Stedefast

Contributing

Code Standards

2 min read

Code Standards

TypeScript

All packages use strict mode with noUncheckedIndexedAccess. This means:

  • No implicit any
  • Array index access returns T | undefined
  • All function parameters and return types must be inferrable or explicit
// ✗ — implicit any
function process(data) { ... }

// ✓
function process(data: Record<string, unknown>): string { ... }

When you genuinely need any (e.g. CF Workers globals not typed in Node), add a biome-ignore comment:

// biome-ignore lint/suspicious/noExplicitAny: CF Workers global
const msg = new (globalThis as any).EmailMessage(...);

Use import type for type-only imports:

import type { StedefastPlugin } from "@stedefast/core";
import { definePlugin } from "@stedefast/core";

Biome (lint + format)

We use Biome for both linting and formatting — no Prettier, no ESLint.

pnpm check          # check all files
pnpm check --write  # auto-fix

Key conventions (see biome.json at the repo root):

  • Indentation: 2 spaces
  • Quotes: double quotes in TypeScript/TSX
  • Semicolons: always
  • Line width: 80 characters
  • Import sorting: automatic

Commit messages

We enforce Conventional Commits via commitlint:

feat(plugin-mermaid): add dual-theme support
fix(module-search): handle empty content nodes
docs(contributing): add module PR checklist
test(content): add listing page pagination tests

Valid types: feat, fix, docs, test, refactor, perf, chore, ci.

The scope (in parentheses) should be the package name suffix — plugin-shiki, module-comments, cli, content, etc.

Testing

We use Vitest. Test files live at src/__tests__/*.test.ts alongside source code.

pnpm test                                     # run all tests
pnpm --filter /content test         # single package
pnpm --filter /content test --watch # watch mode

Guidelines:

  • Test behaviour, not implementation — test what goes in and what comes out
  • Don't mock internal modules — use real implementations
  • Use the provided mock helpers for CF bindings (D1, KV) — see module-comments/__tests__
  • One describe per module/function, one it per behaviour

File naming

  • Source files: kebab-case.ts
  • React components: PascalCase.tsx
  • Test files: kebab-case.test.ts
  • No barrel index.ts re-exports in src/ — import directly from the source file

Pre-commit hooks

Lefthook runs automatically on git commit:

  1. biome check on staged .ts/.tsx files
  2. tsc --noEmit on the affected package

If either fails, the commit is blocked. Fix the issue and recommit — don't use --no-verify.

Changelog

Add a CHANGELOG.md entry in the relevant package for any user-facing change:

## [Unreleased]

### Added
- `lazy` option to defer language loading until the code block is in view (#123)

### Fixed
- Dual-theme CSS variables not applied when `themes` config is used (#124)

Format follows Keep a Changelog.