Local Radar
Essentially a Bloomberg Terminal for US cities.
Inspiration
Every small business owner we know makes the biggest decision of their career where to open, when to expand, whether to hold on one more year on a gut feeling and a walk around the block. Meanwhile, an analyst covering a public company has a Bloomberg Terminal such as every filing, hiring signal, and competitor move on one screen, ranked and explained.
What it does
Local Radar is a local business intelligence terminal covering the 20 largest U.S. cities by population, with real neighborhoods, real businesses, and real addresses in each one.
Reasoning features:
- Business Health Score an AI-generated 0–100 score with the reasons behind it (
+ hiring increased,+ reviews improving,- parking complaints up,- competitor opened nearby), not a number pulled out of a black box. - AI Detective ask "Why is Downtown losing coffee shops?" and watch a five-agent pipeline reason across permits, demographics, rent, reviews, closures, and events to build an answer.
- Predict the Future closure probability with a real confidence band derived from token logprobs, plus the evidence trail behind the forecast.
- AI Debate two agents argue opposite sides of a decision and a third delivers a verdict, so you see the counterargument instead of a single confident answer.
- Competitor Simulator pick your business, get your rivals' actual strengths and concrete countermoves.
Spatial and temporal features:
- Opportunity Heatmap an interactive city grid scoring every neighborhood from "great opportunity" to "avoid," per business category.
- Shockwave Simulation "What if Costco opens here?" or "What if the anchor tenant closes?" traced through a six-step chain reaction across grocery, traffic, property values, restaurants, and fuel.
- Memory Timeline January through July snapshots showing what actually moved: hiring, reviews, complaints, competition, and net health.
- Business DNA a six-axis radar identity: growth, stability, competition, innovation, community trust, and expansion potential.
How I built it
Plain HTML, CSS, and JavaScript. No framework, no build step, no bundler. Open a local server and it runs. That constraint was deliberate: we wanted the thing to be readable, forkable, and impossible to break with a dependency update.
- Frontend semantic HTML with a hand-written CSS design system built on the MaterialM token palette. Roughly 40 KB of CSS driving light and dark themes off a single
data-themeattribute, with every color, radius, and shadow as a custom property. - Visualization every chart is hand-drawn on
<canvas>with no charting library: animated score gauges, the six-axis DNA radar, the 9×6 opportunity heatmap with hit testing and hover tooltips, and the shockwave chain diagram. All of them redraw on theme change and repack automatically so no city can break the layout. - Reasoning engine a single
AIclient speaking the OpenAI chat-completions protocol against OpenRouter free models, with automatic fallback down a four-model chain when one is unavailable, rate limited, or refuses a parameter. - Data layer a hand-researched atlas of 20 cities: 8 real neighborhoods, 6 real businesses with real addresses, 2 real news anchors, 2 real recurring events, and 4 simulation scenarios each. A hydration layer derives health signals, DNA axes, timelines, ticker items, and alerts deterministically from those records, so the same city always produces the same numbers.
Challenges I ran into
The API key that looked broken but wasn't. Every call to OpenRouter failed silently. The key was valid, the endpoint was right, the model existed. The actual cause: opening index.html by double-clicking loads it from a file:// path, which sends Origin: null, and the two attribution headers we were sending turned every request into a CORS preflight that a null origin can never pass. The request was dying inside the browser before it ever hit the network. We now detect file:// and send only the minimum headers, ship a one-click local server, and — more importantly — replaced "key rejected" with error messages that name the real cause, whether that is a 403 privacy setting or a 429 rate limit.
Migrating providers twice, mid-build. We started on Gemma, moved to Gemini, then to OpenAI, then landed on OpenRouter. Each move meant a different auth scheme and a different feature surface. OpenRouter has no /embeddings endpoint, so our semantic search had to degrade gracefully to substring matching rather than crash. Free models reject parameters that paid ones accept — seed, logprobs, strict schemas so every request now retries once with a plain body instead of failing the panel.
What I learned
The reasoning layer is the product, not the data layer. Our first instinct was to build more charts. What actually made people lean in was the Detective explaining why Downtown is losing coffee shops, and the Debate showing the counterargument. A number without a reason is a number you do not trust.
Error messages are a feature. We lost real hours to a CORS failure disguised as an auth failure. Now every failure path names its actual cause and the fix. That single change made the project debuggable by someone who did not build it.
Constraints produce better architecture. Refusing a framework forced us to understand our own state flow. Refusing a charting library taught us canvas rendering properly. Deriving everything from a per-city record meant the app scaled from 1 city to 20 without a rewrite.
Provider portability matters more than provider choice. Because we targeted the OpenAI chat-completions protocol rather than any single vendor's SDK, switching providers four times cost us a base URL and a model list each time not a rewrite.
Be explicit about what is real. Labeling simulated metrics as simulated cost us nothing and made every real thing in the project more credible.
What's next for Local Radar
- Watchlists and alerting. Let owners track their block and get notified when a competitor files a permit, a rent comp shifts, or their health score moves pushed, not polled.
- A report generator. One click from an analysis to a lender-ready or landlord-ready PDF, because the last mile of a business decision is usually a document someone else has to read.
(NOTE: the openrouter API key is for public use, but will expire in 7 days time)
Built With
- css
- data-visualization
- html5
- javascript
- local-storage
- openrouter
- python
- responsive-design
Log in or sign up for Devpost to join the conversation.