Inspiration

Online echo chambers cause real-world harm, yet most people can’t see how narrow or broad their news consumption is. Radius was inspired by the idea that “you can’t fix what you can’t see.” Unlike existing tools that require extra effort, Radius works passively in the browser where people already read news.

What it does

Radius is a Chrome extension that tracks news articles and analyzes reading patterns in real time. It measures diversity across political spread, outlet variety, topic breadth, and source concentration, showing a 0–100 score with a concentric ring visual. The overlay provides ideological analysis, bias detection, evidence scoring, and context gap identification, all client-side. It also tracks how content reaches users, calculates a Reinforcement Velocity metric, and uses Gemini-powered recommendations to fill gaps and show multiple perspectives on the same story.

How we built it

Radius is built entirely with vanilla JavaScript, HTML, and CSS, with no frameworks, build step, or bundlers. It runs as a Chrome Manifest V3 extension with a modular architecture.

A service worker (background.js) listens for tab updates, extracts domains, matches them against a database of 35+ classified news outlets, and persists visit data and exposure metadata to chrome.storage.local.

Scoring uses standard deviation for political spread, weighted counts for outlet and topic diversity, and an inverse Herfindahl-Hirschman Index (HHI) for source concentration:

$$HHI = \sum_{i=1}^{n} s_i^2$$

where \(s_i\) is each outlet's share of total visits. Lower concentration yields a higher diversity score.

The article overlay is a content script pipeline: parser.js detects article structure (headline, author, date, and paragraph density) and computes a confidence score; lexicon.js provides keyword dictionaries and regex patterns; analyzer.js runs heuristic NLP across ideology, framing, evidence, rhetoric, and context gaps; and overlay.js renders a floating panel with six tabbed views.

Gemini integration (gemini.js) calls Gemini 2.0 Flash with Google Search grounding for personalised recommendations and cross-outlet article discovery, with local caching (1-hour and 30-minute TTLs) and exponential backoff retry logic to handle rate limits.

All visualisations, including concentric rings, radar charts, and spectrum bars, are rendered with inline SVG and CSS, as Manifest V3's Content Security Policy prohibits the use of external libraries and CDNs.

Challenges we ran into

  • Manifest V3 restrictions were a constant obstacle. The strict CSP forbids inline scripts, external CDNs, and eval(). We had to replace Chart.js with hand-rolled SVG/HTML charts, move all inline <script> blocks to external files, and work around limitations on chrome.scripting.executeScript for non-user-initiated contexts.
  • Content script architecture — ES modules aren't supported in content scripts, so we built a global namespace (window.RadiusX) pattern where each file registers itself and the controller (content.js) orchestrates them. Silent failures with no stack traces made debugging painful; we added extensive console.log instrumentation throughout the pipeline.
  • Article detection needed careful tuning. Our initial 55% confidence threshold missed legitimate articles, and the text extraction only looked for <article> tags. We lowered the threshold to 20%, added fallback extraction from all <p> tags, and built a multi-signal scoring system (headline presence, author, date, paragraph density, structured content).
  • Gemini API rate limits — on the free tier, every new tab opened triggered an API call, quickly hitting 429 errors. We solved this with chrome.storage.local caching and retry-with-backoff, reducing API calls by ~95%.
  • Narrative comparison initially used Google site: search operators, which produced irrelevant results. We switched to direct outlet search URLs and then to Gemini with search grounding for finding real, relevant articles across perspectives.

Accomplishments that we're proud of

Radius performs fully client-side NLP analysis with no data leaving the browser. The Reinforcement Velocity metric shows bubble dynamics over time. It works without a build step, classifies 35+ outlets by political leaning and type, and provides multi-axis ideological insights beyond a simple left/right spectrum.

What we learned

Manifest V3 requires a new extension approach with service workers and strict security. Heuristic NLP with curated lexicons is effective for bias detection. Caching is critical for API-based features. Building visualisations without libraries increases control and understanding of SVG and CSS.

What's next for Radius

  • Expanded outlet database — crowdsourced outlet classifications with community review, covering international and non-English sources.
  • Cross-browser support — port to Firefox (Manifest V2) and Safari (Web Extensions API).
  • Gemini-powered deep analysis — replace heuristic NLP with Gemini for more accurate ideological and framing analysis on individual articles, while keeping the client-side engine as a fast fallback.
  • Social features — anonymised, aggregate diversity scores to show users how their media diet compares to population averages.
  • Mobile companion — a lightweight version for mobile browsers that syncs with the desktop extension, and developing a synced mobile companion for social media apps such as Instagram and Twitter.

Built With

Share this project:

Updates