Core Framework Integration for Generating CSS Tokens in Instatic
Instatic's Core Framework module centralizes design-system definitions and transforms them into CSS custom properties and utility classes through a validated, multi-stage pipeline.
The Core Framework integration is the engine behind Instatic's token-driven CSS generation. It bridges the visual editor's design panels with the static publishing pipeline, ensuring every site emits consistent, namespaced CSS tokens that can be safely overridden by user styles.
This article walks through the complete workflow—from framework settings in the admin UI to the final framework.css bundle—using actual source paths and function signatures from the CoreBunch/Instatic repository.
How Framework Settings Become CSS Tokens
The pipeline begins when site owners configure design tokens through the admin interface. These settings flow through validation, planning, and rendering stages before reaching the published page.
Step 1: Framework Settings Validation
Site configurations are stored in site.settings.framework and validated against FrameworkSettingsSchema in src/core/framework-schema/schemas.ts. This TypeBox schema enforces type safety for colors, typography, spacing scales, and other design primitives.
Admin panels for Colors, Typography, and Spacing write to this validated structure. Invalid or incomplete settings fail fast at the schema level, preventing downstream errors in CSS generation.
Step 2: Building the Framework Plan
The buildFrameworkPlan function in src/core/framework/index.ts transforms validated settings into an executable plan. This plan contains:
- Root custom-property definitions for color, font-family, and spacing tokens
- Generated utility classes for each scale step (e.g.,
.font-size-lg,.gap-2)
The plan acts as an intermediate representation—decoupled from both the admin UI and the final CSS output. This separation allows the publisher to optimize without affecting the authoring experience.
Step 3: CSS Generation and Bundling
The publisher consumes the framework plan in src/core/publisher/frameworkCss.ts. Two key functions orchestrate this stage:
| Function | Location | Purpose |
|---|---|---|
buildSiteFrameworkCss(site) |
src/core/publisher/frameworkCss.ts |
Orchestrates the full generation workflow |
generateFrameworkCss(site) |
src/core/publisher/frameworkCss.ts |
Renders the final framework.css bundle |
The generated CSS includes:
/* Example output: root custom properties */
:root {
--color-primary: #007bff;
--font-primary: 'Inter', sans-serif;
--space-4: 1rem;
}
/* Example output: utility classes */
.font-size-lg { font-size: var(--font-size-lg); }
.gap-2 { gap: var(--space-2); }
Step 4: Token Emission and Cascade Order
In src/core/publisher/render.ts, the final page CSS is assembled by concatenating four bundles in strict order:
reset— browser normalizationframework— the generated design tokensstyle— component-level stylesuserStyles— custom user CSS
This ordering guarantees framework tokens appear before user-defined CSS, enabling predictable overrides without specificity battles.
Token Scale Generation Internals
The framework doesn't hand-write every token. Shared engines in src/core/framework/ compute systematic scales.
Spacing and Typography Scales
src/core/framework/spacing.ts— implements spacing scale math and token generationsrc/core/framework/typography.ts— implements typography scale and token generation
Both modules leverage src/core/framework/scaleModule.ts, the shared engine that creates the token-to-utility-class mapping. This abstraction ensures consistent naming conventions and calculation logic across different token categories.
Runtime Token Consumption
Framework tokens aren't just for published output. The admin UI itself consumes them through design-token primitives.
UI Primitive: pillAccent
Located at src/ui/pillAccent.ts, this primitive selects deterministic accent tokens from the framework palette:
import { pillAccent } from '@/ui/pillAccent';
const accent = pillAccent('primary'); // → '--pill-primary' custom property
Components like pills, badges, and buttons use these primitives to maintain visual consistency with the site's configured theme without hardcoding values.
Import and Conflict Resolution
When external CSS is imported, the framework handles token extraction and merging through src/core/siteImport/*.
Token Extraction Pipeline
| Module | Function |
|---|---|
src/core/siteImport/colorTokens.ts |
Extracts :root color properties, rewrites as framework tokens |
src/core/siteImport/fontTokens.ts |
Extracts font-family declarations, registers as framework tokens |
src/core/siteImport/conflicts.ts |
Detects and resolves token name collisions |
Imported custom properties are namespace-migrated into the framework registry, preserving their values while ensuring they follow Instatic's token conventions.
Complete Workflow Example
Here's the full chain from settings to published CSS:
// 1️⃣ Resolve framework preferences (with sensible defaults)
import { resolveFrameworkPreferences } from '@core/framework';
const prefs = resolveFrameworkPreferences(site.settings.framework?.preferences);
// 2️⃣ Build the framework plan (scales, colors, utilities)
import { buildFrameworkPlan } from '@core/framework';
const { rootCss, utilityClasses } = buildFrameworkPlan(site.settings.framework);
// 3️⃣ Generate the final CSS bundle for publishing
import { generateFrameworkCss } from '@core/publisher';
const frameworkCss = generateFrameworkCss(site);
// 4️⃣ Use a token in a component (e.g., a Pill)
import { pillAccent } from '@/ui/pillAccent';
const accent = pillAccent('primary'); // → '--pill-primary' custom property
Each stage is pure and testable: preferences resolve against defaults, plans build deterministically from settings, and CSS generates without side effects.
Key Architectural Guarantees
The Core Framework integration provides three invariant properties:
- Namespace safety — all tokens use the
--prefix, preventing collisions with third-party CSS - Tree-shaking — only utility classes actually referenced by site content appear in
framework.css - Zero runtime — the published
framework.csscontains no editor code or JavaScript dependencies, ensuring fully static output
Summary
- The Core Framework validates settings through
FrameworkSettingsSchemainsrc/core/framework-schema/schemas.ts buildFrameworkPlaninsrc/core/framework/index.tscreates an intermediate plan of tokens and utilitiesgenerateFrameworkCssinsrc/core/publisher/frameworkCss.tsrenders the final CSS bundlesrc/core/publisher/render.tsconcatenates bundles with framework tokens first in the cascade- Scale generation is shared through
src/core/framework/scaleModule.tsfor consistent spacing and typography - Imported CSS tokens are extracted and merged via
src/core/siteImport/colorTokens.tsandsrc/core/siteImport/fontTokens.ts - UI primitives like
src/ui/pillAccent.tsconsume tokens at both edit-time and publish-time
Frequently Asked Questions
What file generates the actual framework.css output?
The generateFrameworkCss function in src/core/publisher/frameworkCss.ts renders the final bundle. It consumes the framework plan built by buildFrameworkPlan and outputs CSS containing root custom properties and utility classes.
How does Instatic handle conflicts between imported CSS tokens and existing framework tokens?
Conflicts are detected and resolved in src/core/siteImport/conflicts.ts. The pipeline extracts :root custom properties from imported CSS via src/core/siteImport/colorTokens.ts and src/core/siteImport/fontTokens.ts, rewrites them as framework tokens, and merges them with the existing registry according to conflict resolution rules.
Can users override framework tokens in their custom CSS?
Yes. The render pipeline in src/core/publisher/render.ts concatenates bundles with framework preceding userStyles. This cascade order allows user-defined CSS to override any framework token using standard CSS custom property semantics.
What ensures that only used utility classes are included in the output?
The framework plan tracks which utility classes are referenced by site content. The publisher performs tree-shaking during generateFrameworkCss, emitting only classes that appear in the site's component graph—keeping framework.css lean for performance.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →