TypeScript Development
Objective
Produce TypeScript solutions in two modes: full projects for compiled browser frontends, Node.js servers, or Node.js CLI tools, and one-offs for ad-hoc execution. Full projects must be OOP-first, strictly typed, tested, and built with the appropriate toolchain for the target use case; one-offs must be short and self-contained.
Scope
In-scope:
- New TypeScript projects, modules, and classes
- Refactors of existing TypeScript code
- One-off snippets
- OOP design with strict typing
- Project structure with src-layout
- Build configuration (Vite for browser, tsc for Node.js)
- pnpm dependency management with Corepack
- Vitest-based testing
- Biome linting and formatting
- Browser frontend projects
- Node.js server projects
- Node.js CLI tools (including agent skill CLIs)
Out-of-scope:
- Framework-specific architecture (React, Angular, Vue component hierarchies)
- GraphQL schema design
- Database ORM configuration
- Docker or deployment configuration
- Monorepo tooling (Nx, Turborepo)
- Deno or Bun runtimes
- CSS/SCSS architecture
Inputs
Required inputs:
- Purpose and functional requirements
- Target output form: FullProject or OneOff
- Target use case: Browser, Server, or CLI
- New development or refactor
Optional inputs:
- Mode selection override
- Existing patterns to mirror
- Domain context (DOM, API, data processing, CLI)
- Performance constraints
- Node.js version constraints (default: 22 LTS)
- Linting alternative (ESLint + Prettier instead of Biome)
Assumptions:
- TypeScript 5.x with strict mode
- pnpm as package manager (version pinned via Corepack)
- Biome for linting and formatting (ESLint + Prettier as alternative)
- fnm for Node.js version management (reads
.node-version) - Node.js 22 LTS unless specified
- Build tool determined by use case:
- Browser: Vite (bundling + dev server)
- Server / CLI: tsc (compilation), tsx (development execution)
Outputs
Format:
- FullProject: directory tree with package.json, tsconfig.json, src/, tests/
- OneOff: snippet (1-10 lines preferred, max 20 lines)
Full Project Structure:
- package.json with project metadata, scripts, dependencies, Corepack
packageManagerfield, andenginesconstraint - tsconfig.json with strict compiler options
- biome.json with lint and format configuration
- .node-version pinning the Node.js runtime version (consumed by fnm)
- src/ with entry point, classes, and modules
- tests/ with Vitest test files
- Type annotations on all signatures
- Additional per use case:
- Browser: vite.config.ts, index.html
- Server: vitest.config.ts
- CLI: vitest.config.ts, src/cli.ts for argument parsing
Files produced:
- FullProject: complete directory tree (see references/templates.md)
- OneOff: no file unless requested
Formatting requirements (FullProject):
- Formatting enforced by Biome (do not specify manually)
- Import ordering enforced by Biome
organizeImports - Naming conventions: see references/standards.md
- Guard clauses at method entry (instruction-only; not enforceable by tooling)
- Max 3 levels of nesting (instruction-only; not enforceable by tooling)
Constraints
Conflict resolution: User requirements override defaults unless they violate safety or explicit MUST rules.
Mode selection rules:
- OneOff when user asks for a snippet, quick function, or inline solution
- FullProject when user asks for an application, reusable library, or multi-file project
- Default to FullProject when ambiguous
Use-case selection rules:
- Browser when building a web frontend or browser utility
- Server when building a web server, API, or backend service
- CLI when building a command-line tool, script, or agent skill utility
- Default to CLI when ambiguous for Node.js projects
Global MUST:
- Choose FullProject or OneOff and follow the mode rules
- Use strict typing on all function and method signatures
- Enable
strict: truein tsconfig.json - Use ESM (
import/export) exclusively; no CommonJS (require)
Global MUST NOT:
- Use
anytype unless interfacing with untyped third-party code (useunknownand narrow instead) - Use
console.logfor diagnostics in production code (use a structured logger) - Use
vardeclarations (useconstby default,letonly when reassignment is required) - Use non-null assertion operator (
!) without a code comment justifying it - Reimplement standard library or platform functionality
- Use default exports (use named exports exclusively)
- Use
enum(useas constobjects or union types instead)
FullProject MUST:
- Encapsulate all business logic in classes
- Use
privateandreadonlymodifiers to enforce encapsulation - Use interfaces for public contracts and dependency injection
- Use abstract classes when sharing implementation across a hierarchy
- Use
readonlyon all properties that are not reassigned after construction - Validate all constructor parameters with guard clauses
- Use specific error classes extending a base application error
- Include Vitest tests in tests/ directory
- Organize tests into
describeblocks mirroring source classes - Test happy paths, error paths, and edge cases for every public method
- Use
it.eachordescribe.eachfor data-driven tests with 3+ input variations - Define all configuration as typed objects (no loose string keys)
- Document all public classes, methods, and interfaces with TSDoc
- Keep module-level code limited to imports, constants, and class/function definitions
- Pass
tsc --noEmitwith zero errors - Pass
pnpm biome check .with zero violations - Include Biome and Vitest in
devDependencies
FullProject MUST NOT:
- Hard-code environment-specific values (URLs, ports, paths) outside configuration
- Place business logic outside classes
- Use module-level mutable state
- Catch and suppress exceptions silently
- Mix argument parsing or I/O handling with business logic
- Use
// @ts-ignoreor// @ts-expect-errorwithout a specific justification comment
OneOff MUST:
- Prefer 1-10 lines, maximum 20 lines
- Skip classes, TSDoc blocks, and project scaffolding
- Use arrow functions and modern syntax
- Use type annotations on any function definitions
OneOff MUST NOT:
- Create a full project scaffold
- Add long-form documentation
Procedure
- Select mode using the mode rules.
- Determine use case (Browser, Server, or CLI).
- FullProject: scaffold directory structure per use case, then populate tsconfig.json, package.json, biome.json, source files, and tests. Add vite.config.ts for Browser or vitest.config.ts for Server/CLI.
- OneOff: write the minimal typed snippet within line limits.
- Apply typing, guard clauses, error handling, naming conventions, and documentation.
- CLI projects: apply patterns from references/cli-patterns.md — testable argument parsing, two-layer validation, structured output.
- FullProject post-generation: run
pnpm install,pnpm run build,pnpm run lint,pnpm run test.
Validation
Pass conditions (FullProject):
- Structure matches the Full Project Structure list
- All public classes, methods, and interfaces have TSDoc documentation
- All signatures are strictly typed; no implicit
any strict: trueis enabled in tsconfig.json- Guard clauses validate constructor and method preconditions
- Error classes extend a base application error
- Tests cover success paths, error paths, and boundary values
tsc --noEmitreports zero errorspnpm biome check .reports zero violationsvitest runpasses with zero failures- Max nesting depth is 3
Pass conditions (OneOff):
- Line count within limits
- Type annotations present on all function signatures
- No project scaffolding or documentation blocks
- Uses modern TypeScript syntax (const, arrow functions, template literals)
Failure modes:
anytype used without justification- Public method or class missing TSDoc
- Business logic placed outside a class
- Default export used
enumused instead ofas constor union type- Test file missing for a source module
- Error caught and suppressed without re-throw or specific handling