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.
- 01
Scanner cache: reuses candidates and diagnostics per file when the scanner contract and file metadata match.
- 02
Compiler cache: reuses generated CSS when the input, sorted candidates, options, and imported CSS dependencies still match.
- 03
Scope cleanup: detects added and deleted files and removes stale entries from that source scan.
- 04
Cold equivalence: disabling or deleting the cache changes performance only, never the generated stylesheet contract.
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.
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);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.
coordiation-css \
--input src/coordiation.css \
--output dist/coordiation.css \
--content src \
--cache-dir .coordiation-cacheUse --no-cache for a deliberate cold-build comparison or a read-only environment. Cache writes use a temporary sibling file and atomic rename.
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.
coordiation({
content: ["src"],
cssFile: "src/coordiation.css",
cache: true,
})Set cache: false only when profiling cold behavior or when a host intentionally owns caching.
Inspect every cache decision
Scanner and compiler results expose compact JSON-safe manifests for logs, tests, and AI tooling.
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.cacheandresult.cachebefore claiming a cache hit or miss. - Use
rejected,/api/utilities, and/api/capabilitiesto 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
sourceMapin the build contract when cached results must retain mappings.
