Skip to content

Coding style

This page is the canonical reference for coding conventions in TomeTrove. For the Cloudflare runtime context (wrangler, drizzle-kit, Workers limits), see Cloudflare Workers. For documentation conventions, see Documentation style.

Language

TomeTrove is written in TypeScript and runs on Cloudflare Workers (see ADR 0001 and ADR 0002).

Formatting and linting

Biome is the single tool for formatting, linting, and auto-fixing. Run it before committing:

npx biome check --write

Type-check with the TypeScript compiler (no emit):

npx tsc --noEmit

Method binding (ADR 0012)

Service class methods use arrow function properties so that this is bound at construction time and methods are safe to pass as callbacks:

class BookService {
    constructor(private repo: BookRepository) {}

    markAsRead = async (book: Book): Promise<Book> => {
        return this.repo.save({ ...book, status: "read" });
    };
}

Route handlers use anonymous arrow wrappers that call service methods — the idiomatic Hono pattern (see ADR 0008 for the routing architecture):

router.get("/books/:id/read", async (c) => {
    await service.markAsRead(c.req.param("id"));
});

Do not use .bind() at call sites or in constructors. See ADR 0012 for the full rationale.

Testing

Vitest with the Workers runtime is the test framework (see ADR 0010):

npx vitest

Schema changes

After changing src/db/schema.ts, generate a migration and apply it with Drizzle Kit. For the migration strategy, see ADR 0009; for the database choice (D1 + Drizzle), see ADR 0003.

npx drizzle-kit generate
npx drizzle-kit migrate

Type generation

After changing bindings in wrangler.jsonc, regenerate the TypeScript types with Wrangler:

npx wrangler types

Commits

TomeTrove uses semantic commit messages. Every commit must use this format:

<type>(<scope>): <description>

[optional body]

[optional footer]

Types

Type Purpose
feat A new feature
fix A bug fix
docs Documentation-only changes (ADRs, reference docs, guides)
refactor Code changes that neither fix a bug nor add a feature
test Adding or correcting tests
chore Build, tooling, dependencies, CI configuration
style Formatting, linting, whitespace — no code logic change
perf Performance improvement

Scope (optional)

The scope identifies the area of the codebase: api, db, ontology, i18n, auth, frontend, logging, etc. Examples: feat(api): add GET /api/books endpoint, docs(adr): approve ADR 0023.

Rules

  • The description is lowercase, imperative mood, no trailing period (e.g. add price fetch endpoint, not Added price fetch endpoint.).
  • The body (if present) explains why, not what — the diff already shows what.
  • Breaking changes use ! after the type/scope: feat(api)!: change pagination response shape — and include a BREAKING CHANGE: footer.
  • Squash commits before merging a PR — the PR's commit history should be clean and semantic.