Static Kit
Static Kit is a host-agnostic toolkit for compiling CSS (SCSS), JavaScript, and images. It has no WordPress in it anywhere: grep the source and you will find no reference. In a Wonderpress theme it owns everything under static/; it also works standalone, and paths.dist in its .staticrc config can point at nested dist/ folders or at a Shopify theme's flat assets/ directory.
There’s a whole website dedicated to documenting Static Kit, if you are interested.
Install
Static Kit is distributed as a CLI:
npm install -g @wndrfl/static-kit-clistatic install --dir ./staticstatic compile --dir ./static
Do not copy the GitHub tree into a project. The CLI stamps the framework into the theme and owns compile, template create, and component create. In a Wonderpress project you never run even this by hand: wonderpress init installs the kit into the theme’s static/ directory, and wonderpress static compile proxies compilation from the environment root.
Static Kit’s node_modules is installed at setup and never committed. Only hand-written source (static/src) and compiled output (static/dist) are tracked.
The core idea: one bundle per page
Static Kit compiles one entry per page or template, and the theme loads only the current page’s bundle:
src/scss/<page>.scss→dist/css/<page>.csssrc/js/<page>.js→dist/js/<page>.js- wonderpress-core enqueues
dist/{css,js}/<wonder_body_id()>.{css,js}, meaning only the bundle for the template being served.
Each entry @uses or imports only the components that page needs. That import list is the tree-shaking decision: a page ships nothing it does not use.
src/├─ scss/│ ├─ <page>.scss ← per-page ENTRY (home.scss, single.scss, archive-*.scss …)│ ├─ lib/ ← kit primitives: tokens, functions, flex, type, utilities, reset│ └─ components/ ← per-component styles: _<slug>.scss└─ js/ ├─ <page>.js ← per-page ENTRY (home.js, single.js …) ├─ components/ ← per-component behavior: <Pascal>.js └─ lib/ ← kit JS helpers
One standing exception: every page entry @uses lib/utilities, which carries the WordPress .screen-reader-text hide rules (clip-path, never display: none) and the :focus reveal for a skip link. Core-generated markup uses that class, so it ships everywhere. Do not invent a second classname for it.
SCSS components
src/scss/components/_<slug>.scss, selector .<slug>, composed from kit tokens, BEM modifiers and elements:
@use "../lib/tokens" as *;.cta-banner { // &--white { background-color: $color-white; }}
A page opts in with @use 'components/cta-banner'; only where the component appears.
JS components
src/js/components/<Pascal>.js exports a class. Each page entry imports the component classes that page needs and initializes them, mirroring the SCSS entry’s @use list. Nothing under components/ is auto-wired, deliberately: auto-wiring would pull a component into pages that never render it.
Tokens
The kit’s lib/tokens files declare Sass variables in the shape $color-accent: var(--color-accent, fallback), with the host expected to set the matching custom properties on :root. In a Wonderpress theme, wonderpress-core is that host and theme.json is the source of the values. The full contract, including what wonderpress lint checks, is in Design tokens.
Leave the token files as the kit stamped them. Project-specific tokens go in the same shape ($font-mono: var(--font-mono, …)) with a matching theme.json slot.
How Wonderpress delegates
The Wonderpress CLI never writes into static/ itself. It calls the Static Kit CLI, which owns the location and format:
| Wonderpress command | Delegates to |
|---|---|
wonderpress init | installKit (stamps the framework into static/, runs npm install there) |
wonderpress template create | template.create (per-page SCSS and JS entries) |
wonderpress partial create | component.create (style stub, plus the opt-in --js behavior class) |
wonderpress partial remove | component.remove, then deletes the exact paths the manifest recorded |
wonderpress static compile | compile.all with the theme’s static/ as the target (--watch stays on the CLI) |
The paths Static Kit returns at creation are recorded on the partial manifest, so removal deletes exactly what was created even if the kit’s layout has changed between releases. Newer stamps use components/; older trees may still have src/scss/partials and src/js/lib/partials, and the manifest is the source of truth either way.
The @wndrfl/static-kit-cli version range in the Wonderpress CLI’s package.json is the single point of coordination between the two projects. The caret range is intentional: these are first-party packages released in lockstep.