Customization

Theming

Import @vojtechportes/react-query-builder/styles.css once, then customize the built-in components with inherited --query-builder-* CSS variables. The stylesheet supplies the default token values; components do not inject runtime styles.

Dark mode

Import the optional @vojtechportes/react-query-builder/dark-mode.variables.css after styles.css, then set the colorScheme prop. Changing the prop updates colors without remounting the Builder.

Reactive dark mode
import '@vojtechportes/react-query-builder/styles.css';
import '@vojtechportes/react-query-builder/dark-mode.variables.css';
const [darkMode, setDarkMode] = useState(false);
<Builder
fields={fields}
data={data}
colorScheme={darkMode ? 'dark' : 'light'}
onChange={setData}
/>;
  • Use colorScheme="light" or colorScheme="dark" to create an explicit palette boundary for one Builder.
  • Leave colorScheme undefined to preserve colors inherited from your application or a surrounding wrapper.
  • Explicit light and dark Builders can be siblings or nested. The nearest Builder scheme applies to its built-in components.
  • Built-in SQL highlighting uses the same info, success, warning, primary, grey, and error variables as the rest of the Builder.
Monaco editor
The packaged Monaco light and dark themes use the same query-builder palette roles as the built-in SQL editor and update without remounting when colorScheme changes. Monaco's standalone theme service is global, so the latest mounted packaged editor, or the editor whose scheme changes most recently, wins across all mounted editors. Synchronizing consumer CSS variable overrides or custom per-editor themes requires application-level configuration.

Global overrides

Set variables on :root when every builder and standalone built-in control should share the same values.

Global tokens
:root {
--query-builder-color-primary-default: #3157c8;
--query-builder-root-padding: 1.25rem;
--query-builder-root-radius: 8px;
}

Wrapper overrides

Set variables on an application-owned wrapper to scope a theme to one subtree. The values are inherited by the builder and its built-in controls.

Wrapper-scoped tokens
.orders-query-builder {
--query-builder-color-primary-default: #3157c8;
--query-builder-group-padding: 1rem;
--query-builder-shadow-group: 0 8px 24px rgb(15 23 42 / 12%);
}

Builder overrides

Use the typed Builder.style prop for values that belong to one builder instance. This is the most specific supported token override boundary.

Per-Builder tokens
import '@vojtechportes/react-query-builder/styles.css';
import {
Builder,
type IBuilderStyle,
} from '@vojtechportes/react-query-builder';
const builderStyle: IBuilderStyle = {
'--query-builder-color-primary-default': '#3157c8',
'--query-builder-root-padding': '1.25rem',
'--query-builder-root-radius': '8px',
};
<Builder
data={data}
fields={fields}
style={builderStyle}
onChange={setData}
/>;

Public token groups

  • Colors --query-builder-color-primary-*, --query-builder-color-secondary-*, grey scale, status colors, and the background surface.
  • Spacing and layout --query-builder-spacing-*, root/group/rule padding, control/group gaps, control dimensions, and drop-zone height.
  • Shape and depth --query-builder-radius-* and --query-builder-shadow-* tokens for roots, groups, popovers, and focus rings.
  • Typography and editors Font, font size, line height, editor typography, editor minimum height, motion, and popover layering tokens.

IBuilderStyle is the typed list of every public token accepted by Builder.style. The same variable names can be declared in global or wrapper CSS. See the complete CSS variables reference for every variable and its default value.

Precedence

Values are resolved in this order, from lowest to highest:

  • Stylesheet defaults Light defaults from styles.css.
  • Inherited CSS Application variables when colorScheme is undefined.
  • Explicit scheme The complete light or dark palette selected through colorScheme.
  • Builder class Consumer CSS targeting the root through className.
  • ThemeProvider Explicit legacy provider colors mapped to root variables.
  • Builder style Variables passed through Builder.style as the final override.

Stable styling hooks

  • Pass an application-owned className to Builder or select its stable [data-query-builder="root"] attribute.
  • The root remains available when useDefaultContainerStyles={false}removes its built-in surface class.
  • Prefer public CSS variables for built-in presentation and the component override API when you need different markup.
  • CSS Module classes shaped like rqb_[local]_[hash] are private build output. Their names can change between releases and must not be used as selectors.

Migrating from ThemeProvider

Legacy theme provider
import '@vojtechportes/react-query-builder/styles.css';
import {
Builder,
ThemeProvider,
} from '@vojtechportes/react-query-builder';
<ThemeProvider colors={{ primary: { default: '#3f51b5' } }}>
<Builder data={data} fields={fields} onChange={setData} />
</ThemeProvider>;

Replace each legacy color leaf with its matching CSS variable. For example, colors.primary.default becomes --query-builder-color-primary-default. Put shared values on a wrapper or pass one-off values through Builder.style, then remove the provider when it no longer serves other builders.

Legacy API
Prefer CSS variables for new code. ThemeProvider, colors, and the public color types remain available for the v2 compatibility cycle. The provider has no DOM wrapper, only handles colors, and nested providers replace rather than merge the outer color value.
Adapters and theming
ThemeProvider and the built-in color tokens do not theme host-library controls supplied by an adapter. Configure the host UI library through its own theme API and use query-builder variables for the remaining structural surfaces. See Adapters.
API reference
© Vojtěch Václav Porteš 2026 - All library contents are available under the MIT license.
Loading privacy preferences...