Guide · @staticflux/vite-plugin · @staticflux/rspack-plugin · @staticflux/sf · @staticflux/loader
Build tooling: Vite, Rspack & the sf CLI
Packages are bundler-agnostic plain ESM. The only build contract is the loader’s sf-manifest/1; the plugins produce it, and the CLI keeps everyone honest.
#Vite 8 (default)
import { defineConfig } from 'vite';
import { staticflux } from '@staticflux/vite-plugin';
import { chunkDeclarations } from './src/app/chunks.js';
export default defineConfig({
plugins: [staticflux({
chunks: chunkDeclarations,
bootEntries: ['src/boot-browser.ts'],
budgets: { onViolation: process.env.CI ? 'error' : 'warn', bootKb: 150 },
isolation: 'preferred', coep: 'credentialless',
})],
});
Each declaration with an entry becomes a stable, readable chunk (assets/feature.studio-desktop-<hash>.js). The plugin emits sf-manifest.json, sf-preloads.json (per profile), sf-precache.json (critical tier, Workbox format) and sf-build-report.json, injects boot-plan modulepreload tags, serves COOP / COEP / CORP in dev and preview, and checks chunk, eager and boot budgets. App code imports chunks by logical id through virtual:sf-chunks.
import { chunks } from 'virtual:sf-chunks';
defineFeature({ id: 'studio/desktop', weight: 'heavy', modes: ['expanded'],
load: () => chunks['feature:studio-desktop']!() as Promise<FeatureModule> });
#Rspack + Module Federation 2.0
staticfluxRspack(options) emits the same files from the compilation’s chunk groups for organizations deploying independently. It maps remotes’ exposed modules to logical chunk ids and validates host-owned shared singletons and versions at build time (P9: one version per app); the loader re-checks the ranges before a remote’s init. Any other bundler works by producing the same manifest with createManifest from @staticflux/loader.
#The sf CLI
| Command | What it checks |
|---|---|
sf graph <entry> | DI graph: cycles, scope rules, fan-in / fan-out, duplicate and unused providers, boot order, critical set |
sf lint | no-direct-flag-reads, no-bare-listener, inheritance-depth, no-string-tokens, no-default-export |
sf errors | Collects every defineError into docs/errors.json; --check fails on stale or conflicting codes |
sf budgets | Limit vs actual; proposes tightening (ratchet), never loosens |
sf agents | Regenerates the “Budgets” and “Allowed dependencies” sections of every AGENTS.md |
sf routes <entry> | Route × profile completeness: every capability-bound route has a feature for every mode |
sf manifest <file> | Validates an sf-manifest.json: shapes, dangling deps, budgets, eager reasons |
pnpm lint:sf # sf lint over packages/*/src
pnpm errors:check # catalog is current
pnpm budgets # size-limit --json → sf budgets (ratchet proposals)
pnpm agents:check # generated AGENTS.md sections are current
pnpm sf graph dist/units.js --max-fan-out 12 # any module exporting `units`
AGENTS.md on GitHub: @staticflux/vite-plugin · @staticflux/rspack-plugin · @staticflux/sf · @staticflux/loader