The business back office for agencies and freelancers, in one app you can own outright.
CRM, deal pipeline, projects, time tracking, invoicing, expenses and reports.
Self-host it for free, with no seat limits and no per-user pricing.
Try the live demo →
No sign-up. Resets every hour.
![]() |
![]() |
![]() |
| Contacts and pipeline | Projects | Invoicing |
| Everything in one place | A contact becomes a deal, the deal becomes a project, the project's hours become an invoice. No Zapier glue between five subscriptions. |
| You own it | Self-hosted on PocketBase, a single binary. Your data sits in one folder on your server. |
| Leave any time | Full JSON backup and restore, CSV exports everywhere. Move between the hosted cloud and your own server in either direction. |
| Gets paid | Recurring retainer invoices, client share links with PDF download, and unbilled time turned into invoice lines in one click. |
| Fast to live in | Command palette, keyboard shortcuts, two themes (Classic and BareStack) with dark mode, real-time sync across tabs and devices, installable as an app. |
curl -sSL https://raw.githubusercontent.com/anirudhprashant/barestack-app/main/install.sh | bashOr if you already have the repo:
./install.shBy default this is a fully self-hosted install: the app talks to a PocketBase
instance running on your own machine. Your data lives in ./pb_data and never
touches the BareStack cloud.
This will:
- Install npm dependencies
- Download PocketBase (the pinned, tested version)
- Apply the database schema from
pb_migrations/(collections + owner-only access rules) - Create a PocketBase admin with a randomly generated password (printed once)
- Build the frontend pointed at your local PocketBase
- Create a
start.shscript
Then run ./start.sh to launch.
Want to use the hosted BareStack cloud instead of your own backend? Run
./install.sh --cloud. This builds the frontend againstapi.barestack.organd skips the local PocketBase setup.
Manual setup
npm installDownload the pinned version (the installer uses the same one; newer majors change the admin API and may not match these migrations):
PB_VERSION=0.36.2
# Linux amd64 (use linux_arm64 / darwin_arm64 / darwin_amd64 as appropriate):
curl -fL "https://github.com/pocketbase/pocketbase/releases/download/v${PB_VERSION}/pocketbase_${PB_VERSION}_linux_amd64.zip" -o pocketbase.zip
unzip -o pocketbase.zip pocketbase
chmod +x pocketbaseThe collections and their owner-only access rules are version-controlled in
pb_migrations/. Apply them; no manual collection creation needed:
./pocketbase migrate up --dir ./pb_data --migrationsDir ./pb_migrationsThen create an admin (superuser):
./pocketbase superuser upsert admin@barestack.local "$(openssl rand -base64 18)" --dir ./pb_dataCreate a .env file pointing at your local PocketBase:
VITE_POCKETBASE_URL=http://127.0.0.1:8092./pocketbase serve --dir ./pb_data --migrationsDir ./pb_migrations --hooksDir ./pb_hooks --http="0.0.0.0:8092" &
npm run build
PORT=8080 node serve.cjsserve.cjs is a small dependency-free static server with security headers,
gzip, long-lived caching for fingerprinted assets and SPA routing. Put it (and
PocketBase) behind a TLS-terminating reverse proxy for anything public.
CRM
- Contacts with tags, inline editing, search, tag filters, sort, CSV export and bulk actions
- Contact profiles with deals, projects, invoices, lifetime value and editable notes
- Deal pipeline (Lead → Qualified → Proposal → Won/Lost) with drag and drop, titles, values, expected close dates, win rate and open pipeline value
- CSV / Excel import with duplicate handling (skip, update or create, per row or all at once) and one-click undo
Projects & time
- Projects with budget, estimated hours, hourly rate, due date and live progress (hours, budget used, tasks)
- Task boards with priorities, due dates, overdue flags, edit and delete
- Start/stop timer that survives reloads and syncs across tabs, plus manual entries (
1.5,1:30or90m) - Weekly hours chart with week navigation, billable vs non-billable, CSV export
Money
- Invoices with multiple line items, tax, notes, custom numbering (
INV-2026-001) and automatic overdue detection - Recurring invoices for retainers (weekly, monthly, quarterly, yearly), generated on the server as drafts
- Client share links: a private page where your client views the invoice and downloads the PDF, no account needed. Updates when you edit; turn it off any time
- Bill unbilled time in one click: billable hours become invoice lines at the project rate, and the entries are marked as billed
- Branded PDF invoices with your business details, payment instructions and currency; preview, download, ZIP of many, or email to the client
- Expenses with categories, projects, receipt links, period filters and CSV export
- Reports: revenue vs expenses by month, profit and margin, top clients, hours by project, expenses by category
Workspace
- Command palette (Ctrl/⌘ + K) to jump to any contact, project or invoice, or start a timer
- Keyboard shortcuts (
g iinvoices,n cnew contact,?for the full list) - Themes: Classic or BareStack (the barestack.org design system), each with light, dark or follow-the-system
- Real-time sync: changes appear instantly in every open tab and device
- Installable as an app (PWA) on desktop and phones
- One-click sample data to explore, and one-click removal
- Notifications for overdue invoices, tasks due and deals past their close date
- Business profile: name, address, tax ID, currency, default tax rate, payment terms and invoice footer
- Getting-started checklist, activity log, responsive on phones
- Your data is portable: CSV export, full JSON backup, and restore into any BareStackOS instance (cloud → self-hosted and back)
- Account settings: name, email change, password change, and full account deletion
Pull, rebuild, and restart PocketBase with --migrationsDir ./pb_migrations
(the bundled start.sh already does). New migrations apply automatically and
only add things; existing data is untouched.
git pull
npm ci
VITE_POCKETBASE_URL=<your PocketBase URL> npm run build
./start.shNew accounts must verify their email before they can see any data. When
PocketBase has no SMTP configured (the default for a fresh self-hosted
install), there is no way to deliver that email, so new sign-ups are verified
automatically (pb_hooks/auth.pb.js). As soon as you enable SMTP in the
PocketBase dashboard (/_/ → Settings → Mail settings), normal verification
emails are used. Set BARESTACK_REQUIRE_EMAIL_VERIFICATION=true in
PocketBase's environment to always require verification.
npm run dev # Vite dev server (point VITE_POCKETBASE_URL at a PocketBase)
npm test # unit tests (vitest)
npm run test:e2e # browser tests: starts a throwaway PocketBase + production build
npm run typecheckThe end-to-end suite (tests/e2e) downloads the pinned PocketBase into
.e2e/, applies this repo's migrations and hooks to a fresh database, and
drives the real production build with Playwright. CI runs it on every pull
request.
- Frontend: React 18, TypeScript (strict), Vite 7, Tailwind CSS 4
- Backend: PocketBase (self-hosted, open-source)
- Fonts: Instrument Serif + Inter + Plus Jakarta Sans (Google Fonts)
- PDF: jsPDF with AutoTable
- Filter Injection Prevention: All user IDs are sanitized with regex validation
- Input Validation: Required fields enforced on all forms
- Security Headers: CSP, X-Frame-Options, X-Content-Type-Options, Referrer-Policy
- Auth: JWT-based via PocketBase authStore
- Data Isolation: Server-side PocketBase rules: users can only read and write their own records, and can't move a record into someone else's account
- Safe exports: CSV exports neutralise spreadsheet formulas (CSV injection)
- Secrets: Environment-based, never committed to git
├── components/ # React components (forms, command palette, UI kit)
├── pages/ # Page components
├── pb_migrations/ # PocketBase schema + access rules (applied automatically)
├── pb_hooks/ # Server-side hooks (activity integrity, verification)
├── src/
│ ├── context/ # Toasts, timer
│ ├── lib/ # API, dates, money, invoices, PDF, backup, CSV
│ └── style.css # Tailwind styles
├── vite.config.ts # Vite + security headers
├── index.html # Entry + Google Fonts
├── types.ts # TypeScript types
├── dataStore.tsx # State management
├── install.sh # One-line installer
└── start.sh # Launcher script
AGPL-3.0. Run it, modify it, self-host it, no charge and no seat limits. If you distribute a modified version, or run one as a network service for others, you have to publish your source under the same licence. See LICENSE for the full text.
made by Anirudh Prashant · barestack.org



