Theme package
Most teams use this package for one job: get live brand colours into Figma.
CSS in the project is the source of truth. Brand with --af-* overrides (Theming), then export. Plugin how-to: Figma plugin. Product overview: Airframe → Figma.
- Preferred —
npx af theme export→ Airframe plugin → Update Figma (figma.variables.json) - Alternate — same export’s DTCG pack or Theme Studio → drop four files by hand
Optional tools also map foreign files, lint CSS, and generate theme stylesheets. Most apps never import the library — they use the CLI from @airframeui/build.
npx af theme exportWorking example: examples/theme in the Airframe workspace. BYO Tokens: examples/byotokens.
How it works
Section titled “How it works”- Brand the product in CSS (
:rootand[data-brand]). - Point
theme.filesat those stylesheets inairframe.config.js. - Run
npx af theme export— writes DTCG undertokens/(andbyo/when BYO Tokens is set) plusfigma.variables.jsonfor the plugin. Use--no-figmafor DTCG only.
Both layers of the export use the same inputs:
- Catalog defaults from
@airframeui/tokens - Breakpoints from
airframe.config.js(if you set them) - Each path in
theme.files, in array order
Later files win when the same token is set twice. Earlier values stay if a later file does not repeat them. Brands are discovered from [data-brand]. Do not list brand ids in config. Colours and fonts stay in CSS.
Extra --af-* names still export. Theming.
BYO Tokens: product-owned variables (theme.byoTokens.prefix) export in parallel under .airframeui/byo/<slug>/ and as separate Figma collections (Demo / default). Full guide: BYO Tokens.
Config
Section titled “Config”Create airframe.config.js in the project root. npx af init writes a starter. af theme loads this file from cwd. --config picks another path.
/** @type {import('@airframeui/build').AirframeBuildOptions} */
export default {
theme: {
files: ['./src/tokens.css', './src/brands/*.css'],
outputDir: '.airframeui',
byoTokens: { prefix: '--demo-' },
existingUi: { excludePrefixes: ['--ion-'] },
},
};| Key | What it does |
|---|---|
theme.files | CSS/SCSS with --af-* overrides and BYO tokens. Globs are allowed. Split colour across files is expected. A comma-separated [data-brand] list applies to every brand in the list. |
theme.byoTokens.prefix | Product namespace for BYO Tokens. Exports to byo/<slug>/ and a separate Figma collection. See BYO Tokens. |
theme.existingUi | Airframe → existing UI mapping (runtime only). excludePrefixes skips host vars from export. |
theme.outputDir | Folder tokens/ is written into. Default .airframeui if you omit it. CLI -o / --out overrides. |
That is not top-level outputDir in the same file. That key is optional generated CSS for PostCSS / af build. See Build Tool.
Add .airframeui/ to .gitignore. Do not commit the export.
--css src/extra.css adds stylesheets for one export without editing config.
Commands
Section titled “Commands”| Command | Direction | Writes |
|---|---|---|
af theme export | CSS → JSON | tokens/… + byo/… (BYO Tokens) + figma.variables.json (omit Figma with --no-figma) |
af figma export | CSS → JSON | figma.variables.json only (alias; prefer af theme export) |
af figma sync | refresh + push | same file; Enterprise REST when configured |
af figma check | check Figma | Enterprise REST drift report |
af theme generate --from … | JSON/CSS → CSS | --af-* stylesheet (best-effort inbound) |
af theme lint | check CSS | diagnostics only |
af theme validate | check a file | the same report, no CSS written |
npx af theme export
npx af theme export -o ./figma-tokens
npx af theme export --no-figma
npx af theme export --css src/extra.css
npx af figma sync
npx af figma check
npx af theme generate --from ./tokens.json -o theme.css
npx af theme lint theme.css
npx af theme validate ./tokens.json --format autoFormats for generate / validate: auto, dtcg, tokens-studio, css, figma-variables, style-dictionary, airframe-spec.
--from accepts a local file or an HTTPS URL to JSON/CSS (not an HTML page). --strict fails on warnings.
What export writes
Section titled “What export writes”Each af theme export replaces tokens/ (and byo/ when present) so a brand you deleted in CSS does not linger. It also rewrites figma.variables.json unless you pass --no-figma.
.airframeui/
tokens/
default/ ← :root palette
light.tokens.json
dark.tokens.json
hc-light.tokens.json
hc-dark.tokens.json
delta/ ← [data-brand='delta']
light.tokens.json
dark.tokens.json
hc-light.tokens.json
hc-dark.tokens.json
airframe.resolver.json
byo/demo/default/light.tokens.json ← when theme.byoTokens.prefix is set
figma.variables.json ← plugin payload (skip with --no-figma)Same four filenames in every folder so modes line up. default is :root. Every other folder is a [data-brand] id. Do not name a brand base. That collides with --af-base-*.
After branding in CSS, sync the same colours into Figma Variables. CSS in the project is the source of truth — not Figma.
| Path | Export | In Figma |
|---|---|---|
| Preferred — plugin | npx af theme export → figma.variables.json | Open Airframe → drop file → Update Figma |
| Alternate — token pack | same export’s tokens/ or Theme Studio | Drop four DTCG files from tokens/default onto one collection |
Step-by-step (plugin, drift, token pack, Enterprise): Figma plugin. Product overview: Airframe → Figma.
Export preserves aliases in the pack (for example button background → primary colour → brand base). Mode-specific and derived colour-mix values stay as resolved colours. Figma does not read airframe.resolver.json. How CSS becomes JSON: Tokens — source of truth.
Do not import a Figma or Tokens Studio dump back into Airframe and expect a complete theme. Names rarely match. Set colours in CSS (or Theme Studio), then export.
Generate and lint
Section titled “Generate and lint”Inbound is best-effort. The mapper is a small alias table (primary → --af-base-primary, plus --af-* names). Proprietary paths (color.blue.500, brand/500) land in the unmapped report, not in CSS. Dark and high-contrast companions are often missing.
Keep generate for CSS that already uses --af-*, for a round-trip of our own DTCG, or when you have renamed tokens to match the catalog. Then lint.
Import the generated theme.css after @airframeui/core.
This package
Section titled “This package”@airframeui/theme is the library behind the CLI. Dev dependency. Same version as core. It does not run in the browser. The app still needs @airframeui/core for runtime CSS.
npm install -D @airframeui/themeUse the library when you are writing your own script. Most apps stop at af theme export.
import { emitDtcgExport, emitFigmaVariablesModel, resolveTheme } from '@airframeui/theme';
const spec = resolveTheme({ config, css });
const { palettes } = emitDtcgExport({ spec });
// palettes.default.light … palettes.delta.dark
const figma = emitFigmaVariablesModel({ spec });
// figma.collections[0].variables — native Variables payload (plugin / REST)Related
Section titled “Related”- Figma plugin — plugin how-to and drift check
- BYO Tokens — product-owned tokens alongside Airframe
- Airframe → Figma — product overview
- Theming — brand the app with CSS
- Tokens — CSS is the spec
- Build Tool —
afCLI (theme+figma)