Vibe coding a visualisation for historical AQI trends
A research experiment with Claude Code and Codex
The premise
I have been a long-time admirer of Our World in Data and the book Factfulness. While mainstream media optimises for clickbait that showcases the direness of our existence, these two make a data-driven case for how this is the best time to be alive.
I love Delhi but am disappointed every year when we don’t take any measurable steps to curb the menace of air pollution.
As a pragmatic optimist, I wanted to study how air pollution has trended historically across major cities of the world. And more importantly, what they did to fix it.
So I vibe coded a historical AQI tracker for 8 cities (across 6 pollutants) that have successfully combated air pollution. It shows how the concentration of pollutants has trended over the last several years and also plots key policy interventions that potentially drove the improvement.
This research served two purposes:
It gave me hope that things will get better
The entire building experience was super-fun
Notes on building
Link to GitHub
I wanted to build a data journalism-style site that tracks historical air quality across 8 cities, 6 pollutants, and up to 70 years of data for some cities.
I vibe coded the entire thing in ~4 days with Claude Code and Codex. This was my first time using agentic AI tools to build and deploy a site end-to-end.
I have always been an amateur coder and my side projects in the pre-LLM era relied heavily on cloning GitHub repos, copying and editing source code from inspiration websites and scouring through Stack Overflow for solving maddening bugs. Most of the issues that I faced then were more to do with plumbing than the actual coding logic. Installing the right packages, structuring files correctly, and deployment overheads.
Claude Code and Codex, with their repo-level access, make this a breeze. They helped me focus more on the problem solving and the experience.
Claude Code is the better architect. It is great at taking a vision and fleshing it out. It works amazingly well in plan mode to create an elaborate context document, chart out the steps that it will take, and makes great architecture and tooling decisions.
The only constraint that I have faced with Claude Code is that it has a fairly small limit on the Pro plan, which makes it hard to work in long sessions on a single problem.
Codex came in handy when Claude Code hit its limit. Overall, I found it to be the better machinist. Precise, fast, and reliable for isolated fixes like tooltip clipping or restructuring a component without breaking six other things.
The stack is minimal. React 18, Vite, Tailwind, Recharts. Deployed on Vercel.
The design language is editorial, not dashboard. I took inspiration from Our World in Data. Everything fits in one viewport. Seeing the chart and the interventions at the same time helps establish the relationship between policy and possible outcome.
The project has 96 commits. I didn’t write a single line of code myself.
33 of the 65 commits are authored by Claude Code. The rest were through Codex.
I was writing prompts, reviewing pull requests, pushing back on implementation choices, and deciding what “done” looked like. Claude and Codex were writing React components, building data transparency features, and fixing mobile bugs.
The most useful thing I did was ask Claude to write a brutal critique of my own site. What would a researcher say? What would a data journalist say? What would Twitter say? The critique helped improve the site significantly. Some examples:
Inadequate citations.
Implied causation. Markers on intervention years strongly suggest those policies caused the improvements. But air quality is multi-factorial.
Survivorship bias. I’d only picked cities where things got better.
Geographic bias. Zero cities from Africa, South America, or the Middle East.
Interpolated data displayed identically to measured data.
Claude then built every fix into the site.
Proper source attribution so every number is traceable.
Causation-vs-correlation disclaimers in the sidebar.
A selection bias disclosure that tells you upfront: this dataset is not representative. It lists what’s missing and warns about success-oriented bias.
Interpolated data now renders as hollow circles with dashed lines and an “Est.” badge in tooltips.
Desktop site was fairly straightforward. But perfecting the mobile experience took a fair bit of work.
I wrote a full CLAUDE.md spec with breakpoint architecture, desktop protection rules, and a regression checklist. I had to explicitly instruct it to consider the desktop to be frozen and focus on mobile-only.
31 pull requests later, including multiple reverts and redos, the mobile experience works.
The experience reinforced what I wrote in How to ask?. Now the constraint is specification and taste. Can you describe what you want with enough precision? Can you tell when the output is wrong, not syntactically, but conceptually? These are fundamentally different skills from writing code, and they draw on a different kind of expertise.

