Repository navigation
Development
- Node.js 24+ (see repo
.nvmrc) - pnpm 11+
- A Cloudflare account (for local D1/R2/KV emulation)
git clone https://github.com/andriansandi/inbix.git
cd inbix
pnpm installThe dashboard and the Worker need matching Clerk keys from the same Clerk application.
Create apps/dashboard/.env:
VITE_CLERK_PUBLISHABLE_KEY=pk_test_your_clerk_publishable_keyThis value must match the CLERK_PUBLISHABLE_KEY used by the Worker.
Create .dev.vars at the repo root:
APP_DOMAIN=inbix.xyz
CORS_ORIGIN=http://localhost:5176
ENVIRONMENT=development
CLERK_SECRET_KEY=sk_test_your_clerk_secret_key
CLERK_PUBLISHABLE_KEY=pk_test_your_clerk_publishable_key
VAPID_PUBLIC_KEY=your_vapid_public_key
VAPID_PRIVATE_KEY=your_vapid_private_key
VAPID_SUBJECT=mailto:noreply@inbix.xyzVAPID_* keys are only required for local Web Push testing.
If the local D1 database does not have tables, apply the migrations manually. pnpm db:migrate is currently not working, so use Wrangler directly:
npx wrangler d1 execute inbix --local --config wrangler.jsonc --file=packages/database/migrations/0001_initial.sql
npx wrangler d1 execute inbix --local --config wrangler.jsonc --file=packages/database/migrations/0002_add_user_id.sql
npx wrangler d1 execute inbix --local --config wrangler.jsonc --file=packages/database/migrations/0003_add_missing_tables.sql
npx wrangler d1 execute inbix --local --config wrangler.jsonc --file=packages/database/migrations/0004_notifications.sql
npx wrangler d1 execute inbix --local --config wrangler.jsonc --file=packages/database/migrations/0005_v02_api_and_automation.sqlThen seed the default domain:
npx wrangler d1 execute inbix --local --config wrangler.jsonc \
--command="INSERT OR IGNORE INTO domains (id, domain, is_default, is_verified, created_at) VALUES ('domain_inbix_xyz', 'inbix.xyz', 1, 1, strftime('%s','now')*1000)"pnpm --filter @inbix/web devThis runs wrangler dev which starts a local Worker at http://localhost:8791 with local D1, R2, and KV emulated by Miniflare.
pnpm --filter @inbix/dashboard devThis runs Vite dev server at http://localhost:5176 with /api requests proxied to the Worker.
# Terminal 1
pnpm --filter @inbix/web dev
# Terminal 2
pnpm --filter @inbix/dashboard devOr use turbo:
pnpm devpnpm typecheck # Type check all packages (run before PR)
pnpm build # Build all packages
pnpm lint # Lint all packages (eslint may not be installed in some envs)
pnpm db:generate # Generate D1 migration from schema changes (currently broken, write SQL manually)
pnpm db:migrate # Run D1 migrations (currently broken, use wrangler d1 execute)
pnpm db:studio # Open Drizzle Studio (visual DB browser)
pnpm --filter @inbix/web tail # View live Worker logs- Edit
packages/database/src/schema/index.ts - Write the migration SQL manually in
packages/database/migrations/ - Update
packages/database/migrations/meta/_journal.json - Apply the migration locally:
npx wrangler d1 execute inbix --local --config wrangler.jsonc --file=packages/database/migrations/XXXX_your_migration.sql
Visual database browser:
pnpm db:studioAdd shared types to packages/shared/src/types.ts and Zod schemas to packages/shared/src/schemas.ts.
Add query functions to packages/database/src/queries/index.ts. Use Drizzle ORM's query builder.
Email parsing logic is in packages/parser/. The main entry is parseEmail() which uses postal-mime to parse raw MIME.
The TypeScript SDK is in packages/sdk/. It provides a InbixClient class with methods for all API endpoints.
The wrangler dev local environment does not support the email() handler. To test email reception:
# Deploy to a staging environment
pnpm deploy
# Send emails to the deployed addressUse the API to test the dashboard without real emails:
# Create an inbox
curl -X POST http://localhost:8791/api/inboxes
# The dashboard will show the inbox- Start the local stack:
pnpm dev- Seed a local test API key:
npx wrangler d1 execute inbix --local --config wrangler.jsonc \
--command="INSERT OR REPLACE INTO api_keys (id, name, key_hash, prefix, user_id, created_at, last_used_at, is_active) VALUES ('key_local_test', 'Local Test Key', '7dff8481e8d2d24bdd50828893c621ebc1b342bbace3ea03854b0ec006e1f7f5', 'inbix_local', NULL, strftime('%s','now')*1000, NULL, 1)"- Run the smoke test:
node packages/mcp-server/scripts/smoke-test.cjsThis starts the MCP server via STDIO and calls create_inbox against http://localhost:8791.
See docs/MCP.md for full client configuration examples.
# Local
pnpm --filter @inbix/web dev # logs in terminal
# Production
pnpm --filter @inbix/web tail# Run a query
npx wrangler d1 execute inbix --command "SELECT * FROM inboxes LIMIT 5"
# Run a query (local)
npx wrangler d1 execute inbix --local --command "SELECT * FROM inboxes LIMIT 5"# List objects
npx wrangler r2 object list inbix-attachments
# Get an object
npx wrangler r2 object get inbix-attachments/attachments/xxx/filename.ext- TypeScript strict mode
- No
anytypes - No comments (self-documenting code)
- Conventional Commits
- File naming:
camelCasefor files,PascalCasefor React components - Import order: external packages → internal packages → relative imports