SurveyJS v3.0 Design Tokens and Themes (Part 1)

TL;DR: SurveyJS v3.0 introduces a shared CSS-based design system across Form Library, Survey Creator, Dashboard, and PDF Generator. A shared set of design tokens now controls colors, typography, spacing, sizing, borders, shadows, and individual components. You can start with one of 32 predefined theme variations, create a theme visually in Theme Editor, or override CSS variables directly in a reusable JSON theme object.

When several UI libraries appear in the same application, styling them separately becomes a maintenance problem.

A form may use one set of colors and spacing rules. The form builder around it may use another. The dashboard may come with its own typography and component styles. PDF exports may look like they belong to a completely different product.

Even if each component can be customized, separate styling systems create duplicated work. A brand-color change has to be implemented several times. Light and dark modes have to be coordinated across products. Small differences in borders, spacing, or typography accumulate until the UI no longer feels consistent.

SurveyJS v3 addresses this problem with a shared design token and theming system.

Form Library, Survey Creator, Dashboard, and PDF Generator now use the same CSS-variable foundation. You can define your visual language once, store it as a JSON theme object, and apply it across the entire SurveyJS product family.

SurveyJS products with a shared design token system

One Theming System Across All SurveyJS Products

A SurveyJS theme is a JSON object that contains CSS variables and other appearance settings.

The same theme format can be used with:

  • Form Library to style forms and surveys rendered for respondents
  • Survey Creator to style both the form builder UI and the form under configuration
  • Dashboard to style charts, filters, controls, and result views
  • PDF Generator to carry the same colors and visual identity into generated documents

Each product exposes a method for applying a theme:

import { Model } from "survey-core";
import { SurveyCreatorModel } from "survey-creator-core";
import { Dashboard } from "survey-analytics";
import { SurveyPDF } from "survey-pdf";
import { FlatDarkPanelless } from "survey-core/themes";

const survey = new Model(surveyJson);
survey.applyTheme(FlatDarkPanelless);

const creator = new SurveyCreatorModel({ /* options */ });
creator.applyCreatorTheme(FlatDarkPanelless); // Survey Creator UI
creator.applyTheme(FlatDarkPanelless);        // form being configured

const dashboard = new Dashboard(questions, data, { /* options */ });
dashboard.applyTheme(FlatDarkPanelless);

const surveyPdf = new SurveyPDF(surveyJson);
surveyPdf.applyTheme(FlatDarkPanelless);

Survey Creator has two separate calls for a reason. applyCreatorTheme() styles the form builder UI, including its Toolbox, Property Grid, tabs, dialogs, and other designer controls. applyTheme() styles the form displayed on the design surface and in preview mode.

This separation allows you to use the same theme for both surfaces or give the form builder and the respondent-facing form different appearances.

What Are Design Tokens?

A design token is a named variable that represents a visual decision.

Instead of assigning #085DE5 directly to every primary button, focus state, selected item, and active control, you define the color once as a brand token:

--sjs2-color-project-brand-600: #085DE5;

Components reference that token or another token derived from it. When the value changes, every component connected to it updates automatically.

SurveyJS v3 uses design tokens for colors, typography, spacing, component sizing, border widths, corner radii, opacity, shadows, interaction states, and individual component styles.

This means UI customization no longer depends on scattered CSS selectors that target the current HTML structure of each component. You work with named variables that describe either a design role or a specific component.

How the New Design Token System Is Organized

The SurveyJS design token system contains five layers:

  1. Palette
  2. Base tokens
  3. System primitives
  4. Semantic tokens
  5. Component tokens

You do not normally edit every layer. Each one has a specific purpose.

Layer 0: Palette

Palette tokens contain raw color values:

--sjs2-palette-green-400: #15CDAB;
--sjs2-palette-green-600: #19B394;
--sjs2-palette-green-700: #15947A;

A palette provides the available color material, but it does not describe how those colors should be used. A green value may become a brand color, a success-state color, or a selected-control background at a higher layer.

Most custom themes do not need to replace the entire palette.

Layer 1: Base Tokens

Base tokens define the global scale of the UI:

--sjs2-base-unit-size: 8px;
--sjs2-base-unit-spacing: 8px;
--sjs2-base-unit-radius: 8px;
--sjs2-base-unit-border-width: 1px;
--sjs2-base-unit-font-size: 8px;
--sjs2-base-unit-line-height: 8px;

Changing a base token has a broad effect. For example, increasing --sjs2-base-unit-spacing increases derived gaps, margins, and paddings throughout the UI. Changing --sjs2-base-unit-radius makes many controls more or less rounded.

Use base tokens when you deliberately want to change the scale of the entire interface. Do not use them for isolated adjustments.

Layer 2: System Primitives

System primitives are calculated scales derived from the base tokens. For example, the spacing scale includes variables such as:

--sjs2-spacing-x050;
--sjs2-spacing-x100;
--sjs2-spacing-x200;
--sjs2-spacing-x400;

The same pattern applies to font sizes, line heights, component sizes, radii, opacity, and other measurements.

These variables give the rest of the system a consistent rhythm. They should not be overridden directly. If you want to change the global scale, change the corresponding base token. If you want to restyle a particular surface or component, use a semantic or component token.

Layer 3: Semantic Tokens

Semantic tokens describe how a value is used rather than what the raw value is. Examples include tokens for brand actions, backgrounds, text, borders, informational messages, positive states, warnings, errors, and floating surfaces.

This is the layer where most global theme customization should happen:

const customTheme = {
  cssVariables: {
    "--sjs2-color-project-brand-600": "#085DE5",
    "--sjs2-color-bg-basic-primary": "#F2F2F2",
    "--sjs2-color-bg-basic-secondary": "#E8EAEB",
    "--sjs2-typography-font-family-text": "Inter, sans-serif",
    "--sjs2-typography-font-size-default":
      "var(--sjs2-font-size-x250)"
  }
};

survey.applyTheme(customTheme);

This example changes the primary brand color, two application surfaces, the font family, and the default text size. Components that consume these semantic tokens update together.

Layer 4: Component Tokens

Component tokens provide targeted control over individual UI elements, including buttons, panels, questions, input fields, checkboxes, radio buttons, toggles, sliders, validation messages, pages, and survey containers.

Use these tokens when one component should differ from the shared theme. This creates a clear customization path:

  • Change a semantic token to update a design rule throughout the UI.
  • Change a component token to restyle one type of component.
  • Change a base token only when you want to rescale the interface globally.

Start with 32 Predefined Theme Variations

SurveyJS v3 includes predefined themes with light and dark color palettes and container-based or panelless layouts. Together, these options provide 32 ready-to-use theme variations.

The Default Light theme is applied when you import the standard SurveyJS stylesheet. To use another theme, import its theme object and pass it to applyTheme():

import { FlatDarkPanelless } from "survey-core/themes";

const survey = new Model(surveyJson);
survey.applyTheme(FlatDarkPanelless);

The same theme can be applied across the product family:

import { Model } from "survey-core";
import { SurveyCreatorModel } from "survey-creator-core";
import { Dashboard } from "survey-analytics";
import { SurveyPDF } from "survey-pdf";
import { FlatDarkPanelless } from "survey-core/themes";

const survey = new Model(surveyJson);
survey.applyTheme(FlatDarkPanelless);

const creator = new SurveyCreatorModel({ /* options */ });
creator.applyCreatorTheme(FlatDarkPanelless); // Survey Creator UI
creator.applyTheme(FlatDarkPanelless);        // form being configured

const dashboard = new Dashboard(questions, data, { /* options */ });
dashboard.applyTheme(FlatDarkPanelless);

const surveyPdf = new SurveyPDF(surveyJson);
surveyPdf.applyTheme(FlatDarkPanelless);

A panelless theme removes question containers and produces a more compact layout. Dark variations replace the light palette while keeping the theme's underlying component rules.

You can also apply custom overrides on top of a predefined theme:

import { LayeredDarkPanelless } from "survey-core/themes";

const customTheme = {
  cssVariables: {
    "--sjs2-color-project-brand-600": "#19B394"
  }
};

survey.applyTheme(customTheme, LayeredDarkPanelless);

Only the specified variables are replaced. All other values continue to come from the selected predefined theme.

Create Custom Themes Visually with Theme Editor

You do not need to work with CSS variables directly to create a SurveyJS theme.

Theme Editor, included with Survey Creator, provides a visual interface for configuring form appearance. You can adjust colors, typography, spacing, backgrounds, corner radii, and other settings while previewing the result on an actual form.

When the theme is complete, export it as a JSON object. That object can be stored in your database, versioned with application code, assigned to an individual form, shared by multiple forms, selected for a tenant, switched at runtime, or applied in another SurveyJS product.

// In production, handle fetch failures and validate the response shape
const response = await fetch(`/api/tenants/${tenantId}/theme`);
const tenantTheme = await response.json();
survey.applyTheme(tenantTheme);

If users need to create and maintain themes themselves, enable the Theme Editor tab in your embedded Survey Creator. They can configure the appearance visually, while your application decides where the exported theme JSON is stored and where it may be used.

Switch Themes at Runtime

Themes are not build-time stylesheet choices. You can switch themes while the application is running:

import { ContrastDark, ContrastLight } from "survey-core/themes";

function setColorMode(mode) {
  survey.applyTheme(
    mode === "dark" ? ContrastDark : ContrastLight
  );
}

This supports light and dark modes, user-selected themes, per-tenant branding, role-specific interfaces, accessibility modes, and theme previews before publishing.

Because the theme is an object applied through the component API, switching themes does not require recreating the form schema or changing response data.

Reuse Themes Without Coupling Them to Form Definitions

A theme and a form schema solve different problems. The schema defines questions, pages, validation, conditional logic, navigation, and calculated values. The theme defines how the form looks.

Keeping them separate means one form can use several themes, and one theme can be shared by many forms:

const survey = new Model(formSchema);

survey.applyTheme(
  customer.prefersDarkMode
    ? customer.darkTheme
    : customer.lightTheme
);

You do not need to duplicate the schema to produce branded, dark, high-contrast, or compact versions of the same form.

What Changes for Existing SurveyJS Applications?

You can continue using predefined SurveyJS themes, but v3 gives you a more systematic customization model.

For broad changes, override semantic tokens instead of writing CSS rules for multiple components. For isolated changes, use component tokens. Use base tokens only when you want to alter the scale of the whole UI.

A practical customization sequence looks like this:

  1. Select the predefined theme closest to the required design.
  2. Set brand colors and main surfaces through semantic tokens.
  3. Configure typography, spacing, and corner radii.
  4. Add component-token overrides only where a specific control should differ.
  5. Store the result as a reusable theme object.
  6. Apply the theme to each SurveyJS product used in the application.

This approach reduces the amount of custom CSS you need to maintain and makes the intent of each override explicit.

One Visual System

The important change in SurveyJS v3 is not simply that more CSS variables are available.

The change is that Form Library, Survey Creator, Dashboard, and PDF Generator now participate in the same appearance system.

You can choose a predefined theme, customize it visually, or work directly with the token architecture. You can make global changes through semantic tokens and handle exceptions through component tokens. The resulting theme stays portable because it is stored as JSON and applied through a public API.

That gives teams one place to define how SurveyJS should look—across form creation, form filling, response analysis, and PDF output.

To explore the complete variable hierarchy, see the SurveyJS Design Tokens guide. For theme setup, predefined themes, Theme Editor, and runtime switching, see the SurveyJS theming documentation.

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.