Local development
Use this guide to start a development environment and run checks before changing Calends source code.
- Install Node.js 22, clone the repository and run the setup commands below.
- Open the local app; follow the instructions for
.dev.varsif you need to bypass sign-in. - Run checks relevant to your changes, then review the full checklist before submitting.
You’ll need Node.js 22.
git clone https://github.com/imetn/calends && cd calendsnpm cinpm run db:migrate:localnpm run devTo bypass sign-in during development, add DEV_BYPASS_AUTH=1 to .dev.vars, preserving existing contents.
npm run dev starts two processes: Vite (front end with hot reload, :5173) and wrangler (the Worker and a local D1, :8787). Open http://127.0.0.1:5173/admin.
The local database is kept in .wrangler/state at the repository root.
Common commands
Section titled “Common commands”| Command | What it does |
|---|---|
npm test |
Unit tests (billing, phases, metrics, shared plans, categories and more) |
npm run typecheck |
TypeScript type check |
npm run lint |
oxlint |
npm run format / npm run format:check |
Prettier format / check |
npm run i18n:check |
Checks every language has every string |
npm run build |
Production build |
npm run email:preview |
Renders every reminder email with sample data into .preview/email/ as HTML; sends nothing |
npm run demo |
Generates the demo ledger of the made-up user Alex and writes it to the local database |
Code layout
Section titled “Code layout”src/ app and public pageshared/ billing, phases, metrics, FX, masking, i18n — shared by browser and Workerworker/ API, auth (password + passkeys), MCP, reminders and channels, backup, ICSmigrations/ D1 / SQLite schemadocker/ self-hosting image entrypointStack: React 19 with the React Compiler and Vite for the app, with react-aria-components for dialogs, menus and controls; shadcn/ui for the public page; Cloudflare Workers + D1 on the server.
Before a pull request
Section titled “Before a pull request”npm run typecheck && npm run lint && npm run format:check && npm run i18n:check && npm test && npm run buildA few ground rules (see CONTRIBUTING.md in the repository):
- Domain logic lives in
shared/and must run in both the browser and the Worker — no DOM or Node APIs. Add unit tests inshared/*.test.tsfor billing, phase or metric changes. - Every user-visible string goes through
t(), and never at module top level. Add new strings toenandzh-CNat least. - Keep stored data compatible. Old records must keep working; schema changes go in a new file under
migrations/; new data must round-trip through backups. - Privacy: anything that could identify a person or account stays off the public page;
shared/mask.tsallow-lists what’s shared. - Keep the UI consistent with existing components and check phone width (390px), desktop, light and dark.