Skip to content
Bread Basket

Bread Basket

Bread Basket logo

Bread Basket

The local-first bakery operating system. A touch kiosk POS that keeps selling offline, an Expo customer app, and a BIR-aware REST backend — one pnpm monorepo, three apps, four shared packages.

TypeScript React 19 Expo Express PostgreSQL pnpm Docker

Demo (kiosk web): coming soon · Demo (mobile apps): coming soon · Live demo: 👇

🧑‍🍳 Kiosk — self-service ordering 📱 Customer mobile app
Kiosk demo Mobile demo

Status: working prototype, ~70% complete · payment & monetization workflow in active development


What is Bread Basket?

Bread Basket is a local-first bakery operating system for small Philippine bakeries that still run on paper — handwritten orders, guessed inventory, and a tax-compliance headache at the end of every month. A touch kiosk POS takes orders even when the internet doesn't work, a customer mobile app mirrors the catalog, and a BIR-aware backend ties it all together. It is designed around three hard constraints of real bakeries:

  1. Unreliable internet — the kiosk writes every order on-device first, then syncs; a dead router never stops a sale.
  2. BIR compliance — terminals are registered, locked, and audit-logged (non-resettable serials, daily transaction summaries, audit trails) per Philippine Bureau of Internal Revenue requirements.
  3. Non-technical staff — a touch-first UI with an idle attract screen, upsell prompts, and a full-screen payment flow that needs zero training.

Core Features

  • ** Touch-Screen Ordering** — an idle attract screen and clear categories make self-service ordering feel natural; upsell prompts nudge add-ons before checkout.
  • ** Payments** — GCash, Maya, card, and cash in a full-screen payment flow — the sale is committed locally before the network is even consulted.
  • ** Local-First POS** — every order lands in IndexedDB on-device first; a background sync reconciles catalog and orders with last-write-wins conflict resolution.
  • ** Inventory & Production** — restock levels, production batches, and low-stock alerts keep the back office informed.
  • ** BIR-Ready Compliance** — non-resettable terminal serials, per-terminal Z-reads, and an immutable audit trail.

Also on board: a customer mobile app (Expo / React Native) for browsing, carts, and order status — plus a login-gated admin suite inside the kiosk for products, prices, promotions, and inventory.

App Workflow

  1. Browse — customers browse products, modifiers, and promotions on the touch kiosk; the mobile app mirrors the same catalog.
  2. Order & pay — the order is composed and paid for via GCash, Maya, card, or cash.
  3. Commit locally — the order and its items are written to on-device IndexedDB immediately, so the sale is durable even with no internet.
  4. Sync when online — a background service pulls the latest catalog and pushes orders with last-write-wins on timestamps.
  5. Manage with the admin suite — staff log in to handle products, prices, inventory, promotions, and terminal compliance.

Tech Stack & Why

Layer Tech
Kiosk React 19 · Vite 8 · React Compiler · Tailwind CSS · Dexie (IndexedDB) · Workbox
Mobile Expo 56 · React Native · expo-router · expo-sqlite · Zustand · TanStack Query
API Node 20 · Express 5 · pg · multer · lowdb
Database PostgreSQL 16 · Redis 7
Infra Docker Compose · nginx (immutable asset serving) · pnpm workspaces

Why this stack: pnpm workspaces keep kiosk, mobile, and API in one codebase with shared packages; Dexie and expo-sqlite make offline-first the default rather than a fallback; PostgreSQL's native enums, triggers, and FK integrity are load-bearing for the sync design; Express's generic CRUD factory turns one table into six endpoints in one auditable place; and a dedicated nginx layer keeps heavy image payloads off the API process.

Repository Layout

bread-basket/
├── apps/
│   ├── kiosk/    # React 19 + Vite PWA — touch POS + admin suite (IndexedDB local-first)
│   ├── api/      # Express 5 REST API — generic CRUD + SQL gateway + uploads
│   └── mobile/   # Expo 56 / RN — customer app (expo-sqlite mirror, Zustand cart)
├── packages/     # @bread-basket/types · assets · colors · payment-assets
├── nginx/        # static asset server config (product images)
├── public/       # uploaded product images served at :5000/assets
└── docker-compose.yaml  # Postgres 16 · Adminer · Redis · nginx

About the Author

Arnold Haban — full-stack engineer who enjoys delivering application products end-to-end, from React Native pixels to Dockerized PostgreSQL.

🔗 LinkedIn · Portfolio · GitLab · GitHub


Private — © Arnold Haban. All rights reserved.

Bread Basket — modernizing bakery operations, one loaf at a time. 🍞🥖🍰