Create a Theme
Define the tokens you want to change, generate CSS, and select your theme with VortexProvider. Complete Quick Start first to install the packages and configure PostCSS. To change only part of a page, use Scoped Theming.
Define your theme
Add acme to vortex.config.ts at your project root. This example changes primary text colors and button corners:
import type { VortexThemeConfig } from "@vortexlabs/vortex-themes";
const config: VortexThemeConfig = {
themes: {
acme: {
globalTokens: {
color: {
brandPrimary600: { color: "oklch(52.6% 0.148 259.165)" },
brandPrimary300: { color: "oklch(79.6% 0.11 258.37)" },
},
},
semanticTokens: {
color: {
foregroundPrimaryDefault: {
light: "brandPrimary600",
dark: "brandPrimary300",
},
},
},
componentTokens: {
borderRadius: {
button: { borderRadius: "lg" },
},
},
},
},
};
export default config;Omitted tokens use Vortex's defaults. Each token you define replaces that entire token object, so include all its required fields. For example, a semantic color needs both modes, and a typography token needs all five typography fields.
A theme name identifies your output; naming it sleek does not inherit the bundled Sleek theme.
Generate the CSS
Add a script to your existing package.json:
"scripts": {
"build:theme": "vortex-themes theming --output ./src/themes"
}bun run build:themeThe CLI reads vortex.config.ts and creates src/themes/acme/:
Run it again after changing your config or upgrading Vortex packages. Edit the config, not the generated files.
Apply your theme
Import globals.css once at your app entry. It loads the generated token and typography styles. Use the matching theme name on your provider:
"use client";
import { Button, Text, VortexProvider } from "@vortexlabs/vortex";
import "./themes/acme/globals.css";
export const App = () => (
<VortexProvider defaultTheme="acme">
<Text color="primary">Your theme is ready.</Text>
<Button>Create a project</Button>
</VortexProvider>
);Font files are supplied separately; follow the Fonts guide. For Next.js, import CSS in the root layout and set the initial theme attributes using the Next.js guide.
Change colors
Global colors hold OKLCH values. Semantic colors reference them through light and dark, as in the example above.
When upgrading to Vortex Themes 0.5.0 or later, rename lightMode and darkMode to light and dark in custom semantic colors, then regenerate the CSS.
Changing a global color affects every role that references it. To change a specific component state, edit its semantic role, such as backgroundButtonPrimaryDefault. Check its text, background, border, and hover colors together in both modes.
Use the color reference for token names, and Color Modes to switch between light and dark.
Custom breakpoints
Add breakpoints inside themes.acme.globalTokens:
breakpoints: {
sm: { minPx: 600 },
md: { minPx: 900 },
lg: { minPx: 1200 },
xl: { minPx: 1600 },
},Regenerate the theme, then point PostCSS at its breakpoint file:
import { fileURLToPath } from "node:url";
import { getConfig } from "@vortexlabs/vortex/config/postcss";
export default getConfig({
themeMediaCSSPath: fileURLToPath(
new URL("./src/themes/acme/breakpoints.css", import.meta.url),
),
});Restart your dev server after changing PostCSS.
xs ends just before sm, at 599px here. Themes users switch between should share breakpoints because CSS media queries are compiled at build time.