@kbmjj123/json-editor
v0.1.1
Published
A JSON editor and read-only tree view for the web — CodeMirror 6 editing, live validation with error line locating, and a searchable tree. Vue 3 component, custom element, or plain script tag.
Maintainers
Readme
@kbmjj123/json-editor
A framework-agnostic JSON editor for the web: CodeMirror 6 editing, live
validation with error-line location, format/minify, a searchable and editable
tree view, a table view for arrays, and a value inspector. Use it as a
Vue 3 component, a custom element (<json-editor>), or a plain
script tag from a CDN.
All processing happens in the browser — your JSON never leaves the device.
Features
- CodeMirror 6 editor with JSON syntax highlighting, line numbers and error line highlighting.
- Live validation — reports parse errors with line/column location and a one-click jump to the error line.
- Format / minify toolbar actions.
- Editable tree view — collapse/expand, rename/add/remove nodes, batch edits, undo/redo, and copy a path, JSONPath or value.
- Five search modes — search by key, value, path, all of them combined, or a JSONPath expression (invalid expressions are flagged).
- Value inspector — click a leaf value to recognize colors, timestamps, JWTs, and Base64 (with inline image preview).
- Table view — a top-level array of objects renders as a sortable table with CSV export.
- Four view modes — editor, tree, table, or split side-by-side.
- Light / dark / auto theming via CSS custom properties.
- Zero runtime dependencies for the CDN bundle (Vue + CodeMirror are bundled).
- Small Vue peer-dependency footprint for the npm build.
- Optional attribution badge (
attributionprop) to help visitors find the original project — default is off.
Install
npm / pnpm / yarn
npm install @kbmjj123/json-editor
# or
pnpm add @kbmjj123/json-editorPeer dependencies (Vue 3 + CodeMirror 6 packages) must be installed by the consumer:
npm install vue @codemirror/commands @codemirror/lang-json @codemirror/language @codemirror/state @codemirror/view @lezer/highlightCDN / script tag
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@kbmjj123/json-editor@latest/dist/json-editor.iife.css">
<script src="https://cdn.jsdelivr.net/npm/@kbmjj123/json-editor@latest/dist/json-editor.iife.js"></script>
<json-editor
value='{"hello": "world"}'
view="both"
theme="light"
></json-editor>The CDN build is also available on unpkg and on cdnjs.
Usage
Vue 3
<script setup lang="ts">
import { ref } from 'vue'
import JsonEditor from '@kbmjj123/json-editor'
import '@kbmjj123/json-editor/style.css'
const value = ref('{"name": "JSON Toolbox"}')
</script>
<template>
<JsonEditor
v-model="value"
v-model:view="view"
theme="dark"
locale="en"
height="400px"
/>
</template>Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| modelValue | string | "" | JSON text (the element uses the value attribute). |
| view | 'editor' \| 'tree' \| 'both' \| 'table' | 'both' | Active view. |
| theme | 'light' \| 'dark' \| 'auto' | 'auto' | Theme. |
| locale | 'en' \| 'zh' | 'en' | UI language. |
| messages | Partial<Messages> | — | Override individual UI strings. |
| indent | 2 \| 4 \| 'tab' | 2 | Formatter indentation. |
| readOnly | boolean | false | Disable editing. |
| height | string | '420px' | Editor height. |
| placeholder | string | "" | Placeholder text. |
| maxBytes | number | 0 | Paste size limit (0 = unlimited). |
| bordered | boolean | true | Show outer border. |
| showStatus | boolean | true | Show status bar. |
| attribution | boolean | false | Show "Powered by jsontoolbox.cc" badge. |
| attributionUrl | string | 'https://jsontoolbox.cc' | Attribution link URL. |
Events
| Event | Payload | Description |
|-------|---------|-------------|
| update:modelValue | string | Text changed. |
| update:view | 'editor' \| 'tree' \| 'both' | View changed. |
| error | { message, location } \| null | Validation result (re-emitted on every edit). |
| select | { path, jsonPath, value } | Tree node selected. |
| oversized-paste | { bytes, text } | A paste exceeded maxBytes; the text was not inserted. |
The custom element emits the same information as DOM events — input,
error, select — with the payload on event.detail.
Web Component / custom element
Register manually if you do not use the CDN bundle (which auto-registers):
import { registerJsonEditor } from '@kbmjj123/json-editor/wc'
import '@kbmjj123/json-editor/style.css'
registerJsonEditor()<json-editor
value='{"hello": "world"}'
view="both"
theme="light"
height="320px"
></json-editor>By default the element renders into an open shadow root, so the page CSS
cannot leak in. Set use-shadow="false" to render into the light DOM instead.
Imperative API
Useful when you want full control over the host element:
import { defineJsonEditor } from '@kbmjj123/json-editor/wc'
import '@kbmjj123/json-editor/style.css'
const editor = defineJsonEditor(document.getElementById('host'), {
value: '{"a": 1}',
view: 'editor',
theme: 'dark',
})
editor.format()
editor.on('change', (value) => console.log(value))
editor.destroy()Framework-agnostic core
If you only need JSON utilities, import the core module directly:
import { parseJson, formatJson, buildTree, searchTree } from '@kbmjj123/json-editor/core'Standalone TreeView / TableView (/vue)
If you only need the tree view or the array table — for example to pair
with your own editor — import them from the /vue subpath:
<script setup lang="ts">
import { TreeView, TableView } from '@kbmjj123/json-editor/vue'
import '@kbmjj123/json-editor/style.css'
const text = '{"users":[{"name":"Ada","email":"[email protected]"}]}'
const sensitivePaths = ['users[0].email']
const parsedArray = [{ name: 'Ada', email: '[email protected]' }]
</script>
<template>
<!-- Read-only, with sensitive leaf values redacted as •••• -->
<TreeView
:text="text"
locale="en"
:editable="false"
:masked="true"
:sensitive-paths="sensitivePaths"
/>
<!-- A top-level array of objects renders as a sortable table -->
<TableView :value="parsedArray" locale="en" />
</template>TreeView props:
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| value | unknown | — | Parsed JSON value (alternative to text). |
| text | string | — | Raw JSON text to parse. |
| locale | 'en' \| 'zh' | 'en' | UI language. |
| defaultExpandDepth | number | 2 | Expand container nodes to this depth on first render. |
| editable | boolean | true | Show node-editing controls (rename, add, remove, batch, undo/redo). |
| indent | 2 \| 4 \| 'tab' | 2 | Re-indent used when writing edits back to text. |
| masked | boolean | false | Redact leaf values at sensitive paths as ••••. |
| sensitivePaths | string[] | [] | Dot-paths (e.g. users[0].email) redacted when masked is true. |
TreeView events: select ({ path, jsonPath, value }), copied
({ kind: 'path' | 'jsonPath' | 'value', text }), update:text (edited text).
TableView props: value (parsed array, required), locale, messages.
A top-level array of objects is shown as a sortable table; you can hide/show
columns and export the array as CSV.
Styling
The component ships with its own CSS and uses the --je-* custom property
namespace. Override variables in your own stylesheet:
:root {
--je-bg: #ffffff;
--je-fg: #1f2937;
--je-key: #0451a5;
--je-string: #a31515;
--je-number: #098658;
}Dark mode variables are applied automatically when theme="dark" or when an
ancestor has .je-dark.
Backlinks / attribution
If you embed the editor on a public page, enabling the optional attribution
badge (attribution prop) is the easiest way to give the project a natural
backlink. It is off by default and never added without your consent.
