A minimal, fast RSS reader hosted on GitHub Pages with a dark UI.
- Dark mode UI - GitHub-inspired dark theme
- Category tabs - Filter feeds by category
- Collapsible feeds - Click feed headers to expand/collapse
- Inline article expansion - Click articles to read content inline
- Full-text extraction - Fetches complete article content when available
- Read state tracking - Read articles are dimmed (stored in localStorage)
- Keyboard navigation - Use
j/kto navigate,/to search,mto mark read - Search - Filter articles by title in real-time
- Offline support - Service Worker caches feeds for offline reading
- XSS protection - Content sanitized server-side and with DOMPurify
- Parallel fetching - All feeds fetched in parallel for speed
- Content limits - Oversized articles truncated to prevent bloat
- 4-hour updates - GitHub Actions fetches feeds every 4 hours
https://kossov-it.github.io/rss/
| Key | Action |
|---|---|
j / ↓ |
Next article |
k / ↑ |
Previous article |
Enter / o |
Open/close article |
m |
Mark article as read |
/ |
Focus search |
Esc |
Close article / blur search |
- Fork or clone this repo
- Enable GitHub Pages: Settings → Pages → Source:
mainbranch - Enable Actions: Actions → Enable workflows
- Run the Action manually once: Actions → "Fetch RSS Feeds" → Run workflow
- Access at
https://<username>.github.io/<repo>/
| File | Purpose |
|---|---|
index.html |
Frontend UI (single-page app) |
config.json |
Feed configuration |
scripts/fetch-feeds.js |
Feed fetcher (runs in GitHub Action) |
.github/workflows/fetch.yml |
4-hour cron job |
data/feeds-index.json |
Lightweight feed index (auto-updated) |
data/feeds.json |
Legacy full feed data (auto-updated) |
data/feeds/*.json |
Individual feed files with full content |
sw.js |
Service Worker for offline support |
manifest.json |
PWA manifest |
Edit config.json:
{
"articlesPerFeed": 20,
"fetchFullText": true,
"categories": [
{
"name": "News",
"feeds": [
{ "title": "Feed Name", "url": "https://example.com/rss" }
]
}
]
}| Option | Description |
|---|---|
articlesPerFeed |
Default number of articles per feed |
fetchFullText |
Enable full article content extraction |
Per-feed articlesPerFeed |
Override default for specific feeds |
Push changes and the Action will run automatically.
# Install dependencies
npm install
# Fetch feeds locally
node scripts/fetch-feeds.js
# Serve locally (required - can't open index.html directly due to CORS)
python3 -m http.server 8000
# Then open http://localhost:8000- GitHub Action runs every 4 hours
fetch-feeds.jsfetches all RSS feeds in parallel- For each article, extracts full content using Readability
- Sanitizes content server-side (removes scripts, event handlers)
- Truncates oversized content (>50KB) to prevent bloat
- Writes lightweight index + individual feed files
- Loads lightweight index first (
feeds-index.json) - Lazy-loads full article content on click
- Falls back to legacy
feeds.jsonif index unavailable - Caches loaded content in memory
- Read state stored in browser localStorage (not synced across devices)
- Unique IDs prefixed with feed slug to prevent collisions
- Content size limit of 50KB prevents bloated "Top 10" listicles
- Honest user-agent identifies as RSSReader to avoid ToS violations
- Health checks fail the build if no articles were fetched