What you get
FeedZero is open source under AGPL-3.0-or-later. A self-hosted deployment unlocks every shipped feature. There is no license check, no kill switch, no telemetry. Features still in development stay locked until they ship, and they reach self-hosters the same day they reach hosted users.
- Unlimited feeds. The 25-feed cap on hosted Free does not apply.
- Auto-organize folders and every Personal feature, no subscription required.
- End-to-end encrypted sync on your own server.
- Same UI, same offline support, same OPML and Explore catalog.
What you provide
Self-hosting trades convenience for control. You run the infrastructure. We provide the code and the docs.
- A host that can serve a static SPA plus a few serverless functions. The Vercel free tier is plenty; Cloudflare Pages, Netlify, or a bare Node/Hono server also work.
- Optional: a key/value store if you want sync. Vercel Blob and Upstash KV are tested; the filesystem adapter works for single-server deployments.
- A custom domain you control. The legal Impressum, Privacy, and Terms pages we ship reference our operating entity. Replace those if you intend to operate publicly.
Quick start (Vercel, about 10 minutes)
The path of least resistance. The same setup we run for my.feedzero.app, minus the Stripe gates.
- Fork forcingfx/feedzero to your GitHub account.
- Import the project at vercel.com/new, pointing at your fork.
- Set environment variables in the Vercel project (Production environment):
VITE_SELF_HOSTED=1 # build-time flag: unlocks every shipped feature VITE_PAID_TIER_VISIBLE= # leave unset; hides Subscribe UI LAUNCH_PAID_TIER= # leave unset; disables /api/sync bearer requirement SYNC_STORAGE=filesystem # or "vercel-blob" / "upstash" if you want HA - Deploy. Vercel builds and serves. Open the deployment URL.
- Add your domain in the Vercel project settings if you have one. Otherwise the vercel.app subdomain works.
That's it. The first launch auto-subscribes to the release feed so you know when new versions ship. Otherwise it is indistinguishable from my.feedzero.app, except every Personal feature is on by default.
Configuration reference
Build-time flags (set before npm run build:all)
| Variable | What it does |
|---|---|
VITE_SELF_HOSTED | Set to 1 to bypass tier gates. Every shipped feature is treated as unlocked regardless of stored license tier. This is the flag that distinguishes "self-hosted" from "hosted dev mode". |
VITE_PAID_TIER_VISIBLE | Leave unset for self-hosted. Setting it would show Subscribe buttons and pricing widgets, which is wrong for a self-hosted deployment where there is nothing to subscribe to. |
Runtime flags (set on the server)
| Variable | What it does |
|---|---|
LAUNCH_PAID_TIER | Leave unset. Setting it would cause /api/sync to reject requests without a valid bearer token, which is pointless for self-hosters who have no license server. |
SYNC_STORAGE | Picks the sync-vault adapter: filesystem (default, fine for a single instance), vercel-blob (needs BLOB_READ_WRITE_TOKEN), upstash (needs UPSTASH_REDIS_REST_URL and UPSTASH_REDIS_REST_TOKEN), or memory (dev only; vault evaporates on restart). |
GITHUB_FEEDBACK_TOKEN + GITHUB_REPO | Optional. Routes the in-app feedback form to GitHub Issues. Without it, the feedback button stays inactive. |
Building from source (without Vercel)
If you would rather not use Vercel, FeedZero ships a standalone Hono server that serves the SPA and API routes in one process.
git clone https://github.com/forcingfx/feedzero.git
cd feedzero
echo "VITE_SELF_HOSTED=1" >> .env.production
npm install
npm run build:all
npm run serve # binds to PORT (default 3000)
Reverse-proxy that with nginx, Caddy, or your container platform of choice. The Hono server is plain Node and runs anywhere Node runs.
Sync on a self-hosted server
Sync is end-to-end encrypted. Your passphrase derives a vault ID and an AES-GCM key on the client. The server only stores ciphertext. The same architecture that keeps hosted users private from us also means you do not need to trust your own server with plaintext. It just needs to hold opaque bytes.
Pick a sync adapter:
- Filesystem. Vault files under a writable directory. Simplest. Single-instance.
- Vercel Blob. Managed object storage. Works across serverless function instances. Costs scale with vault size.
- Upstash. Redis-compatible KV. Works well for small vaults and high cross-region traffic.
All three are tested in CI. Pick based on your platform; the client does not care which one the server uses.
src/data/feed-catalog.generated.json). It works offline and never calls home. To refresh the snapshot, rebuild from a current main; we update the catalog periodically and ship it with each release.
SYNC_STORAGE=upstash with matching env vars to enable it for your fork's users.
Updating
Pull from upstream, rebuild, redeploy. main on the upstream repo is the channel hosted production tracks. Tagged releases are also published. There is no separate self-hosted channel: same code, same release cadence.
git remote add upstream https://github.com/forcingfx/feedzero.git
git fetch upstream
git merge upstream/main
# resolve any conflicts on your fork
npm install
npm run build:all
# redeploy
License and the honor-system gates
FeedZero is open source under AGPL-3.0-or-later. A few features (auto-organize, sync, smart filters, offline starred) are gated client-side by tier; setting VITE_SELF_HOSTED=1 bypasses those gates. This is honor-system gating. A determined user could strip the gates from a fork. We accept that:
- The AGPL permits it (with section 13's network-use clause: anyone running a modified FeedZero as a public service must offer their users the modified source).
- $5 a month for a managed deployment with automatic updates and no ops is cheaper than the time of forking, maintaining, and hosting for almost everyone.
- The features paid users pay for include the hosted infrastructure. Cross-device sync needs a server they do not have to run.
Self-hosters who run their own server already provide that value to themselves. It would be hostile to gate the code against them.
See ADR 012 for the full design.
Getting help
- Open an issue: github.com/forcingfx/feedzero/issues
- Read the codebase: CLAUDE.md is the developer's tour of the architecture.
- If you ship a public self-hosted instance, replace our legal pages (Impressum, Privacy, Terms) with your own. Operating someone else's service under our entity's name would mislead your users.