Get Started

shadcn-rjsf is a set of three copy-paste registry items that bring JSON Schema–driven forms and a visual form builder to any shadcn/ui project.

Prerequisites

  • shadcn/ui initialized in your project (npx shadcn@latest init)
  • Next.js 13+ (App Router) or React 18+ with a compatible bundler
  • Node.js 18+

Installation

ItemWhat it is
form-builder-typesTypes (FormSchema, FormFieldDefinition, …), registerValidator and createCustomValidator.
form-rendererRenders a FormSchema as an accessible form built on your shadcn/ui components.
form-builderDrag-and-drop editor with a field palette, canvas and settings panel. Emits a FormSchema via onChange.

Dependencies install automatically: form-builder pulls in form-renderer and form-builder-types, so one command gets everything:

npx shadcn@latest add "https://shadcn-rjsf-form-builder.noowah.dev/r/form-builder.json"

Only rendering forms? Install just the renderer (it pulls in form-builder-types):

npx shadcn@latest add "https://shadcn-rjsf-form-builder.noowah.dev/r/form-renderer.json"

Quick Start: FormRenderer

Pass a FormSchema to FormRenderer and handle submissions via onSubmit.

import { FormRenderer } from '@/components/ui/rjsf-form-builder/form-renderer/form-renderer';
import type { FormSchema } from '@/lib/form-builder-types/types';

const schema: FormSchema = {
  id: 'contact',
  title: 'Contact Us',
  fields: [
    { id: 'name', type: 'text', label: 'Name', required: true, order: 0 },
    { id: 'email', type: 'email', label: 'Email', required: true, order: 1 },
    { id: 'message', type: 'textarea', label: 'Message', order: 2 },
  ],
};

export default function ContactPage() {
  return (
    <FormRenderer
      schema={schema}
      locale="en-US"
      baseLocale="en-US"
      onSubmit={(data) => console.log(data)}
    />
  );
}

Quick Start: FormBuilder

Wire FormBuilder to a FormRenderer for a live preview. The builder emits a full FormSchema on every change.

'use client';

import { useState } from 'react';
import { FormBuilder } from '@/components/ui/rjsf-form-builder/form-builder/form-builder';
import { FormRenderer } from '@/components/ui/rjsf-form-builder/form-renderer/form-renderer';
import type { FormSchema } from '@/lib/form-builder-types/types';

const INITIAL: FormSchema = { id: 'my-form', title: 'My Form', fields: [] };

export default function BuilderPage() {
  const [schema, setSchema] = useState<FormSchema>(INITIAL);

  return (
    <div className="grid grid-cols-2 gap-6 h-screen">
      <FormBuilder
        initialSchema={schema}
        onChange={setSchema}
        locale="en-US"
        baseLocale="en-US"
        availableLocales={['en-US']}
        className="h-full"
      />
      <div className="p-6 border rounded-lg overflow-auto">
        <FormRenderer schema={schema} locale="en-US" baseLocale="en-US" />
      </div>
    </div>
  );
}

Locale Setup

Both components take a locale — the active locale used to resolve LocalizedString values — and a baseLocale fallback for missing translations. In FormBuilder, new field and option labels are created under baseLocale. A plain-string LocalizedString is always shown as-is. See the API Reference for every prop.

Updating

Registry items are copied into your project, so updates are not automatic. Every installed file starts with a comment naming the version it came from:

// shadcn-rjsf-form-builder v0.3.0 — https://shadcn-rjsf-form-builder.noowah.dev/docs/changelog

Compare it with the latest release (v0.3.0) and read the changelog for what changed. To update, install again with --overwrite:

npx shadcn@latest add "https://shadcn-rjsf-form-builder.noowah.dev/r/form-builder-types.json" --overwrite
npx shadcn@latest add "https://shadcn-rjsf-form-builder.noowah.dev/r/form-renderer.json" --overwrite
npx shadcn@latest add "https://shadcn-rjsf-form-builder.noowah.dev/r/form-builder.json" --overwrite

This replaces the files in place. If you edited them, review the result with git diff and re-apply your changes.