A Gleam/Erlang RSS and Atom feed reader. Tracks feeds, fetches entries on a schedule, and serves a server-rendered HTML UI with HTMX for partial updates.
- Subscribe to RSS/Atom feeds (manual add or OPML import)
- Unread, starred, and history views
- Background scheduler fetches new entries every 3 minutes
- SQLite storage via sqlight + Parrot codegen
- Server-rendered HTML with Lustre + lustre_pipes + HTMX
- No authentication (handle at the reverse proxy / network layer)
mise install # install gleam, erlang, rebar3
gleam deps download
gleam run # serves on http://localhost:3000The database defaults to feedreader.db in the working directory. Override
with the DATABASE_PATH environment variable.
gleam check # type check
gleam test # run the test suite
gleam format # format code
mise run pre-commit # format + check + lint + test
mise run gen # regenerate Parrot SQL codegen from schema + queries
mise run assets # install + build TailwindCSSThe CI builds a multi-arch image (amd64 + arm64) and pushes it to GHCR on every
push to main and on version tags (v1.0.0).
docker pull ghcr.io/kasuboski/feedreader:main
docker run -d \
-p 3000:3000 \
-v feedreader-data:/data \
-e DATABASE_PATH=/data/feedreader.db \
ghcr.io/kasuboski/feedreader:mainOr with docker-compose (see docker-compose.yaml):
docker compose up -dThe SQLite database persists in a Docker volume mounted at /data. To migrate
from the old Elixir/Phoenix deployment, copy the existing feedreader.db into
the volume — the schema is compatible.
| Layer | Technology |
|---|---|
| Language | Gleam → Erlang/BEAM |
| Web server | Wisp + Mist |
| HTML rendering | Lustre SSR + lustre_pipes |
| Interactivity | HTMX via hx |
| Database | SQLite via sqlight + Parrot |
| Background workers | Gleam/OTP actors (scheduler + fetcher) under a supervisor |
See SCOUTING_REPORT.md for the full Elixir → Gleam migration analysis.