Contributing to Nagma

Thanks for helping. Nagma is an open-source, self-hostable design suite under the Mozilla Public License 2.0. This page covers setting up, testing, and the few rules every change has to follow.

By taking part you agree to the Code of Conduct. Security problems go to the address in SECURITY.md, not to public issues.

Setting up

You need Node.js 22 and npm. Docker is only needed to try the self-hosted stack.

PartFolderStart it
Editor (React 19, TypeScript, Vite)apps/webcd apps/web && npm install && npm run dev -- --host (http://localhost:5173)
Sync server (Node, no framework)apps/servercd apps/server && npm install && npm run dev
Desktop app (Electron)apps/desktopcd apps/desktop && npm install && npm start (builds the editor first)
MCP serverapps/mcpsee its package.json
VS Code extensionapps/vscode-extensionsee its package.json
Self-hostingDockerfile, docker-compose.yml, tools/install.shdocs/self-hosting.md

The WebAssembly engines in apps/web/src/engines are built from engines/ and committed, so you don't need Rust unless you change an engine (see the Engines section of the README).

Tests and checks

Run what your change touches before opening a pull request. CI (.github/workflows/ci.yml) runs all of it on every pull request to main.

# Editor
cd apps/web
npx tsc --noEmit -p tsconfig.app.json
npx tsc --noEmit -p tsconfig.test.json
npx oxlint src
npx vitest run

# Server and desktop (from the repository root)
node --test apps/server/test/
node --test apps/desktop/test/

# The brand-name guard (must pass)
bash tools/check-brand-names.sh

CI also builds the Docker image, starts the compose stack, waits for /health and signs up an account through the API. If you change the Dockerfile, docker-compose.yml or the scripts in tools/, try docker compose up --build and bash tools/install.sh --dry-run locally.

New behaviour comes with a test: vitest beside the code in apps/web/src, node:test files in apps/server/test and apps/desktop/test.

Commits and pull requests

  • One logical change per commit. The subject line says what changed in plain words, as a sentence fragment without a type prefix, for example Desktop: updates from GitHub Releases, with a download link for unsigned Mac builds. Add a body when the why isn't obvious.
  • Sign off every commit (git commit -s). The Signed-off-by: line certifies the Developer Certificate of Origin 1.1: that you wrote the change, or otherwise have the right to submit it under the project's licence.
  • Keep pull requests focused, fill in the template, and say how you tested. User-facing changes update the README or the docs in the same pull request.
  • Write in plain, concrete English in code comments, docs and the interface: say what a thing does, not how great it is.

Two rules that keep Nagma clean

No other products' names

Nagma imports other tools' files, but it never names the design suite whose files it reads, or its products, anywhere in the tracked files: code, comments, docs, tests, commit-visible strings. Refer to "the design file format", "the import", or the file extension (.fig, .deck). The only exceptions are the two interop modules that hold that format's protocol tokens (apps/web/src/engine/interop-format.ts, apps/server/interop-hosts.mjs).

tools/check-brand-names.sh (and apps/web/src/no-brand-names.test.ts) enforce this; CI fails when either finds a name.

Clean-room format readers

Readers and writers for other tools' formats (.fig, .deck, .sketch, .pptx, .psd, .idml and the rest) are written for interoperability from public documentation and from inspecting files you are entitled to use. Never copy code, assets, icons, fonts, schemas or screenshots from another design product, or from a project whose licence doesn't allow it, and don't contribute anything you learned under an NDA or by breaking a licence's terms. If you aren't sure whether something counts, ask in the pull request before writing it.

Third-party code and assets that Nagma does ship are listed with their licences in THIRD_PARTY_NOTICES.md; add any new one there.

Releases

Maintainers release with tools/release.sh; see docs/releasing.md.

Edit this page on GitHub