Inspiration The average person generates roughly 4 tons of CO₂ per year — but has almost no visibility into which of their daily actions actually matter. Existing carbon footprint apps require manual data entry: search for "beef," pick a portion size, enter the quantity. It's tedious. It's why 90% of carbon tracking apps are abandoned within 3 days.

We asked a simple question: what if your camera was the sensor?

Snap a photo of your lunch, your receipt, or your electricity bill. Let AI figure out the carbon cost. Then let an AI coach — one that actually remembers you — tell you what to change next.

That's CarbonTrace.

What it does CarbonTrace turns a phone camera into a personal carbon sensor.

Snap — Upload or drag a photo of anything: a meal, a receipt, a commute, a utility bill. Gemini 1.5 Flash analyzes the image, identifies the item, and returns a structured carbon estimate with emission factors from peer-reviewed sources (Poore & Nemecek 2018 for food, EPA for transport). Every estimate includes a confidence score and 2-3 lower-carbon alternatives.

Track — Every entry is logged to a PostgreSQL time-series table with daily aggregates. The dashboard shows today, this week, and all-time totals alongside a rolling 14-day line chart and category breakdowns.

Coach — Ask the AI coach how you're doing. It cites your actual numbers, references memories from previous sessions ("I noticed you've had beef three times this week"), and always offers one concrete next step. Hit the voice button and hear it narrated by ElevenLabs.

The key differentiator: CarbonTrace has memory. Most AI apps are stateless — close the tab, lose the context. We use Backboard's persistent memory layer so the coach builds a real relationship with each user over time.

How we built it Frontend: Lovable-generated React app with Tailwind CSS, Recharts for visualizations, and a mobile-responsive green/teal gradient design system.

Backend orchestration: Supabase Edge Functions (Deno) handle all API calls so keys never touch the browser.

AI Vision: Gemini 1.5 Flash with structured JSON output via responseMimeType: "application/json" and a schema constraint — this guarantees valid parseable responses instead of the markdown-fenced garbage that raw prompting produces.

AI Text: Gemini 1.5 Pro for the coach, with a strict 80-word limit and a system prompt that enforces concrete numbers, no guilt-tripping, and one actionable next step.

Voice: ElevenLabs with the eleven_flash_v2_5 model and optimizeStreamingLatency=2, so briefing audio starts streaming within ~200ms of the request.

Memory: Backboard's REST API. Every logged entry triggers a remember() call. Every coach interaction retrieves context via recall(). The same assistant ID serves all users, with metadata scoping.

Data layer: Supabase PostgreSQL with time-bucketed aggregations. Our schema is designed so the same queries work directly on Tiger Data's extended PostgreSQL (TimescaleDB) — the migration path is a CREATE FOREIGN SERVER away.

Hosting: Lovable deployment + a custom domain from GoDaddy Registry.

Challenges we ran into

  1. Gemini returning malformed JSON. Raw prompting gave us markdown-fenced JSON roughly 30% of the time. The fix was switching to responseMimeType: "application/json" with responseJsonSchema — Gemini then respects the schema at the token-generation level, not the parsing level.

  2. Supabase Edge Functions + Deno + SDKs. The ElevenLabs SDK wouldn't resolve from esm.sh. The fix was using the npm: prefix in Deno imports. Similarly for the Gemini SDK — @google/genai works, google-generativeai (the Python package most tutorials reference) does not.

  3. Backboard's stateless-by-default trap. Every LLM API is stateless. Our first coach version forgot everything between messages. Backboard's memory API solved this, but the doc pattern (create assistant → use assistant_id on every call → scope by metadata) took some reverse-engineering.

  4. State management across sessions. Managing "is this a fresh upload or a re-analysis?" and "have we already logged this entry?" required tracking client-side state that survives page refresh. Supabase's localStorage helpers plus a demo=true flag on rows let us safely toggle demo mode without polluting real user data.

  5. Chart data was sparse. One data point makes a boring trend line. We built a demo mode that seeds 25 realistic entries across 14 days so judges immediately see the platform's value, and it toggles off cleanly to show real data.

Accomplishments that we're proud of Sub-3-second end-to-end flow: photo → Gemini analysis → Supabase insert → dashboard update, all in one tap.

Structured AI output that doesn't break. We get valid JSON every time, with confidence scores and alternatives, from a single prompt.

A coach that actually remembers. Not a chatbot gimmick — the memory is scoped, retrieved meaningfully, and cited in responses.

Real emission factors. 3.80 kg for a beef cheeseburger isn't a guess; it's grounded in published life-cycle analysis.

Multi-track coverage in one project. Environmental impact + AI vision + time-series data + voice synthesis + persistent memory, integrated meaningfully rather than bolted on.

A UI that non-technical users can actually use. No forms, no dropdowns, no manual data entry. Just a camera.

What we learned LLM structured output needs schema constraints, not just prompts. "Return JSON" is not enough. The API-level JSON mode is the difference between 70% reliability and 100%.

Stateless AI is a UX antipattern. Once you experience an AI that remembers context from three sessions ago, every other assistant feels broken.

Time-series data wants time-series queries. Writing GROUP BY date_trunc('day', time) in raw PostgreSQL is fine; continuous aggregates that update incrementally are a different league.

Edge Functions force good architecture. Having to declare every secret, every dependency, and every CORS header explicitly makes the security model visible and auditable.

Demo data is not cheating — it's storytelling. Judges need to see the value in 30 seconds. Real data can't always show that fast enough.

What's next for CarbonTrace Short term:

Camera capture directly in-browser (currently upload-only)

Receipt OCR for grocery-level detail (Gemini 1.5 Pro's long-context can handle a full receipt image)

Weekly email digests with voice briefing embedded

Medium term:

Migrate the time-series layer to Tiger Data for high-frequency ingestion and continuous aggregates at scale

Add Solana-based verified carbon offset purchases — logged entries earn credit toward on-chain offsets

Community features: leaderboards, shared goals, team challenges for corporate wellness programs

Long term:

B2B API for corporate ESG teams to measure employee commuting and travel footprints

Partnerships with sustainability-focused retailers to suggest lower-carbon alternatives at point of purchase

Digital twin of an individual's annual footprint with forecast modeling

Built With

  • lovable
Share this project:

Updates

Submission history