Inspiration

Most analytics tools ask you to become a data engineer before they give you a single answer. Upload here, configure there, learn the query language, wire the charts, wrangle the filters — and the insight you actually opened the file for is somewhere on the far side of an afternoon of setup.

We wanted the opposite: open a file, say what you want, and watch it happen — and do all of it in the browser, so your data never has to trust a server it can't see. GPT‑5.6 made that flip believable, because for the first time the same model can both reason about the architecture and live inside the product, authoring SQL, charts, and prose at runtime.

What it does

Data Lens turns a raw spreadsheet into a living analytics workspace without a server.

  • Ask, don't configure. A goal‑driven AI agent understands natural language and drives the whole app through a typed capability registry (search → call → execute code → ask) to build dashboards, apply cross‑filters, write reports, and run SQL.
  • One central widget system. Every KPI, chart, gauge, slicer, table, and AI card is a single WidgetInstance rendered through one adapter — so every widget shares the same chrome: configure, change type, maximize, "ask AI," and "add to report."
  • Cross‑filter that crosses files. Automatic relationship detection finds join paths, so clicking one chart filters every widget across multiple loaded files.
  • AI Insight widget. From one sentence, the model writes SQL and an HTML template; results bind to the live filter and the sandboxed card re‑renders as you filter.
  • Vision in the loop. Attach a screenshot of any widget/dashboard/report to the chat — or let the agent call a ui.screenshot capability — and the model sees the chart and interprets it.
  • Report studio. A block editor (paragraph, heading, divider, chart, table, AI‑Insight, and an AI Writer block that drafts prose from your data) with reordering, add‑anywhere, and a clean print/PDF export.
  • SQL Lab, reimagined. Describe a question; GPT‑5.6 writes multi‑table SQL across everything you've loaded. Each query is a saved card with stored results; materialize it as a view and attach any widget (including AI Insight), then push it to a report.
  • Multi‑provider, your key. OpenAI (GPT‑5.6), Google AI Studio (Gemini), Vertex AI, and local Ollama through one OpenAI‑compatible client.

Privacy is the default: your data stays in the browser (DuckDB‑WASM + IndexedDB). Only your prompts and, when you choose, a screenshot ever leave.

How we built it

The data layer is DuckDB‑WASM — a real analytical database compiled to WebAssembly, running inside the tab. Files become tables via CREATE TABLE … AS SELECT * FROM read_parquet(...) and queries run locally at column‑store speed. The UI is React + Vite + TypeScript, with the WASM bundle loaded from a CDN to keep the deploy lean.

We built it as an agentic engineering loop with Codex, with GPT‑5.6 doing the reasoning: read the real codebase, plan, edit across many files, run npm run build + vitest, read the failures, and fix them — a green build and passing tests at every checkpoint (87 tests). GPT‑5.6 owned the hard architecture calls — unifying two conflicting filter mechanisms into one central cross‑filter, designing the capability registry the product's own agent depends on, and the "materialize query → view → attach widgets" model in SQL Lab. And GPT‑5.6 ships inside the product too: it authors SQL, HTML insight cards, and report prose at runtime, and reads charts via vision.

Challenges we ran into

  • Two filters fighting each other. A per‑chart drill and a global cross‑filter produced a confusing, stuck state. The fix wasn't more code — GPT‑5.6's call was to collapse them into one central model. Good architecture is usually a subtraction.
  • Reactive, model‑authored cards. Letting the model design an HTML card and keep it live under filtering meant binding generated SQL to a filter‑aware data view and rendering safely in a sandboxed iframe.
  • Provider protocol quirks. Vision formats differ — a local model wanted its image as a raw base64 images array while the cloud API wanted an image_url object. We handle both behind one client.
  • Shipping constraints. Keeping the production bundle under the host's size limit (loading DuckDB‑WASM from a CDN) and making the whole thing usable on mobile — wrapping tabs, tappable widget controls, a compact landing.

Accomplishments that we're proud of

  • A 100% in‑browser analytics studio where private data never leaves the machine, yet AI still does the heavy lifting.
  • One widget model, one filter model — consistency you can feel, engineered on purpose.
  • The AI Insight card: the moment a spreadsheet stops being a grid and starts being a briefing that recomputes as you filter.
  • Four surfaces — Files, Dashboard, Report, SQL Lab — that stop being tabs and become a pipeline.
  • A disciplined build: 87 passing tests, green at every step.

What we learned

  • When a model can both design the system and operate inside it, the right move is often to remove mechanisms, not add features — fewer moving parts, more trust.
  • Typed capabilities beat free‑form function guessing: giving the agent a searchable, typed registry made its behavior observable and safe.
  • Privacy and capability aren't a trade‑off — DuckDB‑WASM proves you can keep data local and still be genuinely powerful.
  • Vision changes the conversation: letting the model see a chart turns "explain this query" into "explain this picture."

What's next for Data Lens — the in‑browser, AI‑native analytics studio

  • Shareable, publishable dashboards & reports (export/embed) while keeping the local‑first guarantee.
  • More data sources (databases, APIs, larger Parquet) and smarter automatic relationship detection.
  • Deeper agent autonomy — scheduled refreshes, saved "analysis recipes," and multi‑step narratives.
  • Collaboration — comments and annotations on widgets and report blocks.
  • Broader model support and on‑device models for a fully offline, private analyst in your browser.

Open a file. Say what you want. Watch it happen.

Built With

  • codex
  • duckdb
  • echart
  • gpt5.6
  • indexeddb
  • react
Share this project:

Updates