Riverbucket is an app with two faces:
- River: an organized collection of recent posts from your lovingly curated collection of RSS/Atom/JSON/h-feed feeds.
- Bucket: a list of links from around the web, bookmarked for later reading.
- Subscribe by feed or site URL -- this includes blogs, IndieWeb h-feeds, YouTube channels and playlists, Medium profiles/tags/publications, Mastodon accounts, Reddit listings and GitHub releases/tags/commits. Subscriptions are updated periodically or on demand.
- Browse recent feed items grouped by tag and source.
- Save feed items to the bucket with one click.
- Configure select feeds to automatically save new entries to the bucket.
- Keep river, bucket, feeds, tags, refresh state, and extension-token metadata synchronized across open tabs and devices.
- Import and export feeds via OPML and bookmarks via JSON/HTML.
- Add sites to the river current site and pages to the bucket through the companion webextension.
| River, dark theme | River, light theme |
|---|---|
| Bucket, dark theme | Bucket, light theme |
|---|---|
Riverbucket intentionally does not do any of the following:
- Track or count which feed items you have or haven't read like an email inbox.
- Provide a reader mode or text backup for article content.
- Provide algorithmic ranking or similar content suggestions.
- Use LLMs to summarise articles or provide digests.
Riverbucket is a single-user Cloudflare Workers app protected by a password. The easiest way to run your own instance is to click Deploy to Cloudflare above. Cloudflare will:
- Ask you to choose the
APP_PASSWORDused to sign in. - Create and bind the D1 database, Queue, and Durable Objects.
- Apply the database migrations, build the app, and deploy it with Workers Builds.
The password is stored only as an encrypted Worker secret. Changing it invalidates existing login sessions. After deployment, open the Workers URL shown by Cloudflare and sign in with the password you chose.
To deploy from a local checkout instead, install dependencies and authenticate Wrangler:
npm install
npx wrangler loginCreate the remote D1 database and feed refresh queue:
npx wrangler d1 create riverbucketdb
npx wrangler queues create riverbucket-feed-refreshThe checked-in wrangler.jsonc also provisions the AppSync and RateLimiter Durable Objects when the Worker is deployed.
Copy the D1 database ID from the wrangler d1 create output into wrangler.jsonc as database_id. If you change a resource name, update the matching name in wrangler.jsonc; migration scripts use the DB binding and do not need to change.
Set the password you will use to sign in:
npx wrangler secret put APP_PASSWORDAPP_PASSWORD also supplies domain-separated session-signing key material, so a separate session secret is not required. For an advanced deployment, you can explicitly set SESSION_SECRET; it takes precedence over the derived key.
If you prefer not to configure a plain password secret, Riverbucket retains the pre-hashed authentication format. Generate and store a hash, then configure an explicit session secret:
npm run password:hash -- "YOUR-SUPER-SECURE-PASSWORD-HERE"
npx wrangler secret put APP_PASSWORD_HASH
openssl rand -base64 48
npx wrangler secret put SESSION_SECRETIf both APP_PASSWORD and APP_PASSWORD_HASH exist, APP_PASSWORD is used. Build, apply remote D1 migrations through the DB binding, and deploy:
npm run deployYour instance should then be available at https://riverbucket.YOURNAME.workers.dev. Log in with your password and start reading.
Build browser-specific extension packages:
npm run extension:buildFor Chrome or Chromium, open the extensions page, enable Developer Mode, and load
dist/extension/chrome/ as an unpacked extension. For Firefox, open
about:debugging#/runtime/this-firefox, choose Load Temporary Add-on, and select
dist/extension/firefox/manifest.json.
Configure your Riverbucket app URL and an extension token in the extension options. You can provision extension tokens from Settings on your Riverbucket instance.
The extension can save the current page, save right-clicked links, and discover feeds from the current page.
Use Node.js 24 or newer, then install dependencies:
npm installRun the frontend dev server:
npm run devTypecheck the app and Worker:
npm run typecheckBuild the frontend and typecheck both the app and Worker:
npm run buildApply D1 migrations locally:
npm run db:migrate:localApply D1 migrations remotely:
npm run db:migrate:remoteRun the unit and SQLite integration tests:
npm testFor browser regression checks, install the agent-browser CLI and its Chromium
browser, start Vite with npm run dev -- --port 5174, then run
npm run test:browser. The checks use synthetic data and do not require a deployed
instance. See maintenance and compatibility for upgrade notes.
The default D1 database name is riverbucketdb; migration scripts use its DB binding.
This project was vibe-coded (with love). As its creator, I reserve for myself the special and exclusive privilege of continued vibing. Outside contributors are held to stricter standards.
- You must understand and be able to defend the code you're submitting. A set of high-level matrix calculations cannot take responsibility, and "that's what the AI decided to do" is never a good enough explanation.
- You must make all commits yourself with your own commit messages. No Claude co-authoring: I reserve that right for myself.
Of course, you are also welcome to fork this project and do whatever you want with it, subject to the license. But if you want to contribute upstream, please follow these two rules.
Riverbucket is licensed under the GNU Affero General Public License v3.0. See LICENSE.