json-editor-vue

Vue 2/3 isomorphic JSON editor, viewer, formatter and validator.
2,205,127 695
Install
npm install json-editor-vue
Latest Version:0.19.2
Vue:2 · 3
License:MIT
Last Updated:Aug 24, 2026
Links: GitHub  ·  npm
Maintainer: cloydlau

JSON Editor Vue version

Vue 2/3 isomorphic JSON editor, viewer, formatter and validator.
English | 简体中文

since
npm version JSR Scope
playground Ask DeepWiki Start new PR in StackBlitz Codeflow
build status coverage FOSSA Status minzipped size
code style conventional commits semantic release attw

text mode table mode


Features

  • 🚀 Performant
    • Handle large JSON documents up to 512 MB
    • Deserialize with destr by default, up to 35.96x faster than JSON.parse
  • 💪 Powerful
    • View, edit, format, validate, compact, sort, query, filter, transform, repair, highlight JSON
    • 7 primitive data types including BigInt and Symbol
    • 3 edit modes: text mode & tree mode & table mode
    • 2 themes: light theme & dark theme
    • 2-way binding: parsed or stringified JSON
  • 🤸 Flexible
    • Vue 2.6/2.7/3 isomorphic
    • Support SSR, Nuxt 2/3/4 isomorphic
    • Support Vite, Vue CLI, webpack, CDN...
    • Support microfrontends
    • Support PC & mobile devices
    • Local registration & configuration, or global registration & configuration (Powered by vue-global-config)

Cases

Nuxt Google Mozilla
Tencent BlueKing MRC Epidemiology Unit / University of Cambridge IT Tools
LangBot LangBot Mealie Mealie LangChain4j-AIDeepin LangChain4j-AIDeepin
Open Bank Project OPEA OpenGeoscience
Arkime MISP

[!Important]

json-editor-vue had surpassed 4 million downloads: npm downloads jsDelivr downloads

While having a extremely dismal number of Stars: GitHub Stars

Please consider starring ⭐ to support our ongoing maintenance if it helps: GitHub issues closed


Test Coverage

File % Stmts % Branch % Funcs % Lines
All files 100 100 100 100
constants.ts 100 100 100 100
index.ts 100 100 100 100

Install

Vue 3

npm i json-editor-vue
Local Registration
<script setup>
import JsonEditorVue from 'json-editor-vue'

const value = ref()
</script>

<template>
  <JsonEditorVue
    v-model="value"
    v-bind="{/* local props & attrs */}"
  />
</template>
Global Registration
import JsonEditorVue from 'json-editor-vue'
import { createApp } from 'vue'

createApp()
  .use(JsonEditorVue, {
    // global props & attrs (one-way data flow)
  })
  .mount('#app')
CDN + ESM
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
  </head>

  <body>
    <div id="app">
      <json-editor-vue v-model="value"></json-editor-vue>
    </div>

    <script type="importmap">
      {
        "imports": {
          "vue": "https://cdn.jsdelivr.net/npm/vue/dist/vue.esm-browser.prod.js",
          "vue-demi": "https://cdn.jsdelivr.net/npm/vue-demi/lib/v3/index.mjs",
          "vanilla-jsoneditor": "https://cdn.jsdelivr.net/npm/vanilla-jsoneditor",
          "json-editor-vue": "https://cdn.jsdelivr.net/npm/json-editor-vue@0.19/dist/json-editor-vue.mjs"
        }
      }
    </script>
    <script type="module">
      import { createApp, ref } from 'vue'
      import JsonEditorVue from 'json-editor-vue'

      createApp({
        setup: () => ({
          value: ref(),
        }),
      })
        .use(JsonEditorVue)
        .mount('#app')
    </script>
  </body>
</html>
CDN + IIFE

[!Warning]

Not yet supported because vanilla-jsoneditor does not export IIFE or UMD,

please leave a message here if you need it.

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
  </head>

  <body>
    <div id="app">
      <json-editor-vue v-model="value"></json-editor-vue>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue"></script>
    <script src="https://cdn.jsdelivr.net/npm/vue-demi"></script>
    <!-- TODO -->
    <script src="./vanilla-jsoneditor.umd.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/json-editor-vue@0.19"></script>
    <script>
      const { createApp, ref } = Vue

      createApp({
        setup: () => ({
          value: ref(),
        }),
      })
        .use(JsonEditorVue)
        .mount('#app')
    </script>
  </body>
</html>

Vue 2.7

npm i json-editor-vue
Local Registration
<script setup>
import JsonEditorVue from 'json-editor-vue'

const value = ref()
</script>

<template>
  <JsonEditorVue
    v-model="value"
    v-bind="{/* local props & attrs */}"
  />
</template>
Global Registration
import JsonEditorVue from 'json-editor-vue'
import Vue from 'vue'

Vue.use(JsonEditorVue, {
  // global props & attrs (one-way data flow)
})
CDN + ESM
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
  </head>

  <body>
    <div id="app">
      <json-editor-vue v-model="value"></json-editor-vue>
    </div>

    <script type="importmap">
      {
        "imports": {
          "vue": "https://cdn.jsdelivr.net/npm/vue@2/dist/vue.esm.browser.min.js",
          "vue-demi": "https://cdn.jsdelivr.net/npm/vue-demi/lib/v2.7/index.mjs",
          "vanilla-jsoneditor": "https://cdn.jsdelivr.net/npm/vanilla-jsoneditor",
          "json-editor-vue": "https://cdn.jsdelivr.net/npm/json-editor-vue@0.19/dist/json-editor-vue.mjs"
        }
      }
    </script>
    <script type="module">
      import Vue from 'vue'
      import JsonEditorVue from 'json-editor-vue'

      new Vue({
        components: { JsonEditorVue },
        data() {
          return {
            value: undefined,
          }
        },
      }).$mount('#app')
    </script>
  </body>
</html>
CDN + IIFE

[!Warning]

Not yet supported because vanilla-jsoneditor does not export IIFE or UMD,

please leave a message here if you need it.

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
  </head>

  <body>
    <div id="app">
      <json-editor-vue v-model="value"></json-editor-vue>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
    <script src="https://cdn.jsdelivr.net/npm/vue-demi"></script>
    <!-- TODO -->
    <script src="./vanilla-jsoneditor.umd.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/json-editor-vue@0.19"></script>
    <script>
      new Vue({
        components: { JsonEditorVue },
        data() {
          return {
            value: undefined,
          }
        },
      }).$mount('#app')
    </script>
  </body>
</html>

Vue 2.6 or Earlier

npm i @vue/composition-api json-editor-vue
Local Registration
<script>
import VCA from '@vue/composition-api'
import JsonEditorVue from 'json-editor-vue'
import Vue from 'vue'

Vue.use(VCA)

export default {
  components: { JsonEditorVue },
  data() {
    return {
      value: undefined,
    }
  },
}
</script>

<template>
  <JsonEditorVue
    v-model="value"
    v-bind="{/* local props & attrs */}"
  />
</template>
Global Registration
import VCA from '@vue/composition-api'
import JsonEditorVue from 'json-editor-vue'
import Vue from 'vue'

Vue.use(VCA)
Vue.use(JsonEditorVue, {
  // global props & attrs (one-way data flow)
})
CDN + ESM
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
  </head>

  <body>
    <div id="app">
      <json-editor-vue v-model="value"></json-editor-vue>
    </div>

    <script>
      window.process = { env: { NODE_ENV: 'production' } }
    </script>
    <script type="importmap">
      {
        "imports": {
          "vue": "https://cdn.jsdelivr.net/npm/vue@2.6/dist/vue.esm.browser.min.js",
          "@vue/composition-api": "https://cdn.jsdelivr.net/npm/@vue/composition-api/dist/vue-composition-api.mjs",
          "@vue/composition-api/dist/vue-composition-api.mjs": "https://cdn.jsdelivr.net/npm/@vue/composition-api/dist/vue-composition-api.mjs",
          "vue-demi": "https://cdn.jsdelivr.net/npm/vue-demi/lib/v2/index.mjs",
          "vanilla-jsoneditor": "https://cdn.jsdelivr.net/npm/vanilla-jsoneditor",
          "json-editor-vue": "https://cdn.jsdelivr.net/npm/json-editor-vue@0.19/dist/json-editor-vue.mjs"
        }
      }
    </script>
    <script type="module">
      import { createApp, ref } from '@vue/composition-api'
      import JsonEditorVue from 'json-editor-vue'

      const app = createApp({
        setup: () => ({
          value: ref(),
        }),
      })

      app.use(JsonEditorVue)
      app.mount('#app')
    </script>
  </body>
</html>
CDN + IIFE

[!Warning]

Not yet supported because vanilla-jsoneditor does not export IIFE or UMD,

please leave a message here if you need it.

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
  </head>

  <body>
    <div id="app">
      <json-editor-vue v-model="value"></json-editor-vue>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue@2.6"></script>
    <script src="https://cdn.jsdelivr.net/npm/@vue/composition-api"></script>
    <script src="https://cdn.jsdelivr.net/npm/vue-demi"></script>
    <!-- TODO -->
    <script src="./vanilla-jsoneditor.umd.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/json-editor-vue@0.19"></script>
    <script>
      const { createApp, ref } = VueCompositionAPI

      const app = createApp({
        setup: () => ({
          value: ref(),
        }),
      })

      app.use(VueCompositionAPI)
      app.use(JsonEditorVue)
      app.mount('#app')
    </script>
  </body>
</html>

Nuxt 3

npm i json-editor-vue
Local Registration
<!-- ~/components/JsonEditorVue.client.vue -->

<script setup>
import JsonEditorVue from 'json-editor-vue'

const attrs = useAttrs()
</script>

<template>
  <JsonEditorVue v-bind="attrs" />
</template>
<script setup>
const value = ref()
</script>

<template>
  <JsonEditorVue
    v-model="value"
    v-bind="{/* local props & attrs */}"
  />
</template>
Global Registration as a Module
// nuxt.config.ts

export default defineNuxtConfig({
  modules: ['json-editor-vue/nuxt'],
})
<script setup>
const value = ref()
</script>

<template>
  <JsonEditorVue
    v-model="value"
    v-bind="{/* local props & attrs */}"
  />
</template>
Global Registration as a Plugin
// ~/plugins/JsonEditorVue.client.ts

import JsonEditorVue from 'json-editor-vue'

export default defineNuxtPlugin((nuxtApp) => {
  nuxtApp.vueApp.use(JsonEditorVue, {
    // global props & attrs (one-way data flow)
  })
})
<script setup>
const value = ref()
</script>

<template>
  <JsonEditorVue
    v-model="value"
    v-bind="{/* local props & attrs */}"
  />
</template>

Nuxt 2 + Vue 2.7

npm i json-editor-vue
Local Registration
// nuxt.config.js

export default {
  build: {
    // Vite ≥4 (Rollup ≥3) uses ES2020 as compiler target by default
    // Therefore Vite-≥4-built outputs should be transpiled in webpack 4
    transpile: ['json-editor-vue'],
    extend(config) {
      // Getting webpack to recognize the `.mjs` file
      config.module.rules.push({
        test: /\.mjs$/,
        include: /node_modules/,
        type: 'javascript/auto',
      })
    },
  },
}
<script setup>
import { ref } from 'vue'

function JsonEditorVue() {
  return process.client
    ? import('json-editor-vue')
    : Promise.resolve({ render: h => h('div') })
}

const value = ref()
</script>

<template>
  <JsonEditorVue
    v-model="value"
    v-bind="{/* local props & attrs */}"
  />
</template>
Global Registration
// nuxt.config.js

export default {
  plugins: ['~/plugins/JsonEditorVue.client'],
  build: {
    // Vite ≥4 (Rollup ≥3) uses ES2020 as compiler target by default
    // Therefore Vite-≥4-built outputs should be transpiled in webpack 4
    transpile: ['json-editor-vue'],
    extend(config) {
      // Getting webpack to recognize the `.mjs` file
      config.module.rules.push({
        test: /\.mjs$/,
        include: /node_modules/,
        type: 'javascript/auto',
      })
    },
  },
}
// ~/plugins/JsonEditorVue.client.js

import JsonEditorVue from 'json-editor-vue'
import Vue from 'vue'

Vue.use(JsonEditorVue, {
  // global props & attrs (one-way data flow)
})
<script setup>
import { ref } from 'vue'

const value = ref()
</script>

<template>
  <ClientOnly>
    <JsonEditorVue
      v-model="value"
      v-bind="{/* local props & attrs */}"
    />
  </ClientOnly>
</template>

Nuxt 2 + Vue 2.6 or Earlier

npm i @vue/composition-api json-editor-vue
Local Registration
// nuxt.config.js

export default {
  build: {
    // Vite ≥4 (Rollup ≥3) uses ES2020 as compiler target by default
    // Therefore Vite-≥4-built outputs should be transpiled in webpack 4
    transpile: ['json-editor-vue'],
    extend(config) {
      // Getting webpack to recognize the `.mjs` file
      config.module.rules.push({
        test: /\.mjs$/,
        include: /node_modules/,
        type: 'javascript/auto',
      })
    },
  },
}
<script>
import VCA from '@vue/composition-api'
import Vue from 'vue'

Vue.use(VCA)

export default {
  components: {
    JsonEditorVue: () => process.client
      ? import('json-editor-vue')
      : Promise.resolve({ render: h => h('div') }),
  },
  data() {
    return {
      value: undefined,
    }
  },
}
</script>

<template>
  <JsonEditorVue
    v-model="value"
    v-bind="{/* local props & attrs */}"
  />
</template>
Global Registration
// nuxt.config.js

export default {
  plugins: ['~/plugins/JsonEditorVue.client'],
  build: {
    // Vite ≥4 (Rollup ≥3) uses ES2020 as compiler target by default
    // Therefore Vite-≥4-built outputs should be transpiled in webpack 4
    transpile: ['json-editor-vue'],
    extend(config) {
      // Getting webpack to recognize the `.mjs` file
      config.module.rules.push({
        test: /\.mjs$/,
        include: /node_modules/,
        type: 'javascript/auto',
      })
    },
  },
}
// ~/plugins/JsonEditorVue.client.js

import VCA from '@vue/composition-api'
import JsonEditorVue from 'json-editor-vue'
import Vue from 'vue'

Vue.use(VCA)
Vue.use(JsonEditorVue, {
  // global props & attrs (one-way data flow)
})
<script>
export default {
  data() {
    return {
      value: undefined,
    }
  },
}
</script>

<template>
  <ClientOnly>
    <JsonEditorVue
      v-model="value"
      v-bind="{/* local props & attrs */}"
    />
  </ClientOnly>
</template>

Vite

Ready to use right out of the box.


Vue CLI 5 (webpack 5)

Ready to use right out of the box.


Vue CLI 4 (webpack 4)

≥ v4.5.15

// vue.config.js

module.exports = {
  // Vite ≥4 (Rollup ≥3) uses ES2020 as compiler target by default
  // Therefore Vite-≥4-built outputs should be transpiled in webpack 4
  transpileDependencies: ['json-editor-vue'],
}

< v4.5.15

// vue.config.js

module.exports = {
  // Vite ≥4 (Rollup ≥3) uses ES2020 as compiler target by default
  // Therefore Vite-≥4-built outputs should be transpiled in webpack 4
  transpileDependencies: ['json-editor-vue'],
  configureWebpack: {
    module: {
      rules: [
        // Getting webpack to recognize the `.mjs` file
        {
          test: /\.mjs$/,
          include: /node_modules/,
          type: 'javascript/auto',
        },
      ],
    },
  },
}

Vue CLI 3 (webpack 4)

npm i @babel/plugin-proposal-nullish-coalescing-operator @babel/plugin-proposal-optional-chaining -D
// babel.config.js

module.exports = {
  plugins: [
    '@babel/plugin-proposal-nullish-coalescing-operator',
    '@babel/plugin-proposal-optional-chaining',
  ],
}
// vue.config.js

module.exports = {
  // Vite ≥4 (Rollup ≥3) uses ES2020 as compiler target by default
  // Therefore Vite-≥4-built outputs should be transpiled in webpack 4
  transpileDependencies: ['json-editor-vue'],
  chainWebpack(config) {
    // Getting webpack to recognize the `.mjs` file
    config.module
      .rule('mjs')
      .include
      .add(/node_modules/)
      .type('javascript/auto')
      .end()
  },
}

Vue CLI 2 & 1 (webpack 3)

Vue CLI 2 & 1 pull the template from vuejs-templates/webpack.

npm i @babel/core@latest @babel/preset-env@latest babel-loader@latest -D
// babel.config.js

module.exports = {
  presets: [
    '@babel/preset-env',
  ],
}
// webpack.base.conf.js

module.exports = {
  module: {
    rules: [
      // Getting webpack to recognize the `.mjs` file
      {
        test: /\.mjs$/,
        loader: 'babel-loader',
        include: [resolve('src'), resolve('test'), resolve('node_modules/json-editor-vue')],
      },
    ],
  },
}

Update Dependency Versions

npm rm json-editor-vue && npm i json-editor-vue

[!Warning]

Not working for major version bump, fot that you can specify dependency versions (if necessary)


Specify Dependency Versions

// package.json
{
  // npm/cnpm/bun
  "overrides": {
    "vanilla-jsoneditor": "***",
    "vue-demi": "***"
  },
  // yarn/bun
  "resolutions": {
    "vanilla-jsoneditor": "***",
    "vue-demi": "***"
  },
  // pnpm
  "pnpm": {
    "overrides": {
      "vanilla-jsoneditor": "***",
      "vue-demi": "***"
    }
  }
}

With Scope:

// package.json
{
  // npm/cnpm/bun
  "overrides": {
    "json-editor-vue": {
      "vanilla-jsoneditor": "***",
      "vue-demi": "***"
    }
  },
  // yarn/bun
  "resolutions": {
    "json-editor-vue/vanilla-jsoneditor": "***",
    "json-editor-vue/vue-demi": "***"
  },
  // pnpm
  "pnpm": {
    "overrides": {
      "json-editor-vue>vanilla-jsoneditor": "***",
      "json-editor-vue>vue-demi": "***"
    }
  }
}

Props

Name Description Type Default
v-model /
modelValue (Vue 3) /
value (Vue 2)
binding value any
mode /
v-model:mode (Vue 3) /
:mode.sync (Vue 2)
edit mode Mode /
you can use string in JS
Mode.tree
debounce debounce delay to update the binding value when typing in text mode, in milliseconds number 300
stringified whether to keep the binding value as stringified JSON in text mode boolean true
... properties of svelte-jsoneditor

parsed JSON vs. stringified JSON

  • parsed JSON: what we commonly refer to as JSON, which can be of any data type.
  • stringified JSON: serialized JSON, which is always a string type.

Binding value difference between svelte-jsoneditor and json-editor-vue

  • svelte-jsoneditor: An object contains a parsed JSON or a stringified JSON, will do JSON.parse when passing as a stringified JSON.
  • json-editor-vue: JSON itself. What you see is what you get.

If you prefer the behavior of svelte-jsoneditor:

<JsonEditorVue
  :content="content"
  :onChange="(updatedContent) => {
    content = updatedContent
  }"
/>

The association between binding value and modes

[!Important]

The input value is independent of modes, except:

Input value of string type will be treated as a normal string under tree mode, as a stringified JSON under text mode by default.

The output value of tree mode is a parsed JSON, the output value of text mode is a stringified JSON.

But this correspondence can be disrupted by programmatic changes or mode switching.

See https://github.com/josdejong/svelte-jsoneditor/pull/166 for more details.

FAQ: How to keep the value as parsed JSON in text mode?

[!Caution]

  • Not performant for large JSON documents.
  • Adjust the debounce value based on the size of your JSON.
  • Will output undefined when the input value is invalid.
<script setup>
import { Mode } from 'vanilla-jsoneditor'
</script>

<template>
  <JsonEditorVue :mode="Mode.text" :stringified="false" />
</template>

[!Tip]

You can use mode="text" in JavaScript context without installing vanilla-jsoneditor.

Naming convention

Support camelCase and kebab-case for tag & property name.

[!Tip]

When using json-editor-vue or any Vue component via CDN (HTML), kebab-case must be used exclusively due to HTML's case insensitivity.

Boolean properties

Including the boolean properties of svelte-jsoneditor like readOnly with no value will imply true:

  • ✓ <JsonEditorVue readOnly />

  • ✓ <JsonEditorVue :readOnly="true" />


Exposes

Name Description Type
jsonEditor JSONEditor instance object

Calling the methods of svelte-jsoneditor

<script setup>
import { onMounted, useTemplateRef } from 'vue'

// Vue ≥ v3.5
const jsonEditorVueRef = useTemplateRef('jsonEditorVueRef')
// Vue < v3.5
// const jsonEditorVueRef = ref()

onMounted(() => {
  jsonEditorVueRef.value.jsonEditor.focus()
})
</script>

<template>
  <JsonEditorVue ref="jsonEditorVueRef" />
</template>

BigInt

npm i lossless-json
<script setup>
import JsonEditorVue from 'json-editor-vue'
import { parse, stringify } from 'lossless-json'
</script>

<template>
  <JsonEditorVue :parser="{ parse, stringify }" />
</template>

Dark Theme

<script setup>
import JsonEditorVue from 'json-editor-vue'
import 'vanilla-jsoneditor/themes/jse-theme-dark.css'
</script>

<template>
  <JsonEditorVue class="jse-theme-dark" />
</template>

Changelog

Detailed changes for each release are documented in the release notes


Related Packages

@vee-validate/nuxt

Official vee-validate nuxt module

3,055,027 11,259
@thunderid/nuxt

Nuxt SDK for ThunderID

6,771 7
nuxt-runtime-compiler

A simple module enabling the vue full bundle on Nuxt 2 and 3

3,649 18
nuxt-validate

Simple Nuxt input validation module using vee-validate

50,019 119

Version History

Version Released Vue License
0.19.2 2||3 MIT
0.19.1 2||3 MIT
0.19.0 2||3 MIT
0.18.1 2||3 MIT
0.18.0 2||3 MIT
Pre-releases (4)
Version Released Vue License
0.3.0-beta.0 ^2.0.0 || >=3.0.0 ISC
0.3.0-alpha.2 ^2.0.0 || >=3.0.0 ISC
0.3.0-alpha.1 ^2.0.0 || >=3.0.0 ISC
0.3.0-alpha.0 ^2.0.0 || >=3.0.0 ISC