Paste a pile of customer reviews, support tickets or survey responses and get back a one-page insights report: the top themes, the sentiment behind each, roughly how often each shows up, a real customer quote, and a suggested action — ranked by what customers actually care about.
Think of a research assistant who reads 500 reviews overnight and hands you a single page saying "here are the five things that matter, in order."
Live: distil-feedback.vercel.app — hit Try it with sample data, then Analyse feedback, and a real report comes back in about 15 seconds.
- Paste or import — type into the box, or upload / drop a
.csvor.txtexport straight from Zendesk, Intercom or an app store. The engine picks the likeliest text column and lets you switch it. - Ranked themes with evidence — each theme carries sentiment, a 1–5 frequency meter, a lead quote and an expandable set of further real quotes, so a sceptical reader can check the machine's claims.
- Handles big batches — oversized inputs are split, analysed in pieces and merged into one report (map-reduce), instead of gambling on one call.
- Reports that travel — copy as Markdown, print to PDF, or share as a link: the whole report rides compressed inside the URL fragment, so there is nothing to store server-side.
- Memory — past reports are kept locally; reopen any of them, or read two side by side to see what changed between batches.
- A defended API — per-IP rate limiting, a global daily budget and an input cap keep the free-tier Gemini key safe on a public URL.
Raw feedback is noisy and nobody has time to read it. Translating the voice of the customer into something a product or business team can act on is the core of customer-facing analysis work — this tool automates the reading so a human can spend their time on the deciding.
- Frontend (React + Tailwind) — a single page: paste feedback, hit
analyse, read the report. State handled with
useState, the API call withasync/await+fetch. - Backend (Node + Express) — one endpoint,
POST /api/analyze. It holds the API key (which must never reach the browser) and asks Gemini to cluster the feedback into ranked themes. The Gemini free tier means the whole project runs at £0. - Structured outputs — the model answers against a JSON schema that mirrors CONTRACT.md, so the response is guaranteed to parse. No regex, no hoping.
The commit history is the project diary — each step was committed as it happened:
- Agree the contract first —
CONTRACT.mdpinned down the exact input and output shape before a line of code existed. - Build the empty shell — React, Tailwind, a hardcoded fake report, zero AI. Layout and styling settled early.
- Wire the AI — Express server + an async
fetchfrom the frontend, dumping the raw model answer on screen. - Make the output structured — JSON schema enforcement, parsed and rendered as a typeset report.
- Polish for the demo — loading state, error handling, and a one-click "try it with sample data" button.
Requires Node 22+.
npm install
cp .env.example .env # add your free GEMINI_API_KEY (aistudio.google.com/apikey)
npm start # API on :3001
npm run dev # frontend on :5173 (proxies /api to :3001)No API key yet? Set MOCK_AI=1 in .env and the server returns a canned
report so the full flow still works.
npm run build && npm startLocally, one process serves both the built frontend and the API.
The live site runs on Vercel: the built frontend is
served from its CDN, and api/index.js hands every /api request to the
same Express app as a function in the London region. Every push to main
redeploys. To run your own copy, import the repo into Vercel and set
GEMINI_API_KEY in the project's environment variables.
Swiss-editorial, on purpose: the output is literally a one-page report, so the UI reads like a typeset research memo — paper background, ink type, hairline rules, numbered findings and a single signal-red accent. Open Sans for text, IBM Plex Mono for labels and data. Dark mode is the same report printed on dark stock: it follows your OS, a header toggle overrides it, and printing always comes out on light paper.
React 19 · Vite · Tailwind CSS 4 · Node/Express 5 · Gemini API (gemini-3.5-flash free tier, structured outputs) · Vercel