Front of house, kitchen, delivery, and however your customers already order — one system, running on your own hardware. No cloud account, no per-order fee, no platform standing between you and them.
Quick start · Screenshots · Features · How it works · Status · Docs · Roadmap
Vulos — rooted in vula, the Zulu and Xhosa word for open.
A complete restaurant system: take the order, cook it, serve it, deliver it, and know what it cost you. A Go API and a React app running against your own Postgres — on a laptop in the back office, a machine in the cupboard, or a VM you rent.
What makes it different is who it belongs to. Delivery platforms take 15–30% of every order and own the customer relationship. Cloud POS vendors charge per terminal per month and hold your data hostage to a subscription. BeepBite takes nothing and holds nothing, because there is no BeepBite service — there is only the copy you run.
Ordering is meant to be channel-agnostic: customers order from wherever they already are, not wherever BeepBite decided to build first. Today that means WhatsApp chat (built, using your own Meta credentials) and QR-at-table or web ordering (built). Discord, Slack, and email — including over DMTAP — the mail profile of the KOTVA substrate, and the option with no Meta or Google in the middle, though that one is experimental rather than scheduled — are the intended next adapters, not yet built. See Status for exactly which is which.
Note
Status: pre-1.0 and under active rebuild. The POS, kitchen, inventory and ordering surfaces are substantially built; several architectural changes are in flight. Read Status for an honest per-area breakdown before deploying this anywhere real.
Every shot above is a real seeded tenant ("The Copper Table"), captured from the actual running app by npm run screenshots — nothing is mocked up. Light and dark variants of every surface, and a note on what didn't make the cut and why, are in docs/screenshots.md.
| Front of house | Kitchen & stock |
|---|---|
| Touch POS — tabs, splits, voids, comps, manager approval | Kitchen display with per-station routing and expo |
| Floor plan and table management | Recipes, costing, and the 86 list |
| Customer-facing display | Suppliers, purchase orders, goods receipts |
| Reservations and waitlist | Invoice matching and waste tracking |
| Gift cards, store credit, house accounts | Stock counts and reorder suggestions |
| Money & people | Ordering & delivery |
|---|---|
| Cash drawer sessions and reconciliation | WhatsApp ordering, and QR-at-table / web ordering |
| Tenders — cash, card, transfer, voucher | Delivery zones, driver app, live tracking |
| Promotions, coupons, loyalty | Pickup slots and order status |
| Invoicing and house-account billing | Public customer tracking page |
| Time clock, payroll, tip pools | Discord, Slack, email/DMTAP ordering — planned, not built |
Infrastructure you can trust
- Your database, your building. Postgres you control. Nothing phones home, and a fresh install makes no outbound network calls at all.
- No payment facilitator. BeepBite records tenders; it never touches your money. "Card" means your own card machine on your own counter. No PCI scope, no settlement delay, no cut of your revenue.
- Row-level security, with tenant scoping enforced server-side from the authenticated identity — never from a filter the client supplies.
- Audit log and idempotency keys throughout, so a retried request can't double-charge.
- Every integration is optional. WhatsApp, maps and AI are each off unless you supply your own credentials.
- Not a marketplace. It will not bring you customers. It stops a marketplace from owning the ones you already have.
- Not a payment processor. It records what was tendered. Bring your own card machine and your own bank.
- Not a hosted service. No signup, no dashboard we operate, nobody to call. You run it, you back it up, you own the consequences.
- Not finished. See Status.
# 1. Database
createdb beepbite
# 2. Configure — set DATABASE_URL and JWT_SECRET
cp .env.example .env
# 3. Migrate
cd backend && go run ./cmd/migrate --env=local --up
# 4. API
go run ./cmd/server --env=local
# 5. App
cd .. && npm install && npm run dev # http://localhost:5173Want something to look at first?
cd backend && go run ./cmd/seedcopper --env=local --clean # full demo restaurant, ~1500 orders, live KDS tickets
# or: go run ./cmd/seeddemo --email owner@example.com # lighter seed onto an existing orgseedcopper is also what generates every screenshot in this README — see
npm run screenshots and docs/screenshots.md.
flowchart LR
subgraph Customer
W["WhatsApp"]
Q["QR at table / web"]
T["Tracking page"]
end
subgraph "Your hardware"
API["Go API<br/><i>chi · pgx</i>"]
DB[("Postgres")]
UI["POS · KDS · Floor<br/><i>React</i>"]
end
D["Driver app"]
W --> API
Q --> API
UI --> API
API --> DB
API --> D
API --> T
Orders arrive from WhatsApp, a table QR code / web storefront, or the till, and land in one order stream. They route to the right kitchen station and, if they're going out, to a driver — with a tracking link for the customer. Live updates are server-sent events, so there is no polling and no message broker to operate.
| Variable | Default | Description |
|---|---|---|
DATABASE_URL |
— | Postgres connection string. Required. |
JWT_SECRET |
— | Signing key for access tokens. Required. |
PORT |
8080 |
API listen port |
WHATSAPP_TOKEN |
— | Meta Cloud API token. WhatsApp ordering stays off without it. |
WHATSAPP_PHONE_ID |
— | Meta phone number ID |
MAPBOX_TOKEN |
— | Delivery-zone geocoding. Optional. |
See docs/setup.md for the full list.
An honest per-area account, because a feature that silently does nothing is worse than one that says it isn't built:
| Area | State |
|---|---|
| POS, KDS, floor plan, orders | Built — substantially complete, covered by integration and e2e tests |
| Inventory, purchasing, recipes | Built |
| Gift cards, loyalty, house accounts | Built |
| WhatsApp ordering | Built — direct Meta Cloud API integration, needs your own credentials |
| QR-at-table / web ordering | Built |
| Discord, Slack, email ordering | Not built. No channel-adapter abstraction exists yet — WhatsApp and web ordering are each their own direct integration, not plugins behind a common interface. Channel-agnostic is the intent; today it is two channels, not an open architecture. |
| Ordering / replication over DMTAP & KOTVA | Experimental. A research direction, not a scheduled feature: no KOTVA code is in this tree, none is required to run anything, and each stage is gated behind named preconditions in ROADMAP.md. It may not land. |
| Delivery zones, driver, tracking | Built, but less exercised than the POS. The customer tracking page (/track/:token) has a real gap: the backend returns a flat JSON shape and the frontend expects a nested one, so the order-progress stepper works but the live map and ETA never render — a genuine bug, found while building this README's screenshot tooling, not yet fixed. |
| Payments | Tender recording only, by design. Card processing was deliberately removed |
| Currency & locale neutrality | Built. Currency, tax convention, timezone, locale and dial code all resolve per location from configuration; no hardcoded ZAR/South-Africa defaults remain in application logic |
| Single binary + SQLite | Planned, not done. Postgres is required today |
| Offline-first sync between sites | Not implemented. Some client-side scaffolding exists (src/offline/) but nothing in the app uses it yet |
| Multi-branch sync | Designed, not built. Each branch would run its own copy and stay the single writer for its own orders, drawer and shifts, with the menu and stock ledger replicating between them over a hybrid-logical-clock oplog — manual peer enrolment, and a shared folder or USB stick as a valid transport. Today two instances do not talk to each other. |
| A BeepBite cloud | Does not exist, deliberately. No hosted tier, no account, nothing to sign up for. If you want the till reachable from outside the shop, that is a second machine you deploy — a VPS, or a reachability broker such as Ephor that your box dials out to. Your node either way. |
| Vulos OS integration | Optional, never required. BeepBite runs standalone against your own Postgres; the OS is the long-term answer to sharing one menu and one set of books across branches. A hard runtime dependency on the OS, its control plane or KOTVA is forbidden. |
| Runs on | Linux and macOS, x86-64 and ARM — four release binaries. Windows is not built. |
| Screenshots | Real, captured from a live seeded instance — see Screenshots and docs/screenshots.md |
npm run dev # frontend on :5173
npm run build # production bundle
npm run test:unit # vitest
npm run test:e2e # playwright
npm run screenshots # regenerate docs/screenshots/ against a real seeded instance
cd backend && go test ./...
cd backend && go run ./cmd/tests # integration + pentest suites| Doc | |
|---|---|
| Setup | Install, configure, deploy |
| User guide | Running a service day to day |
| Features | What each surface does |
| API | HTTP contract |
| Development | Working on the code |
| Screenshots | How the gallery is generated, and what's excluded and why |
| Troubleshooting | When it misbehaves |
| Roadmap | Gap analysis and what's next |
Issues and pull requests welcome. Read ROADMAP.md first — some gaps are deliberate design choices and some are simply unbuilt, and the difference matters.
MIT OR Apache-2.0 — © VulOS. BeepBite is a VulOS project; source and issues at github.com/vul-os/beepbite.
![]()
vulos — open by design





