JSONCrack Codebase Analysis — Part 4 — Editor


4 min read

jsoncrack.com is a popular opensource tool used to visualise json into a mindmap. It is built using Next.js.

We, at TThroo, love open source and perform codebase analysis on popular repositories, document, and provide a detailed explanation of the codebase. This enables OSS enthusiasts to learn and contribute to open source projects, and we also apply these learnings in our projects.

In this post, let’s understand the editor functionality used in jsoncrack.com.

jsoncrack editor

Open src/pages/editor.tsx in a new tab and let’s take the top down approach. Let’s first look into the components used.

          <title>Editor | JSON Crack</title>
          {hasQuery && <meta name="robots" content="noindex,nofollow" />}
          <Toolbar />
            <Panes />
        <BottomBar />


This is the first component used in page loaded when you visit https://jsoncrack.com/editor and contains the following

export const EditorWrapper: React.FC<{
  children: React.ReactNode;
}> = ({ children }) => {
  const darkmodeEnabled = useConfig(state => state.darkmodeEnabled);

  return (
    <ThemeProvider theme={darkmodeEnabled ? darkTheme : lightTheme}>
      <MantineProvider forceColorScheme={darkmodeEnabled ? "dark" : "light"}>
        <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>

Providers are imported at the top of the file.

import { MantineProvider } from "@mantine/core";
import { ThemeProvider } from "styled-components";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";


Toolbar is what you see as header/navigation on top of the page


The code is as below:

      {isWidget && <Logo />}
      {!isWidget && (
        <Group gap="xs" justify="left" w="100%" style={{ flexWrap: "nowrap" }}>
          <Styles.StyledToolElement title="JSON Crack">
            <Flex gap="xs" align="center" justify="center">
              <JSONCrackLogo fontSize="1.2em" />

            onChange={e => setFormat(e as FileFormat)}
              { value: FileFormat.JSON, label: "JSON" },
              { value: FileFormat.YAML, label: "YAML" },
              { value: FileFormat.XML, label: "XML" },
              { value: FileFormat.TOML, label: "TOML" },
              { value: FileFormat.CSV, label: "CSV" },

          <ViewModeMenu />
          <Styles.StyledToolElement title="Import File" onClick={() => setVisible("import")(true)}>
          <ViewMenu />
          <ToolsMenu />
          <Styles.StyledToolElement title="Cloud" onClick={() => setVisible("cloud")(true)}>
          <Styles.StyledToolElement title="Download as File" onClick={handleSave}>
      <Group gap="xs" justify="right" w="100%" style={{ flexWrap: "nowrap" }}>
        {!premium && !isWidget && (
          <Styles.StyledToolElement onClick={() => setVisible("premium")(true)}>
            <Text display="flex" c="teal" fz="xs" fw="bold" style={{ textAlign: "center", gap: 4 }}>
              <MdWorkspacePremium size="18" />
              Get Premium

        <SearchInput />
        {!isWidget && (
              title="Save as Image"
              onClick={() => setVisible("download")(true)}
              <FiDownload size="18" />
            <ZoomMenu />
            <AccountMenu />
            <OptionsMenu />
              <AiOutlineFullscreen size="18" />

Code above is self explanatory, the options that you see in the toolbar are listed here.


Panes comprise of two main components, JsonEditor and LiveEditor. I thought why not name this to LivePreview, but then I realised you could edit the mindmap from the livepreview — this is only possible when you are on paid plan, well it isn’t exactly a preview anymore. is it? Yup, naming conventions and their meaning matter. Seasoned devs have constructive discourse about variable or function naming conventions.

“Hang on a minute, what do you mean constructive discourse? appendText() appends a random text and returns the updated string.” Right mate, shouldn’t it be appendAndGetText() or even better, write two functions, one for append and one for get. This is just an example. Anyways, let’s get back to the code now.

<StyledEditor proportionalLayout={false}>
        minSize={fullscreen ? 0 : 300}
        <JsonEditor />
      <Allotment.Pane minSize={0}>
        <LiveEditor />


BottomBar has features like Valid, Save to cloud, Private, Share, Live Transform etc.,

      {data?.name && (
          <title>{data.name} | JSON Crack</title>
        <StyledBottomBarItem onClick={toggleEditor}>
          <BiSolidDockLeft />

        {fileName && (
          <StyledBottomBarItem onClick={() => setVisible("cloud")(true)}>
            <VscSourceControl />
          {error ? (
            <Popover width="auto" shadow="md" position="top" withArrow>
                <Flex align="center" gap={2}>
                  <VscError color="red" size={16} />
                  <Text c="red" fw={500} fz="xs">
                  pointerEvents: "none",
                <Text size="xs">{error}</Text>
          ) : (
            <Flex align="center" gap={2}>
              <MdOutlineCheckCircleOutline />
              <Text size="xs">Valid</Text>
        {(data?.owner_email === user?.email || (!data && user)) && (
          <StyledBottomBarItem onClick={handleSaveJson} disabled={isUpdating || error}>
            {hasChanges || !user ? <AiOutlineCloudUpload /> : <AiOutlineCloudSync />}
            {hasChanges || !user ? (query?.json ? "Unsaved Changes" : "Save to Cloud") : "Saved"}
        {data?.owner_email === user?.email && (
          <StyledBottomBarItem onClick={setPrivate} disabled={isUpdating}>
            {isPrivate ? <AiOutlineLock /> : <AiOutlineUnlock />}
            {isPrivate ? "Private" : "Public"}
          onClick={() => setVisible("share")(true)}
          disabled={isPrivate || !data}
          <AiOutlineLink />
        {liveTransformEnabled ? (
          <StyledBottomBarItem onClick={() => toggleLiveTransform(false)}>
            <VscSync />
            <Text fz="xs">Live Transform</Text>
        ) : (
          <StyledBottomBarItem onClick={() => toggleLiveTransform(true)}>
            <VscSyncIgnored />
            <Text fz="xs">Manual Transform</Text>
        {!liveTransformEnabled && (
          <StyledBottomBarItem onClick={() => setContents({})}>
            <TbTransform />

        <StyledBottomBarItem>Nodes: {nodeCount}</StyledBottomBarItem>
        <StyledBottomBarItem onClick={() => setVisible("review")(true)}>
          <VscFeedback />

There is a lot happening in the above code, but don’t worry. I will explain each of these components in detail in the upcoming tutorials.


We looked at 3 main components in Editor for jsoncrack.com, Toolbar, Panes, BottomBar. In the upcoming tutorials, I will pick each of these components and go into details such as custom hooks used and how this application zustand configured. If you have any questions, feel free to email us at ram@tthroo.com.