An AI-powered news ecosystem that reads the internet so you don't have to. Live RSS + NewsAPI ingestion, Gemini-generated summaries tuned to your reading level, a gamified quiz-and-leaderboard loop, and an interactive 3D globe of world headlines โ all wrapped in a neo-zine brutalist interface.
NutShell ships as two repos: ๐จ NEWS-AI (frontend, on Vercel) ยท โ๏ธ NEWS-AI-BACKEND (backend, on Render)
The modern news experience is broken in two directions at once: it's either an infinite doomscroll that respects none of your time, or a paywalled wall of jargon that assumes a finance degree. NutShell is my answer to both.
It ingests real news from 45+ live sources, then uses Google's Gemini to rewrite each story at a complexity level you choose โ anywhere from "explain it like I'm in 5th grade" to "give me the post-grad analyst brief." Then it makes staying informed genuinely fun: read articles to earn points, take a weekly quiz generated from the actual news, and climb a live leaderboard. Spin the globe to see what the world is reading right now.
No localStorage tokens. No XSS-able auth. No "summary" that's just the first paragraph copy-pasted. It's the news app I actually wanted to use.
๐ง Depth-calibrated AI summaries โ Pick a complexity from 1 to 10. Gemini treats it as a continuous gradient, not three canned presets โ a level 4 is genuinely distinct from a level 5. Two formats: Skim (3 punchy bullets) and Deep (a Bloomberg-style brief).
๐ฐ Real, full-text news โ NewsAPI + 45+ RSS feeds across 8 categories. The free tiers truncate articles, so NutShell scrapes the full body itself (with SSRF protection) before summarizing โ no "[+2400 chars]" cop-outs.
๐ฎ Gamified reading โ Earn points for genuine reading time, take an AI-generated weekly quiz built from the week's stories, and compete on a live weekly leaderboard.
๐ Interactive 3D globe โ A three.js globe of the planet; click any country to pull its top headlines straight from Google News in that country's locale.
๐ฌ Chat with the editor โ Ask follow-up questions about any article. The article is pinned as data, not instructions, with prompt-injection sanitization on both sides.
๐ Genuinely secure auth โ Passwordless Google OAuth with full ID-token signature verification. The JWT lives only in an HttpOnly cookie โ never in localStorage, never in a JSON body, never readable by JavaScript.
๐จ A UI with a point of view โ Neo-zine brutalist design: heavy type, a film-grain noise overlay, Framer Motion throughout, dark/light themes. Opinionated on purpose.
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
RSS x45 โโ โ FastAPI Backend โ
NewsAPI โโผโโingestโโโถ โ โข URL-normalize + SHA-256 โ
โ โ dedup โ
โ โ โข APScheduler (6h refresh, โ
โ โ 2h reconcile, 15m board) โ โโโโโโโโโโโโโโโ
โ โ โข Gemini 2.5 Flash service โ โโโ on โโโถ โ Gemini โ
โ โ (rate-limit + circuit โ demand โ 2.5 Flash โ
โ โ breaker + retry) โ โโโโโโโโโโโโโโโ
โ โ โข Google OAuth โ JWT cookie โ
โ โโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโ
(Kafka, โ โ JSON over HTTPS
optional) โ โ (HttpOnly cookie auth)
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Next.js 14 Frontend โ
โ โข App Router + React Query โ
โ โข Edge middleware gating โ
โ โข three.js globe, Framer โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
A few design decisions I'm proud of:
- URL-normalized dedup โ tracking params stripped, scheme/host normalized, then SHA-256 hashed, so the same story from five places counts once.
- Race-safe summary caching โ Postgres
ON CONFLICT DO NOTHINGwith a SQLiteIntegrityErrorfallback, keyed on(article_id, mode, depth_level). - Atomic counters โ reading time and article counts use
UPDATE col = col + n, so two open tabs can't clobber each other. - Per-concern circuit breakers โ a Gemini hiccup in summaries won't take down chat.
| Layer | Tools |
|---|---|
| Frontend | Next.js 14 (App Router), React 18, TypeScript, Tailwind CSS, Framer Motion, TanStack Query, Zustand, three.js / react-three-fiber |
| Backend | FastAPI, SQLAlchemy 2.x, Pydantic v2, APScheduler, slowapi, BeautifulSoup, feedparser, httpx |
| AI | Google Gemini 2.5 Flash |
| Data | SQLite (local) ยท PostgreSQL + psycopg v3 (prod) |
| Auth | Google OAuth 2.0 โ JWT in HttpOnly cookies |
| Infra | Render (backend) ยท Vercel (frontend) ยท Kafka (optional) |
Prerequisites: Python 3.11+ (3.14 tested), Node 18+, a Google OAuth client, and a Gemini API key. A NewsAPI key is optional โ RSS works without it.
1. Backend โ NEWS-AI-BACKEND
git clone https://github.com/achal2005/NEWS-AI-BACKEND.git
cd NEWS-AI-BACKEND
python -m venv venv
# Windows: .\venv\Scripts\activate macOS/Linux: source venv/bin/activate
pip install -r requirements.txt
# Create backend/.env from the example, then fill in your keys
cp .env.example .env
uvicorn app.main:app --reload --port 8000Backend is now live at http://localhost:8000 โ interactive API docs at /docs.
2. Frontend โ NEWS-AI
git clone https://github.com/achal2005/NEWS-AI.git
cd NEWS-AI
npm install
echo "NEXT_PUBLIC_API_URL=http://localhost:8000" > .env.local
npm run devOpen http://localhost:3000 and you're in.
๐ก Run the backend and frontend in two terminals (backend first, so the API is up).
Backend (backend/.env)
| Variable | Required | Notes |
|---|---|---|
JWT_SECRET_KEY |
โ | โฅ 32 chars. The app refuses to boot in prod with a known dev default. |
DATABASE_URL |
โ | sqlite:///./news_db.sqlite locally, or a Postgres URL in prod. |
GEMINI_API_KEY |
โ | From Google AI Studio. |
GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRET / GOOGLE_REDIRECT_URI |
โ | Google OAuth credentials. |
NEWS_API_KEY |
โ | Optional; RSS feeds work without it. |
ENVIRONMENT / DEBUG / DEV_LOGIN_ENABLED |
โ | Dev conveniences (dev-login is triple-guarded). |
KAFKA_BOOTSTRAP_SERVERS / RENDER_EXTERNAL_URL |
โ | Optional queue + keep-alive ping. |
Frontend (frontend/.env.local)
| Variable | Notes |
|---|---|
NEXT_PUBLIC_API_URL |
Backend base URL (e.g. http://localhost:8000). |
NEXT_PUBLIC_SITE_URL |
Optional; canonical site URL for OG metadata. |
โ ๏ธ .envfiles are gitignored and must never be committed โ they hold live secrets.
Backend โ NEWS-AI-BACKEND
app/
โโโ main.py App + lifespan (migrations, scheduler, keep-alive)
โโโ api/ auth ยท news ยท gamification ยท user routers
โโโ core/ config ยท security ยท cache ยท scheduler ยท limiter
โโโ db/ SQLAlchemy models + session
โโโ services/ gemini ยท oauth ยท newsapi ยท rss ยท scraper ยท kafka
Frontend โ NEWS-AI
app/ routes (dashboard, article, quiz, globe, ...)
components/ UI + globe scene
lib/ auth context
middleware.ts edge auth gating
New here? brain.md (in each repo) is a one-page map of the whole codebase.
- JWT only ever in an HttpOnly cookie โ zero JS-accessible token surface.
- Full Google ID-token signature verification (not just decode).
- SSRF guard on all server-side fetches (private/loopback IPs rejected, size + time caps).
- Prompt-injection sanitization + a structural data/instruction boundary for AI chat.
- Rate limiting on auth and refresh endpoints (slowapi) plus per-user Gemini token buckets.
- CSP without
unsafe-eval, bcrypt(12) password hashing, strict CORS allow-list.
- Backend โ Render:
render.yaml+Dockerfile+build.sh. Auto-rewritespostgres://URLs for psycopg v3, runs a tuned connection pool, and self-pings every 14 min to dodge free-tier cold starts. - Frontend โ Vercel:
output: 'standalone', CSP headers, and cross-originSameSite=none; Securecookies wired up innext.config.js.
Render's free tier spins the backend down after ~15 min of inactivity, so the first request after a quiet spell (typically the login flow) waits 30โ60s for it to wake. The app ships with an internal self-ping every 10 minutes, but that can't help once the server is already asleep. To keep it warm 24/7, add a free external monitor:
- Create a free account at UptimeRobot (or cron-job.org).
- Add a new HTTP(s) monitor pointing at
https://<your-render-url>/health. - Set the interval to 5 minutes.
That's it โ the server never idles long enough to cold-start. For a guaranteed fix with zero
spin-down, upgrade the Render service off the free plan. If most of your users are in one
region, also set Render's region (in render.yaml) to the nearest one to cut round-trip latency.
- Migrate from the EOL
google-generativeaiSDK togoogle-genai - Redis-backed caching for multi-instance scale-out
- Push notifications for breaking news in followed categories
- Saved articles / read-later
- Automated test suite (pytest + Playwright)
MIT โ see LICENSE. Use it, fork it, learn from it.
Built with curiosity, caffeine, and a refusal to read another truncated summary.