npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

jsonedit-builder

v1.0.0

Published

Visual JSON Schema editor for creating and manipulating JSON Schema definitions with an intuitive interface.

Downloads

145

Readme

JSONedit Builder

A React component library for building and editing JSON Schema with a visual UI, a JSON source editor, schema inference, and JSON validation.

Install

npm install jsonedit-builder

JSONedit Builder expects React, React DOM, and Monaco Editor to be available in your app:

npm install react react-dom monaco-editor

Import the stylesheet once, usually in your app entry point:

import "jsonedit-builder/styles.css";

Basic Usage

Use SchemaBuilder when you want the full editor: visual editing on one side and editable JSON source on the other.

import "jsonedit-builder/styles.css";
import { SchemaBuilder, type JsonSchema } from "jsonedit-builder";
import { useState } from "react";

export function App() {
  const [schema, setSchema] = useState<JsonSchema>({
    type: "object",
    properties: {},
  });

  return (
    <SchemaBuilder
      value={schema}
      onChange={setSchema}
      readOnly={false}
    />
  );
}

The editor is controlled: pass the current value, then persist updates from onChange.

Choosing a Component

SchemaBuilder is the best default for application screens. It includes the visual editor, JSON source editor, fullscreen mode, and a draggable split view on desktop.

<SchemaBuilder value={schema} onChange={setSchema} readOnly={false} />

SchemaFieldsEditor renders only the visual schema builder. Use it when your app already has its own source preview, tabs, or surrounding layout.

import { SchemaFieldsEditor } from "jsonedit-builder";

<SchemaFieldsEditor
  value={schema}
  onChange={setSchema}
  readOnly={false}
/>

SchemaJsonEditor renders only the Monaco JSON editor. It can be read-only or editable depending on whether you pass readOnly.

import { SchemaJsonEditor } from "jsonedit-builder";

<SchemaJsonEditor value={schema} onChange={setSchema} />

Working With Schema Changes

Most apps only need to handle the whole-schema change callback:

const [schema, setSchema] = useState<JsonSchema>({ type: "object" });

<SchemaBuilder
  value={schema}
  onChange={(nextSchema) => {
    setSchema(nextSchema);
    saveDraft(nextSchema);
  }}
  readOnly={false}
/>

For visual-editor-only usage, the same pattern is named onChange:

<SchemaFieldsEditor
  value={schema}
  onChange={setSchema}
  readOnly={false}
/>

For quick setup, omit value and start with defaultValue:

<SchemaBuilder defaultValue={{ type: "object" }} onChange={setSchema} />

Schema Inference

Use InferSchemaDialog when you want users to paste example JSON and generate a starting schema.

import {
  InferSchemaDialog,
  SchemaBuilder,
  type JsonSchema,
} from "jsonedit-builder";
import { useState } from "react";

export function App() {
  const [schema, setSchema] = useState<JsonSchema>({ type: "object" });
  const [inferOpen, setInferOpen] = useState(false);

  return (
    <>
      <button type="button" onClick={() => setInferOpen(true)}>
        Infer from JSON
      </button>

      <SchemaBuilder
        value={schema}
        onChange={setSchema}
        readOnly={false}
      />

      <InferSchemaDialog
        open={inferOpen}
        onOpenChange={setInferOpen}
        onInfer={setSchema}
      />
    </>
  );
}

Inference detects object properties, arrays, strings, numbers, booleans, required fields, and common string formats such as dates, emails, and URIs.

JSON Validation

Use ValidateJsonDialog when you want users to test JSON data against the current schema.

import { ValidateJsonDialog, type JsonSchema } from "jsonedit-builder";
import { useState } from "react";

export function ValidateButton({ schema }: { schema: JsonSchema }) {
  const [open, setOpen] = useState(false);

  return (
    <>
      <button type="button" onClick={() => setOpen(true)}>
        Validate JSON
      </button>

      <ValidateJsonDialog
        open={open}
        onOpenChange={setOpen}
        schema={schema}
      />
    </>
  );
}

Validation runs as the user types and reports syntax errors, schema validation errors, and line or column locations when available.

Themes and Styling

All styles are scoped under a .jeb class (added automatically by the components) and resolve through --jeb-* CSS custom properties — the full list lives in src/styles/theme.css, which is the single source of truth for the theme.

Import the stylesheet once:

import "jsonedit-builder/styles.css";

Dark mode

Add a .dark class to an ancestor of the component — put it on <html> (or <body>):

document.documentElement.classList.toggle("dark", isDark);

The Monaco JSON editor follows automatically.

Why <html>? Dialogs render through portals into document.body. A .dark class on a wrapper div below <body> won't reach them, so dialogs would stay light while the rest of the editor goes dark.

Customizing

Override any variable on .jeb (or an ancestor). Light and dark values are overridden separately:

.jeb {
  --jeb-primary: oklch(0.55 0.2 260);
  --jeb-radius: 0.5rem;
  --jeb-font-sans: "Inter", sans-serif;
}

.dark .jeb {
  --jeb-background: oklch(0.2 0 0);
}

| Variable | Purpose | | --- | --- | | --jeb-background / --jeb-foreground | Component background and default text | | --jeb-card / --jeb-card-foreground | Panel surfaces | | --jeb-popover / --jeb-popover-foreground | Dropdowns and popovers | | --jeb-overlay | Dialog scrim | | --jeb-primary / --jeb-primary-foreground | Primary actions | | --jeb-secondary / --jeb-secondary-foreground | Secondary actions and chips | | --jeb-muted / --jeb-muted-foreground | Subdued surfaces and text | | --jeb-accent / --jeb-accent-foreground | Hover highlights | | --jeb-destructive / --jeb-destructive-foreground | Errors and removal actions | | --jeb-success | Validation success states | | --jeb-border / --jeb-input / --jeb-ring | Borders, form control borders, focus rings | | --jeb-radius | Base corner radius (all radii derive from it) | | --jeb-font-sans | UI font | | --jeb-font-mono | Monaco/JSON editor font | | --jeb-type-string--jeb-type-all-of | JSON type indicator colors (string, number, boolean, object, array, null, any-of, one-of, all-of) — also drive Monaco syntax highlighting |

Localization

The default language is English. Pass a bundled locale directly to the component for simple localization.

import {
  SchemaBuilder,
  de,
} from "jsonedit-builder";

<SchemaBuilder value={schema} onChange={setSchema} locale={de} />

Bundled locales are exported for English, German, Spanish, French, Polish, Russian, Ukrainian, and Chinese.

For app-wide defaults, wrap a section in SchemaBuilderProvider:

import { SchemaBuilderProvider, fr } from "jsonedit-builder";

<SchemaBuilderProvider locale={fr} messages={{ schemaEditorTitle: "Schema" }}>
  <SchemaBuilder value={schema} onChange={setSchema} />
</SchemaBuilderProvider>

You can also provide your own translation object or override individual messages:

import { type Translation } from "jsonedit-builder";

const customTranslation: Translation = {
  // Add every key from the Translation type.
};

Supported Schema Features

The visual editor covers the common schema authoring flow:

  • Object fields and nested objects
  • Pattern properties for regex-matched property names
  • Required and optional fields
  • Strings, numbers, booleans, arrays, objects, and null values
  • String length, regex pattern, and format constraints
  • Number range, exclusivity, multiple-of, and enum constraints
  • Array item type, length, uniqueness, and contains constraints
  • Boolean allowed-value constraints
  • anyOf, oneOf, and allOf composition
  • additionalProperties controls

You can still edit unsupported JSON Schema keywords directly in the JSON source editor.

Development

npm install
npm run dev

The demo application runs at http://localhost:5173.

Build the library:

npm run build

Common scripts:

| Command | Description | |---------|-------------| | npm run dev | Start the demo development server | | npm run build | Build the library for production | | npm run build:demo | Build the demo app | | npm run preview | Preview the production demo build | | npm run check | Run Biome checks | | npm run fix | Fix Biome issues | | npm run typecheck | Type check with TypeScript | | npm run test | Run tests |

License

MIT

Credit

This project foundation credit goes to: @ophir.dev who started the project and where we decided to fork for our own custom features and control.