Programmatic API
English · 简体中文
Use the API when a build tool, editor, service or test needs compiled CSS as data instead of invoking a command. The only required argument is the CSS string; configuration, PostCSS processing options, browser targets and quality gates are optional.
One stylesheet
import { compileAdaptiveCss } from 'postcss-adaptive-matrix'
const output = await compileAdaptiveCss('.card { padding: 24px }')
console.log(output.css)output contains css, warnings, map, compatibility, gate and the full PostCSS result. Without targets, compatibility is null; without failOn (or with []), gate is null. Syntax and configuration errors reject the promise.
Result ownership
Each compilation returns its own AST, warnings, compatibility report and gate. Mutating those returned collections does not reconfigure the compiler or change later results. However, css, map, diagnostics and the gate describe the compilation as returned: they are not live views of result.root. If a downstream transform edits the AST, serialize and regenerate source maps through PostCSS, then rerun any audits or gates required for the edited output. Changing the AST alone does not refresh output.css or the earlier verdict.
Regenerate an edited AST
Before reusing an edited result, serialize the changed AST and audit that new CSS:
import { compileAdaptiveCss, auditCompatibility } from 'postcss-adaptive-matrix'
const targets = { safari: 12 }
const output = await compileAdaptiveCss('.card { width: 40px }', {}, { targets })
output.result.root.walkDecls('width', (declaration) => {
declaration.value = '40px'
})
const edited = output.result.root.toResult({ map: false })
const compatibility = auditCompatibility(edited.css, targets)
// Use edited.css and compatibility, not output.css or its earlier audit.This example deliberately disables maps. If your pipeline needs source maps, pass the appropriate paths and upstream map when generating the new result. Recompute your build policy too; this standalone audit does not update output.gate.
Reuse a compiler
import { createAdaptiveCompiler } from 'postcss-adaptive-matrix'
const compile = createAdaptiveCompiler({ profiles: { app: 375 } })
const output = await compile(source, {
process: { from: 'src/card.css', to: 'dist/card.css', map: { inline: false } },
targets: { safari: 14 },
failOn: ['warnings', 'compatibility'],
})One compiler instance retains conversion caches while dynamic file-based rulers refresh for every call. Requests snapshot target, gate and source-map option fields, syntax hooks and object-form stringifier hooks before asynchronous processing. This captures function references, not mutable state inside callbacks; previous-map objects are not deep-cloned.
Treat compiler configuration as fixed for the lifetime of that instance. Profiles (including fluid bounds and query objects), media route bands and root injection filter arrays are captured when it is created. To apply an edited configuration in a development server, create a new compiler and use it for subsequent requests; already-started calls continue with the old instance. Do not mutate shared configuration to reconfigure a running compiler.
Resolver functions are intentionally retained, not evaluated once and frozen. A designWidth or rootValue callback can still return a different ruler for each file or rebuild. State captured by your callbacks remains your responsibility, including when requests overlap.
Gates and maps
Analysis canonicalizes complete escaped at-rule names supplied in PostCSS ASTs, including media conditions and property registrations. This does not repair source text whose at-rule name the default parser has already split into the name and parameters; support depends on the AST provided by the upstream parser or plugin.
Compatibility gates require targets and fail for unsupported features or unknown browser names. A failed gate still returns CSS and diagnostics; the caller chooses whether to set an exit code. Inline PostCSS maps are embedded in CSS and therefore leave map undefined; external maps return a map object. process.map.prev chains an upstream map.
The API gate covers warnings and compatibility, not CLI continuity analysis. Use the CLI JSON report when continuity findings are part of the build policy.
The analyzer considers math expressions and bare viewport-unit values, including output from profiles with no fluid bounds. This is a syntax heuristic, not compiler provenance: authored fluid expressions can also produce findings. Plain fixed-pixel changes remain excluded.
Diagnostic length evaluation has a 128-level recursive-descent budget for nested expressions and unary operations. Exceeding it returns unknown instead of overflowing the JavaScript stack. This limits analysis, not CSS compilation; a clean report is not evidence that such a value was checked.
Continuity analysis samples 0.05 CSS pixels below and above each known breakpoint. This accommodates common 0.02px gaps, but it is not an exact limit calculation: narrower intermediate ranges can be crossed by a probe. Findings are diagnostic evidence to investigate, not a proof of continuity at every viewport width.
For an in-process continuity check, compose the exported analyzer with the compiled root. Pass the same root font size to both conversion and analysis (the default is 16). Resolve a dynamic root font size once for the file and supply that number to both calls, rather than invoking a changing callback twice.
import { compileAdaptiveCss, findContinuityIssues } from 'postcss-adaptive-matrix'
const rootValue = 20
const output = await compileAdaptiveCss(source, { rootValue })
const seams = findContinuityIssues(output.result.root, rootValue)
const accepted = output.gate?.passed !== false && seams.length === 0The analyzer accepts a Root or a PostCSS Document. Document roots are analyzed independently and findings are concatenated in root order; rules and custom properties never leak across roots. To associate findings with individual files or use a different root font size per file, analyze each root separately.
This is a static check for backwards length steps at resolvable viewport breakpoints, not a layout or visual test. Unresolvable values and conditions are skipped; an empty report does not certify every responsive layout. The optional root font size defaults to 16; an explicitly supplied value must be a positive finite number or the analyzer throws a RangeError.
The package includes ESM and CommonJS type declarations. Import AdaptiveCompileOptions, AdaptiveCompileResult, AdaptiveCompileGate and AdaptiveCompileGateCategory instead of restating the result contract.
Server-only TypeScript projects
The main postcss-adaptive-matrix entry can be used with NodeNext resolution and lib: ["ES2022"] without the DOM library. Consumer tests cover both ESM and CommonJS with exactOptionalPropertyTypes enabled. The separate postcss-adaptive-matrix/runtime entry describes browser objects such as Window and HTMLElement; browser projects using it need DOM types. Do not import that helper just to compile CSS in a Node service.
Errors and recovery
Token substitution in continuity diagnostics is bounded per resolution: at most 4,096 substitution calls, 1,048,576 cumulative input UTF-16 code units and 65,536 output code units. Exceeding a budget returns unknown and skips that comparison. Budgets reset for the next resolution; these are diagnostic limits, not CSS compilation limits or process-memory guarantees.
A syntax error, invalid request or throwing configuration callback rejects the compile promise. A diagnostic gate failure does not: inspect output.gate?.passed === false before accepting output into a build. Warnings and PostCSS results belong to each call, so a failed or warning-producing request does not contaminate later requests on the same compiler. Dynamic rulers are refreshed on the next compilation even after a callback throws.
const compile = createAdaptiveCompiler()
try {
const output = await compile('.card { padding: 24px }', { failOn: 'warnings' })
if (output.gate?.passed === false) {
console.error('CSS quality gate failed', output.warnings.map((warning) => warning.text))
} else {
console.log(output.css)
}
} catch (error) {
console.error('CSS compilation failed', error instanceof Error ? error.message : 'Unknown error')
}In a service, keep detailed compiler diagnostics in trusted logs: source paths and authored CSS can be sensitive. Return a suitable public error instead of exposing raw exceptions to untrusted clients.