Current is a self-hosted RSS feed reader backend that implements the Fever API protocol. Built with Rust and compiled to WebAssembly, it runs on Cloudflare Workers with D1 as the database and KV as the cache layer.
Use it as the server-side sync engine for any Fever-compatible RSS client — Reeder, fluent-reader and more.
Important
Do not click the button above before completing these steps, otherwise deployment will fail:
- Fork this repository to your GitHub account
- Create a D1 database — via Cloudflare Dashboard or run
npx wrangler d1 create current-db - Create a KV namespace — run
npx wrangler kv:namespace create current-cache - Paste the generated database_id and KV id into the corresponding fields in
wrangler.jsonc - Then click the button above and select your fork to deploy
After deployment, you still need to initialize the database schema and set secrets — see the Deployment section below for details.
- Features
- Architecture
- Prerequisites
- Deployment
- Configuration
- Usage — Connecting RSS Clients
- API Reference
- Tech Stack
- License
- Fever API v3 — full read/sync protocol implementation: groups, feeds, items, read/unread/saved state
- Feed format support — parses RSS 2.0, Atom, and JSON Feed subscriptions via
feed-rs - Concurrent feed fetching — fetch multiple feeds in parallel with configurable concurrency
- Cron-based auto-sync — periodic feed refreshing via Workers Cron Triggers (default: every hour)
- Startup fetch — triggers an initial full sync on the first HTTP request after deployment
- KV caching — D1 query results are cached in KV for fast API responses; cache is selectively invalidated on mutations
- Deduplication — database-level unique indexes prevent duplicate items by
(feed_id, url)and(feed_id, title) - CORS support — cross-origin requests enabled for web-based RSS clients
- Observability — structured
[INFO]/[WARN]/[ERROR]logging for Cloudflare dashboard inspection - Secure auth — constant-time string comparison for API key validation
┌──────────────────────────┐
│ Fever-compatible Client │ (Reeder, Fiery Feeds, etc.)
│ GET/POST ?api&... │
└─────────┬────────────────┘
│ Fever API protocol
▼
┌──────────────────────────┐
│ Cloudflare Worker │ Rust → WebAssembly (worker-build)
│ ┌──────────────────┐ │
│ │ fever.rs │ │ API request routing & response
│ │ auth.rs │ │ md5(email:password) authentication
│ │ fetcher.rs │ │ Concurrent RSS feed fetching & parsing
│ │ db.rs │ │ D1 database access layer
│ │ cache.rs │ │ KV-backed cache-aside layer
│ │ var.rs │ │ Runtime configuration from env vars
│ │ models.rs │ │ Data models & Fever API response types
│ └──────────────────┘ │
└──────────────────────────┘
│
┌────┴────┐
▼ ▼
┌─────────┐ ┌──────┐
│ D1 DB │ │ KV │
│ SQLite │ │Cache │
└─────────┘ └──────┘
| Layer | Technology | Purpose |
|---|---|---|
| Database | Cloudflare D1 (SQLite) | Feeds, groups, items, read state |
| Cache | Cloudflare KV | Cached D1 queries for fast reads (feeds, groups, unread/saved IDs, item counts) |
| Cache strategy | Cache-aside | Read: KV → miss → D1 → backfill KV. Write: invalidate affected KV keys |
- Node.js 18+
- Rust (latest stable)
- wrangler CLI (
npm install -g wrangler) - A Cloudflare account with:
- Workers subscription (free plan works)
- D1 database quota
- KV namespace quota
git clone https://github.com/jyfzh/current
cd currentNote: The project uses
worker-build(viacargo) to compile Rust to WebAssembly. Thewrangler.jsoncbuild command handles this automatically.
wrangler d1 create current-dbThe command outputs a database ID. Copy it into wrangler.jsonc:
wrangler kv:namespace create current-cacheCopy the output ID into wrangler.jsonc:
"kv_namespaces": [
{
"binding": "CACHE",
"id": "your-kv-id-here"
}
]wrangler d1 execute current-db --remote --file=migrations/0001_init.sqlwrangler secret put CURRENT_FEVER_PASSWORD
wrangler secret put CURRENT_FEVER_EMAILwrangler deployAfter deployment, your API endpoint will be:
https://current.<your-subdomain>.workers.dev/?api
curl "https://current.<your-subdomain>.workers.dev/?api&api_key=$(echo -n '<email>:<password>' | md5sum | cut -d' ' -f1)"Expected response:
{"api_version":3,"auth":1}All configuration is through Worker environment variables (set via wrangler.jsonc vars or wrangler secret put):
| Variable | Description |
|---|---|
CURRENT_FEVER_PASSWORD |
Fever API password (used with email for auth) |
CURRENT_FEVER_EMAIL |
Fever API email (default: admin. Used with password for auth) |
| Variable | Default | Description |
|---|---|---|
CURRENT_MAX_CONCURRENCY |
5 |
Max concurrent feed fetches (0 = unlimited) |
CURRENT_FEED_STALE_SECONDS |
3600 |
Min age (seconds) before a feed is eligible for re-fetch |
CURRENT_STARTUP_FETCH |
true |
Trigger initial full feed fetch on first HTTP request after deploy |
CURRENT_CACHE_TTL_AGGREGATE |
600 |
KV cache TTL for aggregate queries (total items, group counts) |
CURRENT_CACHE_TTL_STRUCTURAL |
600 |
KV cache TTL for structural data (feeds, groups, unread/saved IDs) |
CURRENT_FEVER_ITEMS_PER_PAGE |
50 |
Number of items per API response page |
Current speaks the Fever API protocol, so any RSS reader that supports Fever sync can connect to it.
- Open your RSS client's account/sync settings
- Select Fever as the sync type
- Enter:
- URL:
https://current.<your-subdomain>.workers.dev/?api - Email: whatever you set for
CURRENT_FEVER_EMAIL(default:admin) - Password: whatever you set for
CURRENT_FEVER_PASSWORD
- URL:
Currently feeds must be added directly to the D1 database (the Fever API write endpoints for feed/group management are not yet implemented).
You can execute SQL against the D1 database using either of the following methods:
- Log in to the Cloudflare Dashboard
- Navigate to Workers & Pages → D1 → select your database
- Use the Explorer Data tab to run SQL queries interactively, or view, add, and delete rows directly through the UI
# Execute SQL directly
wrangler d1 execute current-db --remote --command="INSERT INTO groups (title) VALUES ('Tech');"
# Execute from a SQL file
wrangler d1 execute current-db --remote --file=add_feeds.sqlExample SQL to add feeds:
-- Add a group
INSERT INTO groups (title) VALUES ('Tech');
-- Add a feed
INSERT INTO feeds (title, url, site_url, group_id)
VALUES ('Example Blog', 'https://example.com/rss', 'https://example.com', 1);The next cron run (or first API request if CURRENT_STARTUP_FETCH is enabled) will fetch and populate items.
From the RSS client, select the feed/group and use the "Mark as Read" action. The client sends the appropriate mark=feed&as=read&id=N&before=TS command, and Current handles it.
The Fever API protocol is fully documented in docs/fever-api.md and the OpenAPI spec at docs/fever-openapi.yaml.
| Layer | Technology |
|---|---|
| Language | Rust (edition 2024) |
| Runtime | Cloudflare Workers (WebAssembly via worker-build) |
| Database | Cloudflare D1 (SQLite-compatible) |
| Cache | Cloudflare KV |
| Feed Parsing | feed-rs (RSS 2.0, Atom, JSON Feed) |
| Auth | MD5 (Fever protocol) |
| Scheduling | Workers Cron Triggers |
- AI-powered feed clustering — Automatically group feeds into topic clusters (e.g., Tech, Science, Politics) using Cloudflare Workers AI embeddings and Vectorize, so new subscriptions are categorized without manual setup.
- Personalized recommendations — Surface trending or relevant items based on your reading history, powered by on-device-style inference via Workers AI.
- Smart summaries & highlights — Generate concise summaries for unread items using an LLM running on Workers AI, stored back to D1 for quick recall.
- Hot topics detection — Analyze item titles and content across all feeds to identify emerging topics and spikes in coverage, delivered as a new API endpoint.
These features will leverage Cloudflare's global AI inference network, keeping data processing close to the database and minimizing latency.
MIT © 2026 jyfzh