An open, clean-room business suite inspired by the behaviour of full-featured ERPs — app launcher, kanban pipelines, list/form/graph/pivot/calendar views, search panel, chatter. Written from scratch: no third-party ERP code, assets or branding. English and Arabic (RTL).
How the reference behaviour was observed (REA browser captures) and what was a design choice is documented in SPEC.md.
Discuss · Calendar · Appointments · To-do · Knowledge · Contacts · CRM · Sales · Dashboards · Subscriptions · Rental · Point of Sale · Invoicing/Accounting · Documents · Project · Timesheets · Planning · Helpdesk · Website (pages + online shop) · Email Marketing · Events · Purchase · Inventory · Manufacturing · Shop Floor · Barcode · Sign · Employees · Recruitment · Time Off · Payroll · Expenses · Maintenance · Quality · Repairs · Field Service · Fleet · Attendances (kiosk) · Appraisals · Surveys · Lunch · Approvals · Frontdesk · eLearning · Live Chat · SMS Marketing · Social Marketing · Marketing Automation · PLM · Meeting Rooms · Referrals · Skills · ESG · Studio (custom fields) · Apps (install/uninstall) · Settings (56 apps)
POS includes a Kitchen Display; users can be restricted to specific apps; company, apps and Studio changes are admin-only.
Core features on every model: kanban/list/graph/pivot/calendar/Gantt views, search panel (filters, group by, favorites, archived), activities with a due-today counter, chatter with tracked changes, smart buttons, CSV export/import, duplicate/archive/delete actions, multi-level grouped lists.
Accounting is double-entry (credit notes, bank reconciliation, pricelists, discounts): chart of accounts, journals, journal entries generated by invoices, payments, expenses, POS and payroll; Profit and Loss, Balance Sheet and General Ledger reports.
Cross-app flows: manufacturing order consumes components → finished stock; subscription → recurring invoices; POS sale → stock out; quotation → sales order (stock out) → invoice → payment; RFQ → purchase order → receipt (stock in) → vendor bill.
npm install
npm run build
npm start # server + app on http://localhost:8069 (login required)On first start the server creates user admin and prints a random password
(or set MIZAN_ADMIN_PASSWORD). Admins add users in Settings.
Environment: PORT (8069), MIZAN_DB (SQLite file, default mizan.sqlite),
MIZAN_SECURE_COOKIE=1 when served over HTTPS.
Development: npm start in one terminal and npm run dev in another — Vite proxies /api to the server.
Without a server the frontend runs as a browser-only demo (data in localStorage).
npm test # ORM, business-flow and sync testsSet MIZAN_SMTP_HOST, MIZAN_SMTP_PORT (587), MIZAN_SMTP_USER, MIZAN_SMTP_PASS, MIZAN_SMTP_FROM
(MIZAN_SMTP_SECURE=1 for port 465). Then Send by Email on quotations, RFQs and invoices and Send on
email campaigns deliver real messages (STARTTLS when offered). Without SMTP these actions are simulated.
Each integration turns on when its environment variables are set; without them the buttons fall back to a local action
(simulated send, or a wa.me / tel: link).
| Integration | Environment | Used by |
|---|---|---|
AI (Claude, claude-opus-5-5) |
ANTHROPIC_API_KEY (or another Anthropic credential) |
AI Draft in every chatter; Digitize Document on draft vendor bills (reads an uploaded PDF/image into vendor, reference, dates and lines) |
| WhatsApp Cloud API | MIZAN_WHATSAPP_TOKEN, MIZAN_WHATSAPP_PHONE_ID |
WhatsApp button on contacts and quotations |
| SMS (Twilio) | MIZAN_TWILIO_SID, MIZAN_TWILIO_TOKEN, MIZAN_TWILIO_FROM |
SMS Marketing campaigns |
| Carrier rate APIs (DHL, FedEx, Aramex, …) | MIZAN_SHIPPING_TOKEN + Rate API URL on the delivery method |
Add Shipping on quotations |
| Marketplaces (Amazon, Noon, Shopee, TikTok, Jumia, …) | Orders feed URL on the connector, MIZAN_MARKETPLACE_TOKEN |
Sync Orders (idempotent, SKU matching) |
| IoT devices | per-device token from Generate Token | POST /api/iot/ingest with Authorization: Bearer iot_… |
Outbound URLs configured in records must be public https endpoints (private network addresses are refused).
docker build -t mizan .
docker run -p 8069:8069 -v mizan-data:/data -e MIZAN_ADMIN_PASSWORD=change-me mizanCreate a key in Settings → API Keys, then:
curl -H "Authorization: Bearer mzn_..." http://localhost:8069/api/v1/models
curl -H "Authorization: Bearer mzn_..." "http://localhost:8069/api/v1/crm.lead?q=desk&limit=20"
curl -H "Authorization: Bearer mzn_..." -H "Content-Type: application/json" -X POST -d '{"name":"New lead"}' http://localhost:8069/api/v1/crm.leadGET/POST /api/v1/<model>, GET/PATCH/DELETE /api/v1/<model>/<id> (search with q, paging with limit/offset).
Writes go through the same validation as the web client.
src/models/— model registry (fields, filters, group-bys, view definitions, buttons) and app menus. The UI is generated from it: a new app is mostly a new model entry.src/orm.js— pure, immutable ORM (create/write/unlink/search, computed fields, tracking messages, grouping).src/sync.js— record-level diff/apply, so concurrent edits to different records merge on the server; the server validates and strips every incoming record.server/index.js— Node 24 built-ins only (node:http,node:sqlite,node:crypto): scrypt passwords, HttpOnly session cookies, CSRF header check, login rate limiting, static hosting.src/views/— generic Kanban, List, Graph, Pivot, Calendar, Form, plus Dashboard and Settings pages.