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:
Type-check with the TypeScript compiler (no emit):
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):
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):
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.
Type generation¶
After changing bindings in wrangler.jsonc, regenerate the TypeScript types with Wrangler:
Commits¶
TomeTrove uses semantic commit messages. Every commit must use this format:
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, notAdded 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 aBREAKING CHANGE:footer. - Squash commits before merging a PR — the PR's commit history should be clean and semantic.