Live Demo: kaldrick.tech
DevLens is a modern, intuitive web application designed specifically for developers, software engineers, tech students, and professionals. It aggregates high-quality developer-focused content from two trusted sources: DEV.to and Hacker News.
In a world where developers are bombarded with scattered information across blogs, forums, and news sites, DevLens provides a clean, personalized dashboard to stay informed on the latest trends in programming, AI/ML, frontend/backend frameworks, DevOps, cybersecurity, open source, and career opportunities — without information overload.
- Helps developers make better tech decisions and learn faster.
- Reduces time spent switching between tabs and sites.
- Supports daily habits like morning reading or staying ahead in a fast-moving industry.
- Particularly useful for students and professionals in growing tech hubs like Kigali, Rwanda.
This is not a gimmick — it solves a genuine productivity and learning problem faced by the developer community every day.
DevLens is built with a clean, dark-mode-first interface that feels professional and engaging:
-
Smart Lenses (Topic Tabs): Switch instantly between curated views:
- All Developer Content
- Frontend
- Backend & APIs
- AI / Machine Learning
- DevOps & Cloud
- Cybersecurity
- Mobile Development
- Career & Productivity
- Open Source
-
Powerful Live Search: Type in the search bar and results update instantly (debounced for smooth performance).
-
Advanced Filters:
- Source (DEV.to or Hacker News)
- Date range (Today, This Week, This Month)
- Multi-select tags (e.g., javascript, react, python, ai)
-
Sorting Options:
- Newest First
- Most Popular / Highest Engagement
- Relevance (for search results)
-
Beautiful Article Cards:
- Cover images (when available)
- Title, excerpt, author/publisher
- Tech tags
- Estimated read time
- Publish date and source indicator
-
Interactive Actions:
- Click any card to open a clean modal with full summary and "Read Original" button
- Save for Later (persists using localStorage — your personal reading list)
- Side-by-Side Comparison Mode: Select two articles to compare different perspectives on the same topic (e.g., a DEV.to tutorial vs. a Hacker News discussion)
-
Trending Tags Cloud: Discover popular topics at a glance
-
Loading states, skeletons, and graceful error handling (e.g., "One source unavailable — showing results from the other")
The UI is fully responsive and works great on desktop and mobile.
- Frontend: HTML5, CSS3, Vanilla JavaScript
- No backend required for the core app (static hosting friendly)
-
DEV.to Public Articles API
- Base URL:
https://dev.to/api/articles - Used for rich, community-written developer articles with cover images and tags
- Supports filtering by tags (e.g.,
?tag=javascript), search, pagination - Official docs: https://developers.forem.com/api/v0 (DEV.to is powered by Forem)
- Base URL:
-
Hacker News Firebase Public API
- Base URLs:
https://hacker-news.firebaseio.com/v0/topstories.jsonhttps://hacker-news.firebaseio.com/v0/newstories.jsonhttps://hacker-news.firebaseio.com/v0/item/{id}.json
- Used for high-signal tech discussions, Show HN, Ask HN, and trending links
- Completely free and public (no API key required)
- Official docs: https://github.com/HackerNews/API
- Base URLs:
Data Normalization: Articles from both sources are standardized into a common format for seamless filtering, sorting, and display.
Credits:
- DEV.to API – https://dev.to
- Hacker News API – Y Combinator / Firebase
- Clone the repository:
git clone <your-repo-url> cd devlens npx serve .
Or with Python:
python3 -m http.server 8080Do not open
index.htmldirectly as afile://URL — ES modules are blocked by the browser in that context.
This section documents how DevLens is deployed across two web servers with an Nginx load balancer distributing traffic between them.
┌─────────────┐
Internet ──▶ │ Load Balancer│ (lb-server)
│ Nginx :80 │
└──────┬──────┘
│
┌───────────────┴───────────────┐
▼ ▼
┌─────────────────┐ ┌─────────────────┐
│ Web Server 1 │ │ Web Server 2 │
│ Nginx :80 │ │ Nginx :80 │
│ (web-01) │ │ (web-02) │
└─────────────────┘ └─────────────────┘
Three servers are involved:
| Role | Hostname | Description |
|---|---|---|
| Load Balancer | lb-01 |
Receives all incoming requests, distributes to web servers |
| Web Server 1 | web-01 |
Serves the static DevLens files |
| Web Server 2 | web-02 |
Serves the static DevLens files (replica) |
SSH into web-01 and web-02 separately and run:
git clone <your-repo-url> /var/www/devlensVerify the files are in place:
ls /var/www/devlens
# index.html styles/ scripts/ assets/On both web-01 and web-02, create an Nginx site configuration:
sudo nano /etc/nginx/sites-available/devlensPaste the following:
server {
listen 80;
server_name _;
root /var/www/devlens;
index index.html;
# Serve static files directly
location / {
try_files $uri $uri/ /index.html;
}
# Cache static assets
location ~* \.(css|js|png|ico|jpg|jpeg|svg|webp)$ {
expires 7d;
add_header Cache-Control "public, immutable";
}
# Identify which server handled the request (useful for LB testing)
add_header X-Served-By $hostname;
}Enable the site and reload Nginx:
sudo ln -s /etc/nginx/sites-available/devlens /etc/nginx/sites-enabled/devlens
sudo nginx -t
sudo systemctl reload nginxVerify each server responds on its own before touching the load balancer:
curl -I http://<web-01-ip>/
curl -I http://<web-02-ip>/
# Both should return: HTTP/1.1 200 OKSSH into lb-01 and create the Nginx load balancer configuration:
sudo nano /etc/nginx/sites-available/devlens-lbPaste the following:
upstream devlens_pool {
# Round-robin by default — each request goes to the next server in turn
server <web-01-ip>;
server <web-02-ip>;
# Optional: enable keepalive connections to backends
keepalive 32;
}
server {
listen 80;
server_name _;
location / {
proxy_pass http://devlens_pool;
proxy_http_version 1.1;
proxy_set_header Connection "";
# Forward real client info to backend servers
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# Timeouts
proxy_connect_timeout 5s;
proxy_read_timeout 30s;
}
}Replace <web-01-ip> and <web-02-ip> with the private IP addresses of your web servers.
Enable the config and reload:
sudo ln -s /etc/nginx/sites-available/devlens-lb /etc/nginx/sites-enabled/devlens-lb
# Remove the default site if it conflicts on port 80
sudo rm -f /etc/nginx/sites-enabled/default
sudo nginx -t
sudo systemctl reload nginxThe configuration above uses round-robin (Nginx default), which cycles requests evenly across both servers. Two alternative algorithms are available if needed:
Least connections — sends each new request to the server with the fewest active connections:
upstream devlens_pool {
least_conn;
server <web-01-ip>;
server <web-02-ip>;
}IP hash — pins each client IP to the same backend (useful if session state matters):
upstream devlens_pool {
ip_hash;
server <web-01-ip>;
server <web-02-ip>;
}DevLens has no server-side session state (all state is in the browser via localStorage), so round-robin is the correct choice here.
Open a browser and navigate to http://<lb-01-ip>/. DevLens should load and fetch articles normally.
The X-Served-By header added in Step 2 identifies which backend handled each request. Send several requests and observe the header alternating:
for i in {1..6}; do
curl -sI http://<lb-01-ip>/ | grep X-Served-By
doneExpected output (alternating between servers):
X-Served-By: web-01
X-Served-By: web-02
X-Served-By: web-01
X-Served-By: web-02
X-Served-By: web-01
X-Served-By: web-02
Stop Nginx on web-01:
# On web-01:
sudo systemctl stop nginxThen send requests through the load balancer:
for i in {1..4}; do
curl -sI http://<lb-01-ip>/ | grep X-Served-By
doneAll responses should now show X-Served-By: web-02 — the load balancer automatically stops routing to the failed server.
Bring web-01 back up and confirm traffic resumes:
# On web-01:
sudo systemctl start nginx- Open
http://<lb-01-ip>/in a browser - Confirm articles load from DEV.to and Hacker News
- Test search — type a query and verify live results appear
- Apply a lens filter (e.g. "AI / ML") and confirm articles are filtered
- Open an article modal, save an article, and verify the save persists on refresh
- Select two articles and open the Side-by-Side Comparison modal
- Open DevTools → Network tab → confirm all assets (CSS, JS, images) return
200 OK
To deploy a new version, pull the latest code on both web servers:
# Run on web-01 and web-02:
cd /var/www/devlens
git pull origin mainNo server restart is required — Nginx serves files directly from disk.