██████╗ ███████╗███████╗██╗ ██╗███████╗██████╗ ██╗ ██╗██╗ ███████╗███████╗
██╔════╝ ██╔════╝██╔════╝██║ ██╔╝██╔════╝██╔══██╗██║ ██║██║ ██╔════╝██╔════╝
██║ ███╗█████╗ █████╗ █████╔╝ ███████╗██████╔╝██║ ██║██║ ███████╗█████╗
██║ ██║██╔══╝ ██╔══╝ ██╔═██╗ ╚════██║██╔═══╝ ██║ ██║██║ ╚════██║██╔══╝
╚██████╔╝███████╗███████╗██║ ██╗███████║██║ ╚██████╔╝███████╗███████║███████╗
╚═════╝ ╚══════╝╚══════╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═════╝ ╚══════╝╚══════╝╚══════╝
{ GeeksPulse } — Feel the pulse of dev.
Your daily dev briefing, minus the noise.
✓ Hacker News ............. 30 stories
✓ Krebs on Security ....... 12 stories
✓ IEEE Spectrum ........... 18 stories
✓ GitHub Blog ............. 8 stories
✓ Google AI Blog .......... 10 stories
✓ Rust Blog ............... 6 stories
✓ Go Blog ................. 5 stories
# 51 feeds · 0 paywalls · 100% signal
✓ Ready. No paywalls. You're welcome.
▮
GeeksPulse is a static developer-news site powered by a scheduled feed-generation pipeline. A Node.js script fetches and normalises RSS feeds into static JSON files, and the frontend renders from that cache for speed and reliability.
It pulls from 50 hand-picked RSS feeds across 11 categories, sorts them newest-first, and presents them in a sleek cyberpunk UI — no doomscrolling Twitter required.
- 🚫 No ads. No VC money. No ad trackers.
- ⚡ Static hosting. The site is served as plain HTML/CSS/JS — no application server required.
- 🔓 No paywalls. Every article is directly accessible.
- 🧠 No framework bloat. Just clean, fast, modern vanilla web.
| Feature | Details |
|---|---|
| 📡 50 RSS Feeds | Hand-curated from the best dev sources on the web |
| 🗂️ 11 Categories | General · Security · AI · Python · JavaScript · Java · DevOps · Open Source · Rust · Go · Architecture |
| 🤖 AI Summaries | On-demand article summaries via pre-cached snippets or local Ollama fallback |
| ⚡ Static Cache | Articles pre-built by a Node.js pipeline; browser loads JSON instantly |
| 🔄 Auto-Refresh | Configurable: 1m · 5m · 10m · 15m · 30m · 1h |
| 🃏 Grid & List View | Toggle between layouts, preference saved locally |
| 💾 localStorage Prefs | Your filter, view mode & refresh interval persist across sessions |
| 💀 Skeleton Loaders | Shimmer placeholders while feeds are loading |
| 🎨 Cyberpunk UI | Dark theme, neon glows, glitch animations, scanline overlay |
| 🖥️ Animated Terminal | Hero terminal with staggered fade-in lines |
| ♿ Accessible | ARIA roles, labels, aria-pressed, keyboard navigation, prefers-reduced-motion |
| 📱 Responsive | Mobile-first with chip filters on small screens |
| 🔖 Bookmarks | Save articles to localStorage for later reading |
| ⌨️ Keyboard Shortcuts | / search · j/k navigate · o open · r refresh · Esc clear |
| 🏥 Feed Health Panel | Live status: last updated time, online/failed feed counts |
| ⏱️ Reading Time | Estimated read time displayed on every article card |
| 🔗 Share Articles | Web Share API with automatic clipboard fallback |
📡 General
🔐 Security
🤖 AI / ML
🐍 Python
🟡 JavaScript
🌍 Open Source
☕ Java
🦀 Rust
🐹 Go
🏛️ Architecture
GeeksPulse has a full layered test suite — 181 tests that run in CI on every push before any deploy can happen.
| Tool | Role |
|---|---|
| Vitest | Unit, integration & DOM component tests |
| happy-dom | Lightweight DOM environment for browser-side tests |
| Playwright | End-to-end smoke tests (Chromium) |
| @vitest/coverage-v8 | V8-based coverage with per-file thresholds |
# Run all unit, integration & DOM tests (171 tests, ~800ms)
npm test
# Run in watch mode during development
npm run test:watch
# Run with coverage report (outputs to coverage/)
npm run test:coverage
# Run end-to-end smoke tests (10 tests, ~25s — starts Vite dev server automatically)
npm run test:e2e
# Open Playwright UI runner
npm run test:e2e:uitests/
unit/
utils.test.mjs ← scripts/lib/utils.mjs (46 tests)
browser-utils.test.js ← js/utils.js (32 tests)
storage.test.js ← js/storage.js (22 tests)
classifier.test.mjs ← scripts/lib/classifier.mjs (12 tests)
sponsored.test.mjs ← scripts/lib/sponsored.mjs (13 tests)
integration/
parser.test.mjs ← scripts/lib/parser.mjs (22 tests)
build-feed.test.mjs ← pipeline dedup, sort, cap (5 tests)
dom/
cards.test.js ← js/cards.js (happy-dom) (19 tests)
e2e/
smoke.spec.js ← Playwright full-browser (10 tests)
fixtures/
rss-valid.xml / rss-encoded-content.xml / rss-single-item.xml / rss-empty.xml
atom-valid.xml / atom-alternate-link.xml
push / schedule
│
▼
test job — npm test (171 Vitest tests)
│ needs: test
▼
build job — Ollama + feed data + GitHub Pages deploy
│ needs: build (main branch only)
▼
e2e job — npm run test:e2e (10 Playwright tests)
└─ report uploaded as CI artifact (7-day retention)
A failing unit or integration test blocks the entire pipeline — no bad code can reach production.
const architecture = {
hosting: "Static files — no application server required",
markup: "HTML5", // semantic, accessible
styles: "Vanilla CSS", // custom properties, animations, grid
logic: "Vanilla JS", // ES2022+ native ES modules, no bundler
modules: "js/ — 15 focused ES modules loaded via <script type=\"module\">",
fonts: ["JetBrains Mono", "Space Grotesk", "Bangers"],
feedPipeline: "Node.js (scripts/build-feed.mjs + scripts/lib/*.mjs)",
bundler: "Vite 6", // dev server + production build
storage: "localStorage", // preferences & bookmarks
deps: ["fast-xml-parser", "ollama"], // build-time; ollama for local AI summaries
devDeps: ["vite", "vitest", "happy-dom", "@playwright/test", "@vitest/coverage-v8", "msw"],
analytics: "Google Analytics (basic traffic insights)",
};The frontend's primary data source is the pre-built public/feed.json file. If that file is missing or empty, the app silently falls back to fetching RSS feeds directly via browser-side CORS proxies — this is an emergency path only and is not used during normal page loads.
The scripts/build-feed.mjs script is a Node 18+ server-side utility that pre-fetches all feeds and writes a static JSON cache to public/. GitHub Actions runs this every 30 minutes on a schedule to keep the cache fresh.
The build script is split into focused modules under scripts/lib/ — see 📂 Project Structure for the full layout.
# Install dependencies (build-time + dev)
npm install
# Fetch all feeds and write public/feed.json + public/feed-health.json
npm run build:feed
# Regenerate sitemap.xml (homepage-only canonical URLs)
npm run build:sitemap
# Inject latest articles into index.html for SEO crawlers
npm run build:seo
# Write public/version.json
npm run build:version
# Run the full pipeline (data + Vite production build)
npm run build| Output file | Description |
|---|---|
public/feed.json |
Up to 300 deduplicated articles, sorted newest-first |
public/feed-health.json |
Per-feed health: ok/error/article count + last updated time |
public/version.json |
Build timestamp and version metadata |
sitemap.xml |
Minimal canonical sitemap (homepage only) |
index.html |
SEO fallback articles injected between GENERATED_LATEST_ARTICLES_START/END markers |
- Open
data/feeds.json. - Add a new entry:
{ "id": "my-blog", "name": "My Blog", "url": "https://myblog.com/feed.xml", "category": "General", "enabled": true } - Run
npm run buildto regenerate the cache. - Commit both
data/feeds.jsonand the updatedpublic/feed.json.
# Clone the repo
git clone https://github.com/dante0747/geekspulse.dev.git
cd geekspulse.dev
# Install dependencies
npm install
# Start the Vite dev server (hot-reload, proper module resolution)
npm run dev
# or serve the static files with any other server
npx serve .
# or
python -m http.server 8080Then open http://localhost:5173 (Vite default) or http://localhost:8080 if using a plain static server.
To regenerate the feed cache with live data:
npm install
npm run buildgeekspulse.dev/
├── index.html # App shell — nav, hero, sidebar, feed grid
├── styles.css # Full cyberpunk design system
├── playwright.config.js # Playwright E2E configuration
├── vite.config.js # Vite + Vitest configuration (test, coverage thresholds)
├── js/ # ES module source (loaded via <script type="module">)
│ ├── main.js # Entry point — app state, render loop, event wiring
│ ├── config.js # Static data: feeds list, categories, SVG icons, constants
│ ├── analytics.js # GA4 event helper
│ ├── storage.js # localStorage — preferences & bookmarks
│ ├── utils.js # Pure utilities: esc, relTime, truncate, toast, etc.
│ ├── http.js # CORS proxy chain (fetchViaCorsProxy)
│ ├── images.js # Image pipeline: extraction, scoring, caching, resolution
│ ├── consent.js # Cookie consent banner logic
│ ├── feed.js # RSS/Atom parsing & feed fetching
│ ├── cards.js # Card HTML generators (grid, list, skeleton, placeholder)
│ ├── feeds-registry.js # Feed registry loader — fetches & caches data/feeds.json at startup
│ ├── settings-panel.js # Settings popover (auto-refresh, view, theme, cache)
│ ├── pulse-panel.js # My Pulse drawer (topic/source filters, presets)
│ ├── summary.js # AI Summary modal — pre-cached snippets or Ollama fallback
│ └── paypal-modal.js # PayPal support modal
├── favicon.svg # SVG favicon
├── og-image.png # Open Graph image
├── sitemap.xml # SEO sitemap (auto-generated by scripts/generate-sitemap.mjs)
├── robots.txt # Crawler rules
├── assets/
│ └── fallbacks/ # Category SVG fallback images (ai, security, devops, …)
├── data/
│ └── feeds.json # Feed registry — 50 hand-curated RSS/Atom sources
├── public/
│ ├── feed.json # Pre-built article cache (generated by build script)
│ ├── feed-health.json # Per-feed health report (generated by build script)
│ ├── version.json # Build version info (generated by build script)
│ └── sw.js # Service worker
├── scripts/
│ ├── build-feed.mjs # Entry point — orchestrates the feed build pipeline
│ ├── generate-sitemap.mjs # Generates sitemap.xml from data/feeds.json
│ ├── generate-seo-content.mjs # Injects latest articles into index.html for SEO
│ ├── generate-version.mjs # Writes public/version.json
│ └── lib/ # Build pipeline modules (imported by build-feed.mjs)
│ ├── config.mjs # All constants, regex patterns, XML parser instance
│ ├── utils.mjs # Pure helpers (normalizeUrl, stripHtml, …) + streamHtml
│ ├── ai.mjs # Ollama client + shared AI cache (live ESM bindings)
│ ├── classifier.mjs # Keyword + LLM article category classification
│ ├── sponsored.mjs # Regex + LLM sponsored/promotional content detection
│ ├── summarizer.mjs # LLM article summarization (fills missing snippets)
│ ├── images.mjs # Image scoring/extraction + og:image resolver
│ ├── parser.mjs # RSS/Atom XML parsing + per-feed HTTP fetcher
│ └── pipeline.mjs # Article set helpers + named pipeline pass functions
└── tests/
├── unit/ # Pure-logic tests (Vitest, Node + happy-dom)
├── integration/ # Build-pipeline integration tests (Vitest, Node)
├── dom/ # Browser component tests (Vitest, happy-dom)
├── e2e/ # Full-browser smoke tests (Playwright, Chromium)
└── fixtures/ # RSS/Atom XML fixtures for parser tests
The UI uses a cyberpunk-inspired design language with:
| Token | Value | Usage |
|---|---|---|
--cyan |
#58c8ff |
Primary accent, links, glow |
--green |
#39d353 |
Live status, success |
--purple |
#bc8cff |
Support, AI category |
--red |
#ff5555 |
Security category, errors |
--yellow |
#e3c55e |
JS category, warnings |
--orange |
#f07f2f |
Java category |
--bg |
#080b12 |
Page background |
--font |
JetBrains Mono |
Everything |
Animations include: grid drift, scanlines, neon flicker, glitch, cursor blink, and card hover lifts. All animations respect the prefers-reduced-motion media query.
GeeksPulse has no ads and no paywalls. It uses Google Analytics for basic traffic insights so the project owner can understand usage and improve the site. It does not use advertising trackers, sell user data, or personalise ads.
Contributions are welcome! See CONTRIBUTING.md for guidelines.
Quick ways to help:
- 📡 Suggest a new RSS feed via Issues
- 🐛 Report bugs or broken feeds
- ⭐ Star the repo to spread the word
- 💬 Open a PR — all skill levels welcome
GeeksPulse is free and indie. No ads, no investors, no data selling.
If it saves you from opening 12 tabs today, consider tossing a coffee:
Recommended settings for the GitHub repository:
Description: Developer news without the noise — a fast, open-source RSS-powered news hub for software engineers.
Website: https://geekspulse.dev/
Suggested topics:
developer-news rss news-aggregator javascript static-site open-source ai-news security-news programming software-engineering
// thank you, you absolute legend ❤
© 2026 GeeksPulse — No ads. No paywalls. No ad trackers.
Built for developers who like clean feeds, good tools, and fewer tabs.