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

vue-json-ui-editor

v3.1.0

Published

A Vue 3 JSON Schema based form editor component with TypeScript support

Readme

NPM version npm download npm license

json-editor

A Vue 3 JSON Schema based form editor component. Edit JSON in UI form with JSON Schema and element-plus, with full TypeScript support.

ScreenShot

Versions & Branches

本仓库通过不同分支维护多个 Vue 版本的发布。请根据你的 Vue 版本选择对应分支:

| Branch | Version | Vue | UI Library | Status | |--------|---------|-----|------------|--------| | main | 3.x | Vue 3 (^3.5.0) | element-plus (^2.11.1) | ✅ Active | | master | 2.x | Vue 2 (^2.7.16) | element-ui (^2.15.14) | 🛠️ Maintenance | | v1 | 1.x | Vue 2 (^2.5.17) | element-ui (^2.4.11) | ⚰️ Legacy |

  • main 为当前默认分支,对应 npm 3.x(Vue 3 + element-plus)。
  • 如果你使用 Vue 2,请切换到 master 分支(npm 2.x)。
  • 历史的 Vue 2 早期版本(npm 1.x)请见 v1 分支。

Install

npm install vue-json-ui-editor
# or
pnpm add vue-json-ui-editor

vue-json-ui-editor 3.x targets Vue 3 and is designed to work with element-plus. For Vue 2, see the master (2.x) or v1 (1.x) branch.

Use

<template>
  <json-editor ref="jsonEditorRef" :schema="schema" v-model="model">
    <el-button type="primary" @click="submit">Submit</el-button>
    <el-button @click="reset">Reset</el-button>
  </json-editor>
</template>

<script setup lang="ts">
import { ref } from 'vue';
import JsonEditor from 'vue-json-ui-editor';

const schema = {
  type: 'object',
  title: 'vue-json-editor demo',
  properties: {
    name: { type: 'string' },
    email: { type: 'string' },
  },
};

const model = ref({ name: 'Yourtion' });
const jsonEditorRef = ref<InstanceType<typeof JsonEditor>>();

function submit() {
  // jsonEditorRef.value?.form() returns the underlying element-plus form instance
  jsonEditorRef.value?.form().validate((valid: boolean) => {
    if (!valid) {
      jsonEditorRef.value?.setErrorMessage('Please fill out the required fields');
    }
  });
}

function reset() {
  jsonEditorRef.value?.reset();
}
</script>

json-editor renders with native HTML elements by default. To style it with element-plus, register the components via the static JsonEditor.setComponent(type, component, option?) API — see the example.

Complete working example: example/components/Subscription.vue Schema: example/schema/newsletter.json

props

  • schema Object (required) The JSON Schema object. Use the v-if directive to load asynchronous schema.

  • v-model / modelValue Object (optional) default: {} Two-way binding for the form data. In Vue 3, v-model binds to the modelValue prop.

  • auto-complete String (optional) Whether the value of the control can be automatically completed by the browser. Possible values: off, on.

  • no-validate Boolean (optional) default: false Indicates that the form is not to be validated when submitted.

  • input-wrapping-class String (optional) Wraps each field's controls in a <div class="...">. Leave undefined to disable input wrapping.

  • components Object (optional) default: undefined Per-instance component overrides. When provided, these are merged over the global defaults registered via JsonEditor.setComponent, so multiple <json-editor> instances on the same page can each use a different UI library without polluting each other. Keys are element types (e.g. text, select, form, label); values may be a full { component, option } config or a shorthand component name/object. Leave undefined to fall back to the global registry.

// Two editors on the same page, each with its own text widget:
<json-editor :schema="a" :components="{ text: CompA }" />
<json-editor :schema="b" :components="{ text: CompB }" />

events

  • update:modelValue Emitted (for v-model) whenever a field value changes.

  • change Fired when a change to an element's value is committed by the user.

  • submit Fired when the form is submitted and passes validation.

  • invalid Fired when a submittable element has been checked and doesn't satisfy its constraints.

methods

Exposed via a template ref to the <json-editor> instance (e.g. jsonEditorRef.value):

  • input(name) Get a form input reference.

  • form() Get the rendered form component instance (e.g. the element-plus el-form), so you can call .validate() / .resetFields() on it.

  • checkValidity() Checks whether the form satisfies its constraints. Returns boolean.

  • validate() Async validation shortcut — delegates to the underlying form component's validate() when available.

  • reset() Reset the value of all elements of the form to the initial modelValue.

  • setErrorMessage(message) Set an error message (rendered via the error component type).

  • clearErrorMessage() Clear the error message.

  • getFields() Return the current parsed field tree (including $sub containers for nested objects).

  • vm The reactive view-model ({ model, fields, error }), for advanced consumers and option-callback access.

static API

  • JsonEditor.setComponent(type, component, option?) Register a Vue component (or native tag name) for a given field/element type (e.g. form, label, email, text, select, error, …). option may be a plain object or a factory callback ({ vm, field, item }) => propsObject. This is how you wire the editor to a UI library like element-plus.
JsonEditor.setComponent('text', 'el-input');
JsonEditor.setComponent('form', 'el-form', ({ vm }) => ({ model: vm.model, rules: {} }));
JsonEditor.setComponent('error', 'el-alert', ({ vm }) => ({ type: 'error', title: vm.error }));

Note on label with element-plus: el-form-item reads its label text from the label prop (not the default slot), so the label registration callback must return label: field.label in addition to prop: field.name. See example/components/Subscription.vue.

Wiring specific widgets via schema attrs

The widget for a field is chosen by attrs.type in its schema property (the editor reads schema.attrs as the field descriptor). Register the type once with setComponent, then drive it from the schema:

JsonEditor.setComponent('switch', 'el-switch');
JsonEditor.setComponent('date', 'el-date-picker');
// schema:
{ active: { type: 'boolean', attrs: { type: 'switch' } } }
{ createdAt: { type: 'string', format: 'date-time', attrs: { type: 'date' } } }

Schema features

  • disabled: true and readOnly: true on a property disable/readonly the rendered input (readOnly also implies disabled).
  • Nested objects (type: 'object' with properties) render in a sub-container with the object's title (.sub-title) and description (.sub-description).
  • Object arrays (type: 'array' with items: { type: 'object', properties }) render as an editable list of sub-form rows. Each array renders a header (field label + add button, .json-editor-array-header) and one row per item (.json-editor-array-row with the item's sub-fields + a remove button). The add/remove buttons are registered via the arrayadd / arrayremove component types (default native <button>; register as el-button / icon buttons for UI library styling — see example/components/Subscription.vue). Arrays work at any nesting depth, including inside nested objects.
  • Choice arrays (array + enum/oneOf/anyOf) render as a single select / radio group / checkbox group.

Advanced: reusing the array renderer

The object-array add/remove logic is extracted into a standalone, framework-agnostic module so it can be reused or unit-tested in isolation:

import { createArrayRenderer, type ArrayRendererDeps } from 'vue-json-ui-editor';

const renderer = createArrayRenderer({
  model, onChange, getComp, resolveComp, elementOptions, wrapChild, renderInput,
} satisfies ArrayRendererDeps);
renderer.render(field, fieldName);   // → vnode[] for the whole array (header + rows)
renderer.addRow(fieldName);
renderer.removeRow(fieldName, index);

ArrayRendererDeps declares exactly what the renderer needs (a reactive model, an onChange notifier, and the component-resolution helpers), so it isn't coupled to JsonEditor's setup closure.

TypeScript

This package ships with bundled type declarations. You can import types directly:

import JsonEditor, { type JsonSchema } from 'vue-json-ui-editor';
// newly exported types (v3.1+):
import type {
  JsonEditorStatic,   // the setComponent static method signature
  JsonEditorInstance, // exposed instance methods (form/validate/reset/getFields/vm)
  ComponentConfig, OptionContext, VmContext, ComponentsMap,
  ArrayRendererDeps,  // for createArrayRenderer
} from 'vue-json-ui-editor';

Development

pnpm install      # install dependencies
pnpm dev          # start the example app (Vite)
pnpm build:lib    # build the publishable library bundle
pnpm test         # run unit tests (Vitest)
pnpm check        # type-check + format + test

License

MIT © Yourtion