Skip to content

Local Development

dim145 edited this page Apr 26, 2026 · 1 revision

Local development

This page describes how to develop on MangaCollector without Docker — for hot reload, debugger attach, fast iteration on a single component.

The Docker compose is still useful in dev (it gives you Postgres + Redis + MinIO with one command), but you'll typically run the frontend and backend as native processes against those containerised services.


Toolchain

Component What you need
Backend Rust 1.94 (pinned by rust-toolchain.toml), cargo
Frontend Node 22+ (pinned by package.json engines), npm
Database Postgres 15 (or use the dev compose)
Cache Redis 7+ (or use the dev compose)

Optional but useful: rustfmt, clippy, an editor with rust-analyzer.


Step 1 — Bring up data services

The lightest way to have Postgres + Redis available locally is to start them from the dev compose without the application services:

docker compose up -d db redis

This exposes:

  • Postgres on localhost:18966
  • Redis on localhost:18967

Both with credentials matching server/.env.example.


Step 2 — Run the backend natively

cd server
cp .env.example .env
# fill AUTH_CLIENT_ID / AUTH_CLIENT_SECRET / SESSION_SECRET
cargo run

Migrations run automatically at boot. The first build is ~3-5 minutes (SeaORM, Axum, sqlx are heavy); subsequent rebuilds use the incremental cache and complete in seconds.

Listening on http://localhost:3000 by default. The backend's CORS / cookie policy expects FRONTEND_URL=http://localhost:5173 in dev.

Useful cargo aliases

cargo check        # fast compile check, no codegen
cargo test         # full test suite
cargo clippy --all-targets -- -D warnings
cargo fmt

Hot reload

cargo watch is the cleanest way to get hot reload on backend changes:

cargo install cargo-watch
cargo watch -x run

Each rebuild typically takes 5-10 s on a warm cache.


Step 3 — Run the frontend natively

cd client
npm install
npm run dev

Vite serves on http://localhost:5173 with HMR. The dev server proxies /api, /auth, /ws to http://localhost:3000 — see client/vite.config.js.

The PWA service worker is disabled in dev (no caching aggravation when iterating). To test the PWA flow:

npm run build && npm run preview

This serves the production build from dist/, including the registered service worker.

Useful npm scripts

npm run lint         # ESLint
npm run format       # Prettier
npm run build        # Production build
npm run preview      # Serve production build locally

Editor setup

VS Code

Recommended extensions:

  • rust-lang.rust-analyzer — backend
  • dbaeumer.vscode-eslint — frontend
  • esbenp.prettier-vscode — frontend
  • bradlc.vscode-tailwindcss — Tailwind class autocompletion

JetBrains

The repo ships an .idea/ folder configured for the whole stack — WebStorm picks up the React project, RustRover picks up the backend, IntelliJ Ultimate handles both.


Common dev workflows

Add a backend route

  1. Add the handler in server/src/handlers/.
  2. Wire it in the relevant server/src/routes/ module.
  3. Add the corresponding TanStack Query key + helper in client/src/hooks/ or client/src/utils/.
  4. Test with the dev frontend at http://localhost:5173.

Add a database migration

  1. Pick a fresh timestamp:
    date +%Y%m%d%H%M%S
  2. Create the file: server/migrations/{timestamp}_short_name.sql.
  3. Write forward-only SQL — there's no down migration.
  4. Restart cargo run. The migration runner picks it up at boot.

Run a one-off SQL query

docker compose exec db psql -U mangacollector
# or
psql -h localhost -p 18966 -U mangacollector -d mangacollector

Password matches server/.env.example.

Inspect Redis

docker compose exec redis redis-cli
KEYS *
GET mangacollect/some-key

Frontend-only iteration

If you're working on UI without touching the backend, the easiest setup is:

  1. Run the production backend in Docker:
    docker compose up -d server db redis
  2. Run the dev frontend natively:
    cd client && npm run dev

This way the API is stable (one container), and you get HMR on the UI.


Backend-only iteration

Symmetric scenario:

  1. Run the production frontend in Docker:
    docker compose up -d client traefik
    It will be served at http://localhost:12000.
  2. Run the dev backend natively (cargo run).

You'll need to stop the dev compose's server container so port 3000 is free, then either keep Traefik pointing at the dev backend, or hit http://localhost:3000 directly.


Tests

What How
Backend unit tests cargo test (in server/)
Backend integration none yet — manual
Frontend unit none configured — npm test errors on purpose
Lint + types npm run lint && cargo clippy

The test culture leans on type safety (Rust + TanStack Query schemas) and hand-driven smoke tests rather than unit-coverage. Contributions adding real test infrastructure are welcome.

Clone this wiki locally