Monorepo for WooCommerce POS
React Native + Expo cross-platform applications for taking WooCommerce orders at the Point of Sale.
About — Structure — Architecture — Development — Workflows
The goal of this project is a free and extensible Point of Sale application, with a payment-method-agnostic design (including first-class support for cryptocurrency).
This monorepo contains all the code for the client applications — a single React Native + Expo codebase that ships to web, desktop and mobile. It currently uses WooCommerce as its backend, so to run it against a store you also need the WooCommerce POS plugin for WordPress, which provides the REST API and authentication.
| Target | Built from | Distributed as |
|---|---|---|
| 🌐 Web | apps/main |
wcpos.expo.app (EAS Hosting) |
| 🖥 Desktop | apps/electron (wraps the apps/main web build) |
Windows / macOS / Linux installers |
| 📱 Mobile | apps/main |
iOS & Android (EAS Build) |
| 🧩 In-WordPress | apps/web |
JS bundle on jsDelivr, loaded by the WP plugin |
The repo is a pnpm workspace orchestrated with Turborepo. Code is split into apps/* (deployable applications) and packages/* (shared libraries).
| Path | Package | Description |
|---|---|---|
apps/main |
@wcpos/main |
The Expo app (expo-router) — the source of truth for web, iOS and Android. |
apps/electron |
@wcpos/app-electron |
Electron desktop wrapper for Windows/macOS/Linux. (git submodule) |
apps/web |
@wcpos/web-bundle |
Builds the web JS bundle shipped via jsDelivr for the WordPress plugin. (git submodule) |
apps/template-studio |
@wcpos/template-studio |
A Vite harness for previewing and print-testing receipt templates. |
| Path | Package | Description |
|---|---|---|
packages/core |
@wcpos/core |
Core POS screens and navigation. |
packages/components |
@wcpos/components |
Shared UI components (Tailwind/uniwind, FontAwesome icons). |
packages/database |
@wcpos/database |
Local-first data layer built on RxDB. |
packages/query |
@wcpos/query |
Querying and WooCommerce sync/replication. |
packages/hooks |
@wcpos/hooks |
Shared React hooks. |
packages/utils |
@wcpos/utils |
Shared utilities. |
packages/printer |
@wcpos/printer |
ESC/POS printer encoding and transport. |
packages/receipt-renderer |
@wcpos/receipt-renderer |
Receipt rendering (HTML + thermal templates). |
packages/virtual-printer |
@wcpos/virtual-printer |
Dev tool: a virtual TCP printer for testing. |
packages/eslint |
@wcpos/eslint-config |
Shared ESLint configuration. |
Submodules:
apps/electron,apps/weband.wiki(the WCPOS wiki).pnpm installinitialises them automatically; refresh them withpnpm submodules:update.
One Expo codebase renders the POS everywhere; the difference between platforms is mostly the data layer, which adapts RxDB to each platform's best storage engine:
| Platform | Storage engine |
|---|---|
| Web | OPFS (Origin Private File System), in a worker — migrating from IndexedDB |
| Desktop (Electron) | Filesystem-node storage in the main process, reached over IPC; legacy SQLite-over-IPC is used for migrations |
| Native (iOS/Android) | SQLite via expo-sqlite |
Querying and replication against the WooCommerce REST API live in @wcpos/query; printing (ESC/POS encoding, transports and receipt rendering) lives in @wcpos/printer and @wcpos/receipt-renderer. See the Client Architecture wiki page for a deeper dive.
Prerequisites
- Node.js 22+ and pnpm (pinned via
packageManager) - For native builds: the Expo / React Native toolchain (Xcode, Android Studio)
- Access tokens for the licensed dependencies RxDB Premium and Uniwind Pro (CI injects these as secrets)
Setup
git clone --recursive https://github.com/wcpos/monorepo.git
cd monorepo
pnpm install # also initialises submodulesRun the app
pnpm start # clean Metro dev server for apps/main (web + native clients)
pnpm dev:electron # the desktop app (Expo dev server + Electron)
# native dev clients
pnpm --filter @wcpos/main ios
pnpm --filter @wcpos/main androidUseful scripts
| Script | Description |
|---|---|
pnpm start |
Clean-state Metro launcher for apps/main |
pnpm dev / pnpm dev:main / pnpm dev:electron |
Turborepo dev tasks |
pnpm build / pnpm build:main |
Production builds |
pnpm test |
Run package + app unit tests |
pnpm lint / pnpm lint:fix |
Lint via Turborepo |
pnpm typecheck |
Type-check all workspaces |
pnpm extract:translations |
Extract source strings for translation |
pnpm submodules:update |
Pull latest .wiki / apps/electron / apps/web |
CI/CD lives in .github/workflows/:
deploy.yml— exports theapps/mainweb build and deploys it to EAS Hosting (wcpos.expo.app); PRs get preview deployments. Runs sharded Playwright E2E against the deployment.build.yml— EAS Build for native iOS/Android apps (manually dispatched), with optional store submission.test.yml— lint, type-check and unit tests with a coverage ratchet, gating every PR.publish-web-bundle.yml— buildsapps/weband publishes the bundle to theweb-bundlerepo for jsDelivr.bump-submodules.yml— daily auto-bump of the submodules.
- Architecture, product and operations docs live in the WCPOS wiki (vendored at
.wiki/). - User-facing documentation is at docs.wcpos.com.
- 🌐 Website — wcpos.com
- 🖥 Desktop client — github.com/wcpos/electron
- 🔌 WordPress plugin — github.com/wcpos/woocommerce-pos
- 💬 Discord — wcpos.com/discord
License metadata is declared in individual package manifests. Packages that currently declare a license use MIT; this repo does not yet include a root LICENSE file, and some workspace manifests omit a license field.