Skip to content
HomePagesHomePages template kit
Menu

Rules

Router for the rule corpus — every template-kit/<id> an author can hit, and the page that explains it.

Every authoring rule the kit enforces is printed under one namespace, template-kit/<id>, and resolves to exactly one page here: guide/rules/<id>.md.

One namespace, two venues. Some rules are properties of one file (a Date.now() in a Renderer) and are enforced by the ESLint preset, which ships as its own package, @homepages/eslint-plugin-template. Others are properties of the tree (a slot declared in schema.ts but never marked in the JSX, a stylesheet, a dependency, a byte budget) and cannot be expressed one file at a time; those are enforced by template-kit check. You never need to know which engine produced a violation — only the id, which names its page either way.

Read server vs client first if you are here for any rule that mentions “server-rendered code” or an island. It is the one concept those rules assume, and it is explained there rather than on each of them.

Rule Venue What it enforces
no-nondeterminism eslint No clock or randomness reads in server-rendered code.
no-client-runtime-in-server eslint No effects, state, event handlers, network, or browser globals in server-rendered code.
serializable-island-props eslint Props handed to an island must be JSON-serializable.
require-island-editor eslint Every island must declare whether it is live in the editor canvas.
no-client-directive-in-contract eslint No “use client” in a section’s four contract files.
props-from-schema eslint A Renderer’s Props type must be derived from schema.ts, not hand-written.
no-inline-style eslint No inline style= in server-rendered JSX. Islands are exempt.
no-raw-element eslint No raw <section>, <img> or <video> — use <Section>, <Image> and <Video>.
image-bare-needs-reason eslint <Image bare> needs a // bare: comment saying why it skips the frame.
slot-marker-literal eslint A slot-marker key must be a string literal, not an expression.
no-hex eslint No hard-coded colours — the one legal colour function is a color-mix() over theme-derived arguments. Islands are NOT exempt.
no-css-import-from-render-path eslint No relative/absolute .css import from a section’s render path — a package’s is the sanctioned channel.
bundle-incomplete check A section folder is missing one of its four required files.
bundle-binary-asset check An unreferenced binary asset sits in a section folder.
schema-invalid check A section’s schema.ts or fill-spec.ts fails a contract assertion, or cannot be loaded.
fixtures-invalid check A section’s fixtures.ts does not satisfy the fixture-module shape.
manifest-invalid check A template’s manifest.json is missing, unparseable, or violates the manifest contract.
missing-slot-marker check An editable slot in schema.ts has no marker in the section’s JSX.
slot-group-marker check A group with two or more members has no <SlotGroup> wrapper.
css-reason check A hand-written CSS file must open with a css-reason: comment.
no-bare-css-import check No @import in hand-written CSS — the browser drops it silently.
unlayered-fence check An /* unlayered: */ escape hatch must be balanced and give a reason.
sidebar-order check Schema slot order must match the order the page renders them in.
typecheck check The template must compile under TypeScript.
parse-error check A file could not be parsed at all — a syntax error, not a rule violation.
determinism-drift check Rendering the same fixture twice must produce byte-identical HTML.
render-invariant check Rendered output must carry no [object Object], bare null/undefined/NaN leaf, or src-less <img>.
lockfile-missing check The workspace has no package-lock.json.
lockfile-stale check The lockfile does not satisfy package.json — an npm ci would fail.
single-react check The installed tree carries more than one copy of react or react-dom.
audit-severity check A dependency carries a high or critical security advisory.
license-denied check A production dependency’s license is not on the allowlist.
size-renderer-bundle check A section’s renderer bundle exceeds its byte budget.
size-section-css check A section’s compiled CSS exceeds its byte budget.
size-island-bundle check A section’s island (browser) bundle exceeds its byte budget.
size-assets check A section’s static assets exceed their byte budget.
no-templates check The workspace has no template to check at all.
  • Server vs client — how a file is scoped, and which rules stop at the hydration boundary.
  • ESLint preset — setting the preset up in a template workspace.
  • Check — running template-kit check, its flags, output shape, and exit code.