CoordiationCSS
Menu
Docs/Tooling/Incremental cache

TOOLING · COMPLETE

Incremental build cache

Skip source extraction and CSS compilation that have already produced a valid result, without weakening candidate validation or dependency tracking.

The CLI persists a project-local cache by default. Vite and PostCSS keep a cache for the lifetime of each plugin instance. Every build remains deterministic when the cache is empty or disabled.

TWO LAYERS

Invalidate only the work that changed

Source extraction and stylesheet compilation have separate keys and validation rules.

  1. 01

    Scanner cache: reuses candidates and diagnostics per file when the scanner contract and file metadata match.

  2. 02

    Compiler cache: reuses generated CSS when the input, sorted candidates, options, and imported CSS dependencies still match.

  3. 03

    Scope cleanup: detects added and deleted files and removes stale entries from that source scan.

  4. 04

    Cold equivalence: disabling or deleting the cache changes performance only, never the generated stylesheet contract.

01

Reuse one cache instance

Keep one instance alive for a watch loop, build server, or repeated programmatic compilation. A new in-memory instance starts cold.

build.mjs
import { readFile } from "node:fs/promises";
import { createIncrementalBuildCache } from "@coordiation/css";

const filename = "/project/src/coordiation.css";
const cache = createIncrementalBuildCache();
const scan = await cache.scanSources(["/project/src"]);
const inputCss = await readFile(filename, "utf8");
const result = await cache.compileWithToolchain(inputCss, scan.candidates, {
  filename,
});

console.log(scan.cache);
console.log(result.cache);
02

Use persistent CLI caching

One-shot and watch builds use .coordiation-cache/coordiation-css-v1.json by default. The directory is excluded from source discovery.

Terminal
coordiation-css \
  --input src/coordiation.css \
  --output dist/coordiation.css \
  --content src \
  --cache-dir .coordiation-cache

Use --no-cache for a deliberate cold-build comparison or a read-only environment. Cache writes use a temporary sibling file and atomic rename.

03

Let adapters own their process cache

The official Vite and PostCSS adapters create one in-memory cache per plugin instance. Their existing watcher and dependency messages remain the invalidation boundary.

vite.config.js
coordiation({
  content: ["src"],
  cssFile: "src/coordiation.css",
  cache: true,
})

Set cache: false only when profiling cold behavior or when a host intentionally owns caching.

04

Inspect every cache decision

Scanner and compiler results expose compact JSON-safe manifests for logs, tests, and AI tooling.

Cache manifests
scan.cache = {
  enabled: true,
  persistent: true,
  hits: 14,
  misses: 1,
  removed: 0,
  fingerprint: "…"
}

result.cache = {
  enabled: true,
  persistent: true,
  hit: false,
  key: "…"
}

A scan hit means extraction was reused. A compiler hit means the final compiled result was reused. Neither status changes whether a candidate is supported.

INVALIDATION

Know what makes a cache miss

Keys include the observable build contract; imported files are validated separately.

  • Changing prefix, extensions, include/exclude filters, safelist, diagnostics, extractors, or plugins invalidates source entries.
  • Editing, adding, or deleting a source file updates the scan result and fingerprint.
  • Changing CSS input, candidates, compiler options, or a local CSS import invalidates compilation.
  • Runtime extractor and plugin functions are cacheable in the current process, but never trusted across processes.
  • A malformed or schema-incompatible persistent cache is ignored; it cannot become generated CSS input.

AI GENERATION CONTRACT

Use cache data as observability

Agents may explain why a rebuild ran, but support discovery remains separate.

  • Read scan.cache and result.cache before claiming a cache hit or miss.
  • Use rejected, /api/utilities, and /api/capabilities to determine class support.
  • Keep cache directories project-local and literal in generated commands.
  • Prefer one cache instance per build context; do not share one mutable instance across unrelated projects.
  • Include sourceMap in the build contract when cached results must retain mappings.