Thank you for your interest in contributing! OpenMail is built by and for developers who want a better, open alternative to Customer.io.
- Bug reports — open an issue
- Feature requests — start a discussion or open an issue
- Code — fix bugs, implement features, improve docs
- Docs — improve README, add guides, fix typos
- Design — UI/UX improvements to the dashboard
- Bun v1.0+
- PostgreSQL 15+
- Redis 7+
# 1. Fork and clone
git clone https://github.com/YOUR_USERNAME/openmail.git
cd openmail
# 2. Install dependencies
bun install
# 3. Set up environment
cp api/.env.example api/.env.local
cp worker/.env.example worker/.env.local
cp tracker/.env.example tracker/.env.local
# Fill in DATABASE_URL, REDIS_URL, RESEND_API_KEY, BETTER_AUTH_SECRET
# 4. Run migrations
bun db:generate
bun db:migrate
# 5. Start services
bun dev:api # :3001
bun dev:worker
bun dev:tracker # :3003
bun dev:mcp # :3002
bun dev:web # :5173Or use Docker Compose for the full stack:
cp .env.example .env
docker compose up -d- Branch naming:
feat/description,fix/description,docs/description,chore/description - Keep PRs focused — one feature or fix per PR
- Write clear commit messages — follow Conventional Commits
- Update docs — if you change behavior, update README or relevant docs
- TypeScript — all code must be TypeScript, no
anyunless truly necessary - No console.log — use pino logger
- No polling — use event-driven patterns
type(scope): short description
feat(api): add webhook ingestion endpoint
fix(worker): filter unsubscribed contacts before broadcast send
docs(readme): add MCP configuration example
chore(deps): upgrade drizzle-orm to 0.42
- TypeScript strict mode — no ignoring type errors
- No try/catch unless absolutely necessary
- Lazy initialization for all services (env vars inside functions, not module top-level)
- Hard deletes only — no soft delete patterns
- API routes only, no server actions
openmail/
├── packages/shared/ # Drizzle schema, shared types, DB client
├── api/src/
│ ├── lib/ # auth, redis, logger
│ ├── middleware/ # session-auth, workspace-api-key-auth
│ └── routes/ # one file per resource
├── worker/src/
│ ├── jobs/ # one file per queue worker
│ └── lib/ # redis, resend, segment-evaluator
├── mcp/src/
│ ├── tools/ # one file per MCP tool group
│ └── lib/ # api-client
├── tracker/src/ # pixel + click tracking
└── web/src/
├── components/ui/ # shadcn-style UI components
├── hooks/ # TanStack Query hooks
├── routes/ # TanStack Router file-based routes
└── store/ # Zustand global state
Look for good first issue labels. These are well-defined, self-contained tasks ideal for new contributors.
- Open a GitHub Discussion
- Email: kai@1flow.ai
We review all PRs within 2–3 business days. Thank you for contributing!