Coding conventions for the hyperfrontend Nx monorepo. Use when refactoring, adding features, fixing bugs, or writing any new code across libs/, apps/, tools/, or plugins/.
Installation
Installer avec Codex ou Claude Copiez ce prompt, collez-le dans Codex, Claude ou un autre assistant, puis laissez-le vérifier la page du skill et l'installer pour vous.
Coding conventions for the hyperfrontend Nx monorepo. Use when refactoring, adding features, fixing bugs, or writing any new code across libs/, apps/, tools/, or plugins/.
allowed-tools
["Read","Write","Edit","Grep","Glob","Terminal"]
Coding Skill
Know all enforced rules before generating code. Violations will be caught by lint; fix them preemptively.
Reference Locations
What
Where
Shared libs
libs/
Frontend apps
apps/frontend/
Backend apps
apps/backend/
Tooling
tools/, plugins/
ESLint rule docs
tools/eslint-rules/docs/
Base ESLint config
eslint.base.config.cjs
TS path aliases
tsconfig.base.json → paths
Immutable-safe builtins
@hyperfrontend/immutable-api-utils
Validation Workflow
Run in order, targeting only affected projects:
nx test <project-name>
nx lint <project-name> --fix
nx run <project-name>:typecheck
nx format:write --projects=<project-name>
Module Boundary Tags
Tag
Can depend on
type:core
nothing
type:util
type:core, type:util
type:feature
type:core, type:util, type:feature
type:protocol
type:core, type:util, type:protocol
type:app
type:util
type:demo
nothing (npm packages only)
scope:standalone
nothing (npm packages only)
Import Rules
Order
importtype { Foo } from'./types'// 1. type importsimport { readFileSync } from'node:fs'// 2. node: builtinsimport express from'express'// 3. externalimport { bar } from'@hyperfrontend/utils/string'// 4. workspaceimport { helper } from'../../shared/helper'// 5. relative (deep first)import { local } from'./local'// 6. current dir
// ❌const value = map.get(key)!
// ✅ — type narrowingconst value = map.get(key)
if (value === undefined) thrownewError(`key not found: ${key}`)
// ✅ — optional chainingconst name = user?.profile?.name
JSDoc
Required on all exported .ts members: functions, classes, methods, properties.
@param with description
@returns with description
No @deprecated — use the issue tracker
No @todo
Member docs go above the member as JSDoc, never as trailing comments:
Every // comment must use a recognized prefix or be a tooling directive:
Prefix
why:
how:
context:
magic:
todo:
fixme:
note:
ref:
// ❌// Initialize the counter// ✅// why: Counter starts at 0 to match the API's 0-based indexing
No decorative header comments (banners, ASCII art)
No section dividers (==== blocks)
Never write // TODO / // to-do / /** @todo */ — the lowercase todo: prefix is distinct and allowed
File Size
Only applies when a file has more than one function:
File type
Max lines
Implementation
400
Test (.spec.*)
700
When a file approaches the limit, split into discrete functions. Colocate internal helpers in the same folder as the module they support (e.g. a utils/ or shared/ subfolder beside the main file — not <workspace-root>/libs).
Before extracting a helper as reusable, confirm it immediately deduplicates existing code. Check local utils/, shared/, and feature-adjacent folders first. Only promote to a shared location if other code can be deduplicated right now.
Testing
Names — assertive, no "should"
// ❌it('should return the correct value', ...)
// ✅it('returns the correct value', ...)
Assertions — one per test, use Jest APIs, consolidate with asymmetric matchers
One assertion per test. Each it block should express a single observable fact. Multiple expect calls are only acceptable when asserting over a collection or validating tightly coupled state that cannot be expressed as a single matcher.
Use built-in Jest matchers (expect, toBe, toEqual, toThrow, toHaveBeenCalledWith, etc.). Do not introduce raw assertion libraries or custom matchers unless they already exist in the file.
Consolidate multiple property checks into a single toEqual with asymmetric matchers:
Do not add branches that cannot be reached, and avoid defensive branching that adds complexity without observable behaviour. Every new branch requires a corresponding unit test; if the test cannot be written, the branch should not exist.
New Library Checklist
project.json → name starts with lib-, has description and tags