API

Configuration: traceless-style.config.js

Optional file at the project root. CommonJS only — traceless-style.config.js, not .mjs or .ts.

Full shape

// traceless-style.config.js
module.exports = {
  /* Source roots to scan. Default: union of `src/` and `app/` if either exists. */
  srcDir: "src",                            // string or string[]

  /* Lint configuration. Default: all rules ON (strict). */
  lint: {
    noInlineStyles: true,                   // cannot be disabled fully
    noClassString:  true,
    noCSSModules:   true,
    noTailwind:     true,
    ignore:         ["**/__tests__/**"],
  },
  // …or `lint: false` to disable noClassString/noCSSModules/noTailwind
  //   (noInlineStyles stays on).

  /* Auto dark-mode derivation. Default: true. */
  autoDarkMode: true,

  /* Auto RTL physical → logical rewriting. Default: true. */
  autoRtl: true,

  /* WCAG contrast validation. Default: AA enforced, strict by default
     (build fails on errors). Set strict: false to demote to warnings. */
  contrast: {
    level:               "AA",          // "AA" | "AAA" | "off"
    strict:              true,          // AA failures → build errors (default true)
    strictAAA:           false,         // AAA failures → build errors
    surfaceLight:        "#fafafa",
    surfaceDark:         "#0a0a0f",
    largeTextSize:       18,            // px threshold for "large text"
    auditUiComponents:   true,          // §1.4.11 — borders, caret, accent, etc.
    auditPlaceholder:    true,          // §1.4.3 for &::placeholder selectors
    gradientSampleCount: 5,             // midpoints between adjacent gradient stops
    suggestionSpace:     "oklch",       // "oklch" | "hsl" — fix-color search space
    auditPeerSurfaces:   false,         // opt-in: cross-validate against sibling bgs
  },

  /* Custom variants — also detected from `tl.extend({ variants })` calls.
     Putting them here is optional; useful when you want them centralized. */
  variants: {
    _tablet: "@media (min-width: 900px)",
  },
};

Key reference

srcDir: string | string[]

Source root(s) to scan. If unset, the CLI scans both src/ and app/ (whichever exist) plus the project root as a final fallback.

lint

See Linting for the full rule list.

KeyTypeDefaultNotes
noInlineStylesbooleantrueCannot be fully disabled — even lint: false keeps this on
noClassStringbooleantrueReject bare className="..." strings
noCSSModulesbooleantrueReject .module.css imports
noTailwindbooleantrueReject Tailwind utility class names
ignorestring[][]Glob patterns to skip

autoDarkMode: boolean

When true (default), the compiler derives a dark-mode variant of every color value in your styles. See Dark mode. Disable via _autoDark: false per group, or globally with autoDarkMode: false.

autoRtl: boolean

When true (default), the compiler rewrites physical CSS properties (marginLeft, paddingRight, etc.) to their logical equivalents. See RTL. Disable per group with _autoRtl: false.

contrast

WCAG 2.1 + 2.2 audit settings. The full feature set is documented in WCAG contrast validation.

KeyTypeDefaultNotes
level"AA" | "AAA" | "off""AA"Highest standard the validator aims for. AA is the legal floor for Section 508 (US) and EN 301 549 (EU).
strictbooleantrueAA failures → build errors. Set false to demote to warnings while migrating an older codebase.
strictAAAbooleanfalseAAA failures → build errors. AAA is best-effort enhancement; many legitimate designs (large hero gradients, decorative chips) fail it.
surfaceLightstring"#fafafa"Assumed light-mode page surface. Used to composite translucent backgrounds before measurement (CSS Color 4 §10).
surfaceDarkstring"#0a0a0f"Assumed dark-mode page surface.
largeTextSizenumber18Pixel threshold above which text qualifies as "large" (3:1 / 4.5:1 instead of 4.5:1 / 7:1). WCAG defines large as ≥18pt regular OR ≥14pt bold.
auditUiComponentsbooleantrueAudit border / outline / caret / accent / text-decoration / box-shadow colors per §1.4.11 (≥3:1).
auditPlaceholderbooleantrueAudit &::placeholder selectors. Placeholder text counts as text under §1.4.3.
gradientSampleCountnumber5When auditing color: transparent + background-clip: text, sample N midpoints between each pair of adjacent gradient stops. Catches low-contrast troughs that lie between two acceptable declared stops. Set to 0 to only check declared stops.
suggestionSpace"hsl" | "oklch""oklch"Color space for the fix-suggestion binary search. OKLCH preserves hue and chroma intent better than HSL — a brand blue stays blue.
auditPeerSurfacesbooleanfalseWhen true, audit a group's color against the backgrounds declared on sibling groups in the same tl.create({...}) call. Catches cross-component contrast bugs but produces false positives on unrelated siblings. Off by default; enable for design-system rigor.

variants

Optional pre-registered custom variants. Same format as tl.extend({ variants: ... }). Most projects prefer the tl.extend form (variant definitions colocated with code).

Environment variables

VariableEffect
TRACELESS_STYLE_PARSERForce parser: "swc" or "legacy". Overrides config.
TRACELESS_STYLE_DEBUG_RESOLVEWhen set to 1, prints the cross-file token export registry after Pass 0. Useful for debugging "my import isn't expanding."

Loading order

The CLI (src/cli/extract.ts) loads config in this order:

  1. Resolve traceless-style.config.js from process.cwd().
  2. If it exists, require() it (with cache-busted re-read for watch mode).
  3. Apply srcDir → CLI SRC_DIRS.
  4. Apply lint → CLI lint runner.
  5. Apply autoDarkModesetAutoDarkMode(false) if false.
  6. Apply contrastsetContrastOptions(cfg.contrast).

If the config file is missing or malformed, defaults are used silently.

ESM project notes

If your project uses "type": "module" in package.json, name the config explicitly:

  • traceless-style.config.cjs (CommonJS)
  • traceless-style.config.mjs (not currently supported — require() cannot load ESM)
  • traceless-style.config.ts (not currently supported)

The CLI uses Node's require() to load the config — see createRequire(import.meta.url) in src/cli/extract.ts.

See also

See also