Skip to content
HomePagesHomePages template kit
Menu

template-kit check

The `template-kit check` command — what it runs, its flags, its output shape, and its exit code.

template-kit check is the one command that answers “will the platform accept this template?” — the same gate you run locally and the one the registry re-runs when you submit. Every failure prints a stable template-kit/<id>, a file:line where one applies, and a one-line fix hint. The id resolves to its own page under rules/.

Terminal window
template-kit check # infer the template from cwd, or the workspace's one template
template-kit check <template> # check one named template by its key
template-kit check --all # check every template in the workspace
template-kit check --json # machine-readable report (combine with any of the above)

Run it from the workspace root, or from inside a template’s own folder — a bare check infers which template you mean. A workspace with more than one template must either name one or pass --all.

Terminal window
npm i -D @homepages/template-cli # provides the `template-kit` command
npm i -D typescript eslint @typescript-eslint/parser esbuild @homepages/eslint-plugin-template

check runs your toolchain, not a copy of its own: it resolves TypeScript, ESLint and esbuild from your workspace, so the compiler that judges your types is the one you pinned, and a linter and a bundler never end up in the production install of a package whose job is to render sections. A missing one is reported by name, with the install line to fix it.

Two granularities, because a workspace has one package.json and one lockfile, but can hold many templates.

Six authoring stages, run in order, once per selected template. None of them abort the run — a template with several unrelated problems reports all of them in one pass, not one class of fix at a time:

  1. typecheck — the workspace’s own TypeScript compiles the template’s files, judged against the workspace’s own tsconfig.json.
  2. lint — the workspace’s own ESLint, running your own eslint.config.mjs — and so the authoring preset it imports — over the template’s files. See that page for the rules this stage shares with your editor.
  3. validate — the schema, fill-spec, fixtures, and manifest contracts: every cross-reference between a section’s contract files, and a template’s manifest.json against the sections it composes.
  4. tree — the rules a one-file-at-a-time linter cannot express: a missing contract file, a slot declared in schema.ts with no marker anywhere in the section’s JSX, a hand-written CSS file’s own rules.
  5. render — a determinism probe (every fixture is rendered twice; the two outputs must be byte-identical) and a scan of the rendered HTML for objective defects — a stray [object Object], a bare null/undefined/NaN leaf, a src-less <img> — plus, for the typical fixture, that the editor’s sidebar order matches the page’s real render order.
  6. size — every section’s renderer bundle, compiled stylesheet, and largest island (browser) bundle, gzipped, against a fixed byte budget; and its static assets (svg/images/fonts), budgeted by raw bytes since they are already compressed.

The dependency gates run once per invocation, never once per template — they are properties of the workspace’s one lockfile and installed tree, not of any one template: a lockfile present and satisfying package.json, exactly one copy of React installed, no npm audit finding at high or critical severity, and every shipped dependency’s license on an allowlist.

A run that selects zero templates to check is itself a failure — no-templates — never a silent pass.

Human-readable output prints one line per template (✓ <key>, or ✗ <key> — N problem(s) followed by each finding), then any workspace-level findings from the dependency gates, then check passed if everything passed.

--json prints one report object instead, keyed per template so a single-template consumer (the registry, ingesting one submission) and an all-templates consumer (your own CI) parse the same shape:

{
ok: boolean,
kitVersion: string,
templates: {
[templateKey: string]: { ok: boolean, diagnostics: Diagnostic[] },
},
// Dependency-gate findings — evaluated once, not per template.
workspace: { ok: boolean, diagnostics: Diagnostic[] },
}

Each Diagnostic carries a ruleId (template-kit/<id>), the template it belongs to, an optional section and file/line, a message, and a fix.

0 iff every selected template and the workspace pass. 1 otherwise — including when the run itself can’t proceed at all (an unknown template name, no templates/ folder in the workspace).

Every byte budget, severity floor, and license allowlist check enforces is a platform acceptance criterion, not a per-workspace preference — there is no config file or flag that raises them. If a template has a legitimate reason to need an exception, ask the platform team; a workaround that quietly disables a gate will simply fail again at submission.

  • Rules — every id check (and the lint preset) can print, one page each, Rule / Reason / Fix.
  • ESLint preset — the one-file-at-a-time half of the same rule set, run directly by your editor, not only through check.
  • Dev — the other workspace command: preview sections in a browser as you author, before running check as the acceptance gate.