JSON Form Builder and Form
Library for shadcn/ui

Build and render JSON-based forms in your shadcn application. The SurveyJS shadcn adapters make Form Library and Survey Creator follow your selected visual style, semantic colors, radius, density, and color mode.

  • shadcn/ui
  • React
  • JSON-based forms
  • Backend-agnostic

See the shadcn/ui Adapter in Action

Compare the same form built with SurveyJS and native shadcn components to see how SurveyJS follows the active shadcn theme.

How SurveyJS Themes Work

Components keep the same markup and CSS rules. Themes change the variable values those rules consume.

1

SurveyJS Component CSS

.sd-btn {
  background: var(--sjs2-color-bg-brand-primary);
}
2

Design Tokens (--sjs2-*)

--sjs2-color-bg-brand-primary
3

Theme Values

--sjs2-color-bg-brand-primary: #198394
4

Rendered Components

Button

How the shadcn/ui Adapter Remaps
SurveyJS Tokens

The adapter does not replace SurveyJS components with shadcn components. Instead, it maps SurveyJS design tokens to your application’s shadcn semantic variables and applies the sizing and spacing defined by the selected shadcn visual style.

1

shadcn host application

These variables are generated from the active shadcn theme.

:root {
  --primary: oklch(0.205 0 0);
  --primary-foreground: oklch(0.985 0 0);
  --border: oklch(0.922 0 0);
  --radius: 0.625rem;
}
2

shadcn-base-rhea.min.css

The adapter maps SurveyJS design tokens that have corresponding values in the active shadcn theme.

  • --sjs2-color-project-brand-600: var(--primary);
  • --sjs2-color-fg-brand-on-primary: var(--primary-foreground);
  • --sjs2-color-border-basic-secondary: var(--border);
  • --sjs2-base-unit-radius: var(--radius);
3

SurveyJS Components

Consume the values:

Text input, checkbox, radio group, and dropdown rendered with shadcn token values

When shadcn/ui Variables Change,
SurveyJS Follows

When your application changes its shadcn semantic colors, radius, or color mode, the adapter resolves the SurveyJS mappings using the new values, and SurveyJS components update automatically. If you switch to a different shadcn visual style, you must also load the corresponding adapter file.

Light Mode

1

shadcn Light

:root {
  --primary: oklch(0.205 0 0);
  --primary-foreground: oklch(0.985 0 0);
  --border: oklch(0.922 0 0);
  --radius: 0.625rem;
}
2

shadcn-base-rhea.min.css

Adapter mapping

  • --sjs2-color-project-brand-600: var(--primary);
  • --sjs2-color-fg-brand-on-primary: var(--primary-foreground);
  • --sjs2-color-border-basic-secondary: var(--border);
  • --sjs2-base-unit-radius: var(--radius);
3
SurveyJS form rendered with shadcn light mode variables

Dark Mode

1

shadcn Dark

.dark {
  --primary: oklch(0.922 0 0);
  --primary-foreground: oklch(0.205 0 0);
  --border: oklch(1 0 0 / 10%);
}

2

shadcn-base-rhea.min.css

Adapter mapping.

  • --sjs2-color-project-brand-600: var(--primary);
  • --sjs2-color-fg-brand-on-primary: var(--primary-foreground);
  • --sjs2-color-border-basic-secondary: var(--border);
  • --sjs2-base-unit-radius: var(--radius);
3
SurveyJS form rendered with shadcn dark mode variables

Connect SurveyJS to Your shadcn/ui Theme

Keep shadcn variables available at runtime, load SurveyJS base styles and one matching adapter, then add optional application overrides.

1

Keep semantic tokens available at runtime

Define shadcn semantic variables on :root and override color dependent values in .dark.

:root {
  --primary: oklch(0.205 0 0);
  --border: oklch(0.922 0 0);
  --radius: 0.625rem;
}
.dark {
  --primary: oklch(0.922 0 0);
  --border: oklch(1 0 0 / 10%);
}
2

Load SurveyJS base styles

For Survey Creator, also load its base stylesheet before the adapter.

import "survey-core/survey-core.css";

// Survey Creator:
import "survey-creator-core/survey-creator-core.css";
3

Choose the matching visual-style adapter

Import the adapter that corresponds to your application’s shadcn visual style.

@import "survey-core/themes/adapters/shadcn-base-rhea.min.css";
4

Load shared and style-specific overrides last

Create these files only when you need custom spacing or component styling. Load shared overrides before style-specific ones.

// Optional application overrides:
@import "./survey-overrides/shadcn.css";
@import "./survey-overrides/base-rhea.css";

What the Adapter can Match Automatically

The adapter reads shadcn semantic variables and supplies SurveyJS-compatible styles for the selected visual style.

shadcn/ui styling area What SurveyJS can inherit
Palette Background, foreground, card, primary, secondary, muted, accent, destructive
Borders and focus Border, input, ring, primary focus states
Typography Published font variables and adapter typography defaults
Shape Radius values and component rounding
Color mode :root and .dark values without changing form JSON
Visual style Component measurements from the matching default, new-york, or base-* bundle

What Remains Application-Specific

The adapter can read shadcn semantic variables and reproduce the selected stock visual style. It cannot infer application-specific decisions defined only in your component markup, Tailwind utility classes, modified shadcn component code, or custom widgets.

Application decision Where it lives What to do
Tailwind layout utilities p-6, gap-4, grid, sm:grid-cols-2 Map the resulting spacing to SurveyJS layout tokens
App-owned field wrappers Field, FieldGroup, and Card composition Add shared overrides for wrapper spacing and structure
Visual-style component code Different FieldGroup gaps or control density Add a small <style-id>.css override after the adapter
Custom components A Stepper with no stock shadcn counterpart Use SurveyJS tokens first, then targeted selectors if needed
Project variants CVA variants, local recipes, and custom states Map only the decisions your form actually uses
Responsive behavior Breakpoint-specific grids and stacking Test and match mobile, tablet, and desktop layouts

Build on the Adapter in Layers

Load more specific styles after general styles so that the later rules take precedence.

  1. 1

    SurveyJS base styles

    Provide the core structure and default styling for SurveyJS components.

    survey-core.css
  2. 2

    Matching shadcn adapter

    Map shadcn variables and reproduce the selected stock visual style.

    shadcn-base-rhea.min.css
  3. 3

    Shared application overrides

    Apply application-specific layout decisions shared by every visual style.

    survey-overrides/shadcn.css
  4. 4

    Style-specific application overrides

    Apply application-specific differences for the selected visual style.

    survey-overrides/base-rhea.css
Use targeted selectors only when neededPrefer SurveyJS token overrides. Use targeted selectors within your override files only when the required behavior or structure has no corresponding token.

Match SurveyJS Layout to Your
shadcn/ui Application

The adapter maps shadcn semantic variables, but it cannot read layout decisions defined in JSX or Tailwind utilities. Use SurveyJS layout tokens to reproduce your application’s padding, gaps, and spacing without changing SurveyJS component markup.

Layout in the host application

<div className="native-controls border p-6">
  <FieldGroup>
    <FieldGroup className="grid gap-4 sm:grid-cols-2">
      <Field>
        <FieldLabel htmlFor="first-name">First name</FieldLabel>
        <Input id="first-name" />
      </Field>
      <Field>
        <FieldLabel htmlFor="last-name">Last name</FieldLabel>
        <Input id="last-name" />
      </Field>
    </FieldGroup>
  </FieldGroup>
</div>

SurveyJS overrides

/* survey-overrides/shadcn.css */
.sjs-theme-overrides {
  --sjs2-layout-component-survey-box-padding-top:
    calc(var(--spacing) * 6);
  --sjs2-layout-component-survey-box-padding-bottom:
    calc(var(--spacing) * 6);
  --sjs2-layout-component-page-content-area-padding-horizontal:
    calc(var(--spacing) * 6);
  --sjs2-layout-component-page-content-area-gap-horizontal:
    calc(var(--spacing) * 4);
}

/* survey-overrides/base-rhea.css */
.sjs-theme-overrides {
  --sjs2-layout-component-page-content-area-gap-vertical:
    calc(var(--spacing) * 6);
}
These overrides match spacing. Configure question placement separately and verify the responsive layout.

Use Selectors Only When No Token Is
Available

Prefer SurveyJS token overrides, and use targeted selectors only for application-specific behavior or structure that has no corresponding token.

Use a token first

Use --sjs2-* token overrides for spacing, color, radius, and typography.

Reach for SurveyJS selectors only when the application-specific component behavior has no corresponding token.

/* Match the application's custom Stepper. */
.sd-progress-buttons__page-title {
  font-size: var(--text-sm);
  font-weight: var(--font-weight-medium);
  line-height: 1.25;
  color: var(--muted-foreground);
}
.sd-progress-buttons--numbered .sd-progress-buttons__button {
  width: 2.25rem;
  height: 2.25rem;
  color: var(--muted-foreground);
  font-size: var(--text-xs);
  box-shadow:
    0 1px 3px rgb(0 0 0 / 10%),
    0 1px 2px -1px rgb(0 0 0 / 10%);
}
/* Align connectors with the resized indicators. */
.sd-progress-buttons--numbered .sd-progress-buttons__list {
  --sd-progress-buttons-marker-size: 2.25rem;
  --sd-progress-buttons-gap: 0px;
}

When the shadcn/ui Adapter Is a
Good Fit

Use the matching adapter when your application follows shadcn semantic tokens and a supported visual style. Add focused overrides for layout and custom components that belong to your application.

Your UI setup Expected result What you need to do
Supported visual style and runtime semantic variables Works directly Import the matching adapter
Palette, radius, or dark mode changed through CSS variables Usually automatic Keep semantic variables published at runtime
Tailwind utilities define layout around fields Needs a small override Map spacing and layout to --sjs2-* tokens
Vendored Field wrappers vary by style Needs a style override Load <style-id>.css after the shared overrides
Custom widgets (e.g. the demo Stepper) Needs targeted styling Use tokens first, then narrow selectors
Application has become a separate design system Adapter is a starting point Use the SurveyJS styling skill and MCP server to help your AI coding agent analyze the app's design tokens and generate CSS mappings to SurveyJS design tokens
@theme inline can generate Tailwind utilities, but the adapter can only read values that exist as runtime CSS custom properties. Keep the semantic shadcn variables on :root and .dark. Import one complete adapter for the active visual style rather than combining adapters.

Supported Visual-Style Bundles

Choose the adapter bundle that matches the shadcn/ui visual style used by your application’s components. Each bundle includes the shared token mappings and styling for that visual style, so import only one. Color palettes and light/dark mode use the same bundle.

Patient intake form in the Base Nova visual style Patient intake form in the Base Vega visual style Patient intake form in the Base Maia visual style Patient intake form in the Base Lyra visual style Patient intake form in the Base Mira visual style Patient intake form in the Base Luma visual style Patient intake form in the Base Sera visual style Patient intake form in the Base Rhea visual style Patient intake form in the New York visual style Patient intake form in the Default visual style

Render shadcn-Styled Forms From JSON

shadcn defines the visual language. SurveyJS renders the form and executes its JSON-defined behavior, while the adapter aligns the UI with your application.

import { useMemo } from "react";
import { Model } from "survey-core";
import { Survey } from "survey-react-ui";

/* globals.css
@import "tailwindcss";
*/
import "./globals.css";
import "survey-core/survey-core.css";
import "survey-core/themes/adapters/shadcn-base-rhea.min.css";

const surveyJson = {
  elements: [{
    name: "FirstName",
    title: "Enter your first name:",
    type: "text"
  }, {
    name: "LastName",
    title: "Enter your last name:",
    type: "text"
  }, {
    name: "PreferredContactMethod",
    title: "Preferred contact method",
    type: "radiogroup",
    choices: ["Email", "Phone"]
  }]
};

export function PersonalDetailsForm() {
  const survey = useMemo(() => new Model(surveyJson), []);
  return <Survey model={survey} />;
}

Conditional Logic

Show, hide, enable, or require fields based on answers.

Multi-Page Forms

Break complex forms into steps with progress.

Dynamic Panels

Add, remove, and reorder repeatable groups.

Validation

Built-in validation and custom rules with clear error messages.

Localization

Translate content and validation into any language.

Read-Only Modes

Display submitted data or lock sections when needed.

Add a Drag-and-Drop shadcn/ui Form
Builder to Your Application

Embed Survey Creator so non-developers can build and update JSON form schemas while your application retains control of schemas, responses, authentication, permissions, and storage.

Survey Creator embedded in a shadcn/ui application
  • Embed Survey Creator
  • Save JSON schema to your backend
  • Use Form Library to render the schema
  • Keep authentication and permissions in your app

Fits Your Application and Backend

SurveyJS runs as client-side libraries in the browser. Schemas and responses are plain JSON you send to your own API and store in your own database.

Browser

shadcn/ui

Themes + Components

+
SurveyJS

Survey Creator (builder) + Form Library (renderer)

JSON

Your API

Your Database

  • Client-side libraries

    Run entirely in the browser.

  • Store schemas and responses anywhere

    Use your existing API and database.

  • No required hosted form service

    Keep control, privacy, and compliance.

Frequently Asked Questions

Can I use SurveyJS with shadcn/ui?

Yes. Use SurveyJS Form Library or Survey Creator with the adapter bundle that matches your shadcn visual style.

Does SurveyJS render shadcn components?

No. SurveyJS renders its own accessible components and maps their tokens and measurements to your shadcn theme.

Why is there a separate adapter for each visual style?

shadcn visual styles change component code and measurements, not only colors. Each adapter captures the corresponding stock style.

Which shadcn visual styles are supported?

The adapter supports default, new-york, and eight base styles: luma, lyra, maia, mira, nova, rhea, sera, and vega. Import the one that matches your application.

Can the adapter infer Tailwind utility classes?

No. The adapter does not inspect Tailwind utility classes in your component markup. Map the resulting layout to SurveyJS tokens in an override file.

What if my app uses custom shadcn components or variants?

Start with the matching adapter, then add focused token overrides. Use narrow SurveyJS selectors only for behavior or structure that has no token.

Do I need custom CSS?

Not for a stock supported style. You may need a small override layer for app-owned wrappers, responsive composition, or custom controls.

Does Survey Creator generate shadcn JSX?

No. Survey Creator produces and edits a JSON form schema, not shadcn JSX or HTML markup. SurveyJS Form Library renders that schema at runtime, while the shadcn adapter makes the rendered interface visually align with your shadcn application.

What if my application is a separate design system?

The standard adapter cannot infer styling decisions defined outside shadcn’s semantic CSS variables, such as those in JSX, Tailwind utilities, vendored components, or custom widgets. Install the SurveyJS styling skill and connect the SurveyJS MCP server to give your AI coding agent the required theming context. The agent can then analyze your application’s design tokens and generate a small CSS file that maps them to SurveyJS design tokens. Review and test the generated mappings across all relevant component states before using them in production.

Add Form Building to Your shadcn/ui
Application

Install SurveyJS, import the adapter for your shadcn/ui visual style, and build JSON-based forms that follow your application’s theme.

Your cookie settings

We use cookies to make your browsing experience more convenient and personal. Some cookies are essential, while others help us analyse traffic. Your personal data and cookies may be used for ad personalization. By clicking “Accept All”, you consent to the use of all cookies as described in our Terms of Use and Privacy Statement. You can manage your preferences in “Cookie settings.”

Your renewal subscription expires soon.

Since the license is perpetual, you will still have permanent access to the product versions released within the first 12 month of the original purchase date.

If you wish to continue receiving technical support from our Help Desk specialists and maintain access to the latest product updates, make sure to renew your subscription by clicking the "Renew" button below.

Your renewal subscription has expired.

Since the license is perpetual, you will still have permanent access to the product versions released within the first 12 month of the original purchase date.

If you wish to continue receiving technical support from our Help Desk specialists and maintain access to the latest product updates, make sure to renew your subscription by clicking the "Renew" button below.