The stack
What βWave is built on, what it runs on, and what you need to host it yourself. Every figure below is counted from the repository, not estimated.
Runtime
One language end to end, so there is no context switch between the API, the interface and the scripts that drive them.
| Layer | What |
|---|---|
| Language | TypeScript 5.4, across server, client and tooling |
| Server | Node.js + Express 4, executed directly with tsx — no server build step |
| Interface | React 19 single-page app, bundled with Vite 5 |
| Validation | Zod schemas on the boundaries |
| Scheduling | In-process scheduler (60s tick) and job runner (15s tick) — no external queue, no broker |
Why no build step on the server. The server runs straight off TypeScript. Deploying is git pull and a restart. That is one fewer thing standing between a problem and a fix, which matters more than a few milliseconds of cold start.
Data
SQLite, through libsql, in WAL mode. Seventy-two tables covering clients, content, syndication, discovery, outreach, citations, invoicing, commissions and the model-usage ledger.
Why not Postgres. βWave has to be installable by someone who runs a franchise, not a data centre. SQLite is a single file: no database server to provision, no connection strings to get wrong, and a backup is a file copy. It carries the entire multi-tenant platform on two vCPUs. Postgres would buy concurrency this workload does not need, and cost the thing we are actually selling — that you can run this yourself.
The model layer
Seven providers sit behind a single interface, selectable per tenant:
- Anthropic — Claude, the default for long-form and brand voice
- OpenAI — GPT models and image generation
- DeepSeek and Qwen — high-volume, low-cost classification work
- Ollama — local inference, zero API cost, nothing leaves the machine
- Plus a generic OpenAI-compatible endpoint for anything else
Around them: a per-tenant spend guard that hard-stops at a ceiling rather than silently downgrading you to a cheaper model, a usage ledger that records every call with its true billed cost, and prompt caching on the long system prompts.
Why seven. We sell to people who have been burned by a vendor. If a provider triples its price, degrades its model, or an EU client refuses US-hosted inference, that is one setting — not a migration. The point of owning your marketing engine is that nobody can move your cheese.
What it connects to
| Integration | Purpose |
|---|---|
| MCP server | stdio and HTTP transports, so other AI agents can drive βWave directly |
| Browser extension | Manifest V3. Reads context already rendered on pages you visit; no automated browsing |
| Puppeteer | Headless Chrome for generated PDF reports |
| Astro + Netlify | Static sites βWave builds and publishes for clients |
| SMTP | Newsletters and sequenced outreach, through your own mail server |
| RSS, Search Console | Source ingestion and performance data |
How it is hosted
The reference deployment is deliberately unremarkable, because unremarkable is reproducible.
| Piece | What |
|---|---|
| Machine | 2 vCPU · 4 GB RAM · 40 GB NVMe, Ubuntu 24.04 LTS |
| Process | systemd service, with timers for nightly backup and weekly site archive |
| Web | nginx reverse proxy, Let's Encrypt certificates on auto-renew |
| Backups | Fourteen nightly local snapshots, mirrored off-site; secrets encrypted with GPG AES-256 before they ever leave the box |
That is the whole hosting bill. There is no managed database, no queue service, no object store and no per-seat SaaS underneath it.
Security
- Provider API keys are encrypted at rest with AES-256-GCM; the master key is never stored in the database
- Passwords hashed with scrypt; sessions are HMAC-signed cookies
- The client-scoped
operatorrole is deny-by-default — a new endpoint is inaccessible to operators until it is explicitly allowed, rather than the other way round - Self-hosted with Ollama, no content, client data or prompt ever leaves your machine
To run it yourself
Node.js, git, and a machine. Clone the repository, set a few environment variables, npm install, npm start. Bring your own model keys, or point it at a local Ollama and bring none.
It is genuinely free, under AGPL-3.0 — not a trial, not a seat-limited tier. A commercial licence exists for organisations that need release from the AGPL's source-disclosure obligation; it buys different terms, not different software.
What it does not have
βWave has been built by one person shipping daily against live clients, so the feedback loop has been production rather than continuous integration. There is no automated test suite yet. It is the first thing that changes with a second pair of hands.
We would rather you read that here than find it yourself — the repository is public, so you would.
Questions a page cannot answer: read the source, or book a call.