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/.
template-kit check # infer the template from cwd, or the workspace's one templatetemplate-kit check <template> # check one named template by its keytemplate-kit check --all # check every template in the workspacetemplate-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.
What it needs installed
Section titled “What it needs installed”npm i -D @homepages/template-cli # provides the `template-kit` commandnpm i -D typescript eslint @typescript-eslint/parser esbuild @homepages/eslint-plugin-templatecheck 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.
What it runs
Section titled “What it runs”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:
- typecheck — the workspace’s own TypeScript compiles the template’s files, judged
against the workspace’s own
tsconfig.json. - 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. - validate — the schema, fill-spec, fixtures, and manifest contracts: every
cross-reference between a section’s contract files, and a template’s
manifest.jsonagainst the sections it composes. - tree — the rules a one-file-at-a-time linter cannot express: a missing contract
file, a slot declared in
schema.tswith no marker anywhere in the section’s JSX, a hand-written CSS file’s own rules. - 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 barenull/undefined/NaNleaf, asrc-less<img>— plus, for thetypicalfixture, that the editor’s sidebar order matches the page’s real render order. - 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.
Output
Section titled “Output”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.
Exit code
Section titled “Exit code”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).
Thresholds are not configurable
Section titled “Thresholds are not configurable”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.
See also
Section titled “See also”- 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
checkas the acceptance gate.