This repo pins the Node and npm toolchain so every developer (and CI) builds against identical versions. Please do not skip these steps — drift here is the number-one cause of "works on my machine" bugs.
-
Install a Node version manager that reads
.nvmrc. fnm is recommended (faster than nvm, auto-switches oncd). Homebrew Node works too but will not respect Corepack'spackageManagerenforcement.brew install fnm # Add to ~/.zshrc: # eval "$(fnm env --use-on-cd --shell zsh)"
-
Install the pinned Node version. The version is in
.nvmrc.fnm install # installs the pinned version fnm use # activates it in the current shell
-
Enable Corepack. This lets Node fetch the exact npm version specified by the
packageManagerfield inpackage.json:corepack enable corepack enable npm # Corepack doesn't shim npm by default — this opts in
-
Install npm dependencies via the Makefile:
make install-deps
This runs
npm ciat both the repo root and insideweb-client/. Both installs are required — the root owns husky git hooks and Playwright orchestration;web-client/owns the actual Vue app.
- Root
package.json— git hooks (husky), Playwright runner, environment tooling. Must live at the git root because husky installs hooks into.git/. web-client/package.json— the Vue 3 app: runtime dependencies, build tooling (Vite, TypeScript, ESLint), all the things you'd expect.
The Makefile is the canonical interface. Prefer it over raw npm/vite
commands so your local workflow matches CI.
| Task | Command |
|---|---|
| Fresh-clone install of npm deps | make install-deps |
| Clean + reinstall npm deps (preserves lockfiles) | make reinstall-deps |
| Full rebuild from scratch (wipe + reinstall + build) | make rebuild-all |
| Regenerate lockfiles from scratch (rare) | make regen-lockfiles |
| Verify your Node/npm versions | make doctor |
| Verify lockfiles are in sync (CI guardrail) | make verify-lockfiles |
| Run dev server | make run |
| Production build | make build |
| Preview production build | make preview |
| TypeScript check | make typecheck |
| Lint / lint-fix | make lint / make lint-fix |
| Unit tests | make test-unit |
| E2E tests | make test-e2e |
| Run everything CI runs | make ci-check |
| Full help | make help |
make install-deps(wrapsnpm ci) — installs exactly what is in the lockfiles. Never modifiespackage.jsonor the lockfiles. Use this for every fresh clone, every branch switch, and in CI.npm install— re-resolves dependencies and may rewrite bothpackage.jsonandpackage-lock.json. Only use this when you are intentionally adding or upgrading a dependency, and commit both files together in the same commit.
If a PR diff shows large, unexpected changes to either package-lock.json,
something is wrong — usually a wrong Node/npm version, or npm install was run
by accident. Revert the lockfile changes, run make install-deps, and try again.
Decide which package.json the dep belongs in (root vs web-client/), then:
cd web-client # or stay at root, depending on target
npm install <pkg>@<version> # or: npm install <pkg> for latest compatibleCommit both package.json and package-lock.json from that directory in the
same commit.
The Playwright workflow calls the same Make targets you use locally:
make verify-lockfiles— fails ifnpm ciproduces a diff against committedpackage.json/package-lock.jsonin either location.engine-strict=truein both.npmrcfiles — blocks Node/npm versions below theenginesrange.make test-e2e— the same Playwright command you can run locally.
If CI fails on lockfile drift, running make verify-lockfiles on your branch
will reproduce the failure.
Line-ending and binary-file rules live in .gitattributes.
If you are adding a new binary asset type (e.g. a new font or image format)
not already listed, add an explicit binary rule there so cross-platform
checkouts don't corrupt it.