LibreRSS is an open-source, self-hostable RSS reader built for focused reading. Subscribe to RSS, Atom, and JSON feeds, organize them into a fast dashboard, and read without algorithmic interference, engagement traps, or platform lock-in. Run it privately for yourself or open it selectively to a team.
| Capability | What it gives you |
|---|---|
| Universal feed support | Subscribe to RSS, Atom, and JSON feeds from across the open web. |
| Category organization | Group sources into a browsing model that stays usable as your feed list grows. |
| Distraction-free reading | Keep focus on the article instead of interface chrome, prompts, and engagement mechanics. |
| Fast dashboard workflows | Add, sort, refresh, and manage feeds from one responsive control surface. |
| Light and dark themes | Choose the reading environment that fits the room, the hour, and your eyes. |
| Self-hosted ownership | Keep feed data, sessions, and deployment choices under your control. |
| Invite-only mode | Disable public signup for personal, private, or small-team use. |
| Streaming refresh | Watch updates arrive in a flow that feels live without feeling frantic. |
- Bun
- PostgreSQL, or a Neon-compatible Postgres connection string
bun installLibreRSS ships with a committed .env full of documented defaults. Put machine-specific settings in .env.local; keep secrets and credentials out of the committed file.
DATABASE_URL="postgres://user:password@host:5432/dbname"
DB_DRIVER="pg" # or "neon"
ALLOW_SIGNUP=false
NODE_ENV="development"
LOG_LEVEL="warn"DATABASE_URL: your Postgres connection string.DB_DRIVER:pgfor pooled TCP connections, orneonfor fetch-backed Neon mode.ALLOW_SIGNUP: set totruefor public registration; leavefalsefor a private setup and usebun run db:create-userto create accounts.LOG_LEVEL: one ofnone,error,warn,info, orverbose.
Additional knobs: LEGAL_PROFILE (switch legal copy), LOG_COLORS_ENABLED (colored dev logs), ARTICLE_EXTRACT_CACHE_ENABLED (extraction caching), PLAYWRIGHT_BASE_URL (point Playwright at a custom host).
bun run db:provisionThis verifies the connection and applies the schema.
When signup is disabled, create an account from the CLI:
bun run db:create-user <email> <password>Passwords must be at least 8 characters long. The CLI also prompts whether the new account should be persisted as an admin for invitation management.
bun devOpen http://localhost:3000 and sign in.
You should be able to open the dashboard, sign in, add a feed, and see articles populate. If feed refresh fails, check your DATABASE_URL, database reachability, and whether DB_DRIVER matches the connection you are using.
| Command | Purpose |
|---|---|
bun dev |
Start the standard local Next.js development server. |
bun run build |
Create a production build. |
bun run start |
Run the production server after building. |
bun check summary |
Run the repository quality summary. |
bun check --junit |
Run the Bun unit and integration test suite. |
The full quality suite includes a pinned Python-based complexity check powered by lizard.
Install the Python tooling once before running bun check commands that include the lizard step:
python3 -m pip install -r requirements-dev.txtThe Playwright workflow is isolated by design: it runs on port 3100 with its own .next-playwright build directory and cleans up afterward, leaving your normal dev session untouched. Browser binaries are not installed during bun install — run bun run setup:playwright first on any machine where you want to run the suite.
bun run setup:playwright
bun run test:e2eOther useful variants:
| Command | Purpose |
|---|---|
bun run test:e2e:headed |
Run the suite with a visible browser window. |
bun run test:e2e:ui |
Open the Playwright UI runner. |
bun run test:e2e:coverage |
Generate Playwright coverage artifacts and reports. |
| Command | Purpose |
|---|---|
bun run db:provision |
Verify the connection and apply the full schema. |
bun run db:push |
Push schema changes directly without generating migration files. |
bun run db:generate |
Generate SQL migrations with Drizzle Kit. |
bun run db:studio |
Open Drizzle Studio in the browser. |
librerss/
├── src/
│ ├── app/
│ │ ├── api/ # Feed, article, auth, and settings routes
│ │ ├── dashboard/ # Primary reading and feed-management UI
│ │ └── landing/ # Sign-in and public entry experience
│ ├── components/ # Shared app components and vendor-managed UI wrappers
│ └── lib/
│ ├── api/ # HTTP client, services, and response helpers
│ ├── auth/ # Session, CSRF, and credentials logic
│ ├── core/ # Feed fetching, parsing, and article domain logic
│ ├── db/ # Drizzle schema and database access
│ ├── distill/ # Readability and extraction strategies
│ ├── extract/ # Upstream fetch orchestration and caching
│ ├── fetch/ # Transport, proxy, TLS, and cookie-aware fetching
│ ├── hooks/ # Client-side React hooks
│ ├── sanitize/ # HTML sanitization pipeline
│ ├── server/ # Server-only guards, CSP, rate limits, and routing helpers
│ └── utils/ # Pure utility functions
├── scripts/ # Provisioning, user creation, and repo check tooling
├── public/ # Static assets
└── tests/ # Bun and Playwright coverage for product behavior
Made with ❤️ by Evan Schoffstall