Repository navigation
Development
| Path | What |
|---|---|
server/ |
the Express server: sessions, IMAP/SMTP, routes (routes/), contacts, calendar, tasks, rules (Sieve), S/MIME, admin helpers |
web/src/ |
the React + Vite front end (App.tsx, Calendar.tsx, Tasks.tsx, SidePanel.tsx, …) |
web/src/locales/ |
one file per language |
ops/ |
helper scripts for the mail server (goodmail-setpw, goodmail-admin) |
deploy/ |
example systemd unit, Apache vhost, the "be right back" page |
test/ |
unit tests (Node's built-in test runner) |
scripts/screenshots/ |
regenerates the README screenshots from a fake mailbox |
npm run dev # API on :3000 + Vite on :5173 (Node >= 23.6)
npm test # unit tests + a live-server smoke test
npm run typecheck # tsc over server, web and tests
npm run build # dist/ + dist-server/index.mjsThe S/MIME tests skip themselves when openssl with cms is missing.
Copy one of the files in web/src/locales/, translate the values and register it in web/src/i18n.ts. The English text is the key, so anything untranslated falls back to English. The i18n test checks that {placeholders} match and that no translation is empty.
All per-user data is small JSON files written atomically (tasks/, calendar/, contacts/, prefs/, …) through a per-user queue, so no database is needed. See Data and Backups.
scripts/screenshots starts a fake IMAP/SMTP/ManageSieve server with invented demo mail, contacts, events and tasks, and drives headless Chrome through the interface:
cd scripts/screenshots && npm install
npm run demo &
(cd ../.. && npm run build && NODE_ENV=production GOODMAIL_INSECURE_COOKIE=true PORT=3100 \
GOODMAIL_OPENSSL=/opt/homebrew/bin/openssl GOODMAIL_CONFIG=scripts/screenshots/demo.conf \
GOODMAIL_DATA=$(mktemp -d) node dist-server/index.mjs) &
npm run captureStart from a fresh data folder and a fresh npm run demo each time. GitHub caches README images, so bump the ?v= tag in the README image links after regenerating.
Issues and pull requests are welcome. goodmail is AGPL-3.0-or-later: if you run a modified version for other people over a network, offer them the source of your version, and point the in-app "Source code" link at your fork with GOODMAIL_SOURCE_URL.
goodmail
Using it
Security
Running it