A free, automated, daily-curated tech feed for developers who never stop learning.
Keep Up Daily is a Python-powered web scraper that automatically collects trending tech articles, tutorials, and repositories every single day β and publishes them as a clean, distraction-free reading dashboard on GitHub Pages.
No ads. No tracking. No monetization. Just pure learning content.
| Source | Type | What it captures |
|---|---|---|
| Dev.to | REST API | Top community articles |
| Hacker News | Firebase API | Top stories |
| GitHub Trending | HTML scraping | Daily trending repositories |
| JSON API | Hot posts from 11 programming subreddits | |
| Lobste.rs | JSON API | Hottest tech stories |
| Hashnode | GraphQL API | Best developer blog posts |
Content is automatically categorized into: AI & ML, Web Dev, DevOps & Cloud, Languages, Frameworks, Security, Career, and General.
- Clean, focused reading experience β zero distractions, content-first design
- Category filter tabs β focus on what matters to you
- Full-text search β instantly filter across all articles
- Date navigation β browse up to 30 days of history
- Dark mode β respects your system preference, toggleable
- Bilingual UI β English πΊπΈ and Portuguese π§π·
- Fully responsive β works on desktop, tablet, and mobile
- No JavaScript frameworks β fast, lightweight vanilla JS + TailwindCSS
keep-up-daily/
βββ .github/workflows/
β βββ deploy.yml # Daily cron + GitHub Pages deployment
βββ scraper/
β βββ __init__.py
β βββ __main__.py # python -m scraper entrypoint
β βββ main.py # Orchestrator
β βββ config.py # All configuration in one place
β βββ categorizer.py # Keyword-based categorization
β βββ output.py # JSON output + data retention
β βββ sources/
β βββ __init__.py # Exports ALL_SCRAPERS list
β βββ base.py # Article dataclass + BaseScraper
β βββ devto.py
β βββ hackernews.py
β βββ github_trending.py
β βββ reddit.py
β βββ lobsters.py
β βββ hashnode.py
βββ web/
β βββ index.html # Dashboard (TailwindCSS)
β βββ app.js # Vanilla JS app logic + i18n
βββ data/ # Auto-generated JSON (one file per day)
βββ requirements.txt
βββ LICENSE
βββ README.md
- Python 3.10+
- pip
# Clone the repository
git clone https://github.com/LuizMacedo/keep-up-daily.git
cd keep-up-daily
# Install dependencies
pip install -r requirements.txt
# Run the scraper
python -m scraper
# Output will be in data/YYYY-MM-DD.jsonTo preview the dashboard locally, serve the web/ folder plus data/:
# Quick local preview
mkdir -p /tmp/kud-preview/data
cp web/* /tmp/kud-preview/
cp data/*.json /tmp/kud-preview/data/ 2>/dev/null
cd /tmp/kud-preview && python -m http.server 8000
# Open http://localhost:8000Once pushed to GitHub, the workflow runs automatically:
- Every day at 8:00 AM Central Time (14:00 UTC)
- Can also be triggered manually: Actions β Keep Up Daily β Run workflow
- Scrapes all sources, commits data, and deploys to GitHub Pages
To activate the dashboard on your fork:
- Go to your repository Settings β Pages
- Under Build and deployment, set Source to GitHub Actions
- Trigger the workflow manually (Actions β Keep Up Daily β Run workflow)
- Your dashboard will be live at
https://<your-username>.github.io/keep-up-daily/
Important: You must select "GitHub Actions" as the source, not "Deploy from a branch".
This project is designed to be forked and customized. Here's how:
Click the Fork button at the top of this page.
Follow the instructions above to set the source to "GitHub Actions".
Edit scraper/config.py:
# Add/remove subreddits
SOURCES["reddit"]["subreddits"] = ["programming", "rust", "your_favorite_sub"]
# Disable a source
SOURCES["hashnode"]["enabled"] = False
# Add more GitHub Trending languages
SOURCES["github_trending"]["languages"] = ["", "python", "rust", "zig"]Edit the CATEGORIES dictionary in scraper/config.py to add keywords for topics you care about.
Create a new file in scraper/sources/ following this pattern:
# scraper/sources/my_source.py
from .base import Article, BaseScraper
class MySourceScraper(BaseScraper):
name = "my_source"
def fetch(self) -> list[Article]:
articles = []
# Your scraping logic here...
# Return a list of Article objects
return articlesThen register it in scraper/sources/__init__.py:
from .my_source import MySourceScraper
ALL_SCRAPERS = [
# ...existing scrapers...
MySourceScraper,
]Contributions are welcome! This project is meant to help the developer community learn and grow.
- Fork the repository
- Create a feature branch:
git checkout -b feature/my-improvement - Make your changes
- Run the scraper locally to test:
python -m scraper - Commit with a clear message:
git commit -m "Add: new source scraper for XYZ" - Push and open a Pull Request
- π New sources β add scrapers for tech newsletters, podcasts, YouTube channels
- π·οΈ Better categorization β improve keyword matching or add ML-based classification
- π More languages β add UI translations beyond EN/PT
- π Analytics β weekly trends, most popular topics, source comparison
- π¨ UI improvements β accessibility, animations, reading progress
- π± PWA support β offline reading, push notifications
- π§ͺ Tests β unit tests for scrapers and categorizer
The codebase follows a modular architecture. Each source scraper is independent and follows the BaseScraper interface. The Article dataclass is the normalized schema. Feel free to refactor, optimize, or propose architectural changes.
βββββββββββββββ ββββββββββββββββ βββββββββββββββ
β Dev.to β β β β Categorize β
β HackerNews ββββββΆβ OrchestratorββββββΆβ Deduplicateβ
β GitHub β β (main.py) β β Sort β
β Reddit β β β β β
β Lobsters β ββββββββββββββββ ββββββββ¬βββββββ
β Hashnode β β
βββββββββββββββ βΌ
βββββββββββββββ
β data/ β
β YYYY-MM-DD β
β .json β
ββββββββ¬βββββββ
β
ββββββββΌβββββββ
β GitHub Pagesβ
β Dashboard β
βββββββββββββββ
Daily at 14:00 UTC, GitHub Actions:
- Runs all scrapers in sequence (with error isolation)
- Deduplicates articles by URL
- Categorizes using keyword matching
- Sorts by engagement score
- Saves to
data/YYYY-MM-DD.json - Commits and pushes data
- Builds and deploys the static dashboard
"The best time to start learning was yesterday. The second best time is today."
This project exists because:
- Staying current in tech is overwhelming β there are too many sources to check
- Curated feeds shouldn't cost money or track you
- Open source tools should make learning accessible to everyone
- Community-driven means everyone benefits from everyone's contributions
MIT β use it however you want. See LICENSE for details.
Made with β€οΈ for the developer community
If this helps you learn something new, consider sharing it with a fellow developer.
β Star this repo if you find it useful!