This is a submission for Weekend Challenge: Earth Day Edition
What I Built
Carbon Lens is an AI-powered carbon footprint tracker that lets you see the environmental cost of everything you buy. Point your camera at a grocery bag, upload a photo of a receipt, or type in a list of items — and Carbon Lens will instantly estimate the CO₂e footprint of each item, color-code them by impact level, and suggest lower-carbon swaps.
The goal: make carbon awareness as easy as taking a photo. Most people have no idea that a kilogram of beef produces ~27 kg of CO₂e while the same weight of tofu is only ~2 kg. Carbon Lens puts that information right at your fingertips, every time you shop.
Key Features
- Photo Scanning — Upload a receipt, product photo, or meal image. Gemini identifies every item and estimates its carbon footprint.
- Live Camera — Point your phone camera at items on a shelf or in your cart and tap Scan for instant analysis.
- Text Input — Type or paste a list of items (e.g. "1 kg chicken breast, 2 liters milk") for quick estimates.
- Smart Swap Suggestions — Every medium/high-impact item includes a lower-carbon alternative with exact kg CO₂ savings.
- Impact Badges — Color-coded 🟢 Low / 🟡 Medium / 🔴 High badges make it easy to spot the biggest offenders at a glance.
- Dashboard & Charts — Track your total carbon footprint over time with monthly trend charts and category breakdowns.
- Scan History — Browse all past scans with expandable details, swap suggestions, and AI-generated insights.
- BYOK (Bring Your Own Key) — Users can plug in their own Gemini API key for unlimited scanning. The key stays in your browser's localStorage and is sent directly to Google — it never touches our server.
- Dark Mode — Full light/dark theme support across every component.
Demo
Code
This is a Next.js project bootstrapped with create-next-app.
Getting Started
First, run the development server:
npm run dev
# or
yarn dev
# or
pnpm dev
# or
bun dev
Open http://localhost:3000 with your browser to see the result.
You can start editing the page by modifying app/page.tsx. The page auto-updates as you edit the file.
This project uses next/font to automatically optimize and load Geist, a new font family for Vercel.
Learn More
To learn more about Next.js, take a look at the following resources:
- Next.js Documentation - learn about Next.js features and API.
- Learn Next.js - an interactive Next.js tutorial.
You can check out the Next.js GitHub repository - your feedback and contributions are welcome!
Deploy on Vercel
The easiest way to deploy your Next.js app is to use the Vercel Platform from the creators of Next.js.
Check out our Next.js deployment documentation for more…
How I Built It
Tech Stack
| Layer | Technology |
|---|---|
| Framework | Next.js 16 (App Router, Turbopack) |
| Frontend | React 19, Tailwind CSS v4, shadcn/ui, Motion (animations), Recharts (charts) |
| AI |
Google Gemini (gemini-2.5-flash) via @google/generative-ai SDK |
| Database | MongoDB via Mongoose |
| Auth | Custom JWT sessions with jose (HS256, cookie-based) |
| State |
Zustand + custom usePersistedState hook for localStorage-backed state |
The Carbon Estimation Approach
Rather than just throwing images at Gemini and hoping for the best, I built a structured prompt system with embedded carbon reference data. The AI receives a set of 30+ carbon guidelines covering food, clothing, electronics, and transport:
- Beef: ~27 kg CO₂e per kg
- Chicken/Poultry: ~6.9 kg CO₂e per kg
- Tofu: ~2 kg CO₂e per kg
- Clothing (jeans): ~33 kg CO₂e per item
- Electronics (laptop): ~300-400 kg CO₂e
- Car fuel (1L gasoline): ~2.3 kg CO₂e
Gemini is instructed to return structured JSON with per-item carbon estimates, impact levels (low < 2 kg, medium 2-5 kg, high > 5 kg), and a suggested lower-carbon swap for every medium/high-impact item. This keeps the output consistent and parseable, even across wildly different inputs — from a crumpled grocery receipt to a photo of someone's lunch.
Three Prompt Strategies
I created three specialized prompts, each tuned for its input modality:
- Image Analysis — "Analyze this image — it could be a grocery receipt, a photo of products, a meal, clothing, electronics, or any item(s)." Handles the broadest range of visual inputs.
- Text Analysis — "Analyze this list of items and estimate the carbon footprint for each." Optimized for typed/pasted item lists.
- Live Camera — "You are an expert environmental analyst doing real-time carbon analysis. Look at this camera frame and identify ALL visible items." Prioritizes speed and focuses on the most prominent items in the frame.
All three share the same carbon guidelines and response format, so the frontend can render any result identically.
BYOK: Bring Your Own Key
Free-tier Gemini API keys have tight rate limits. Instead of asking users to wait, I built a Bring Your Own Key system:
// The useGeminiKey hook stores the key in localStorage via Zustand
export function useGeminiKey() {
const { state: key, setState: setKey } = usePersistedState<string>("", {
storageKey: "gemini-api-key",
});
return { key, setKey };
}
When a user provides their own key, it's sent via the x-gemini-key HTTP header. The server uses it directly with the Gemini SDK — the key never gets stored in the database. If the key is invalid or exhausted, the error handler classifies the failure and shows a contextual UI:
- Rate limited → Cooldown countdown timer on the scan button
- Zero quota → "This API key has no quota" with a link to get a new one
- Invalid key → "Update your API key" button
- No key → "Add your API key" prompt with a link to aistudio.google.com
Live Camera Optimization
Streaming full-resolution video frames to an AI API would be expensive and slow. The live camera component scales frames down to 640px max width and compresses to JPEG at 0.6 quality before sending:
const maxWidth = 640;
const scale = Math.min(1, maxWidth / video.videoWidth);
canvas.width = video.videoWidth * scale;
canvas.height = video.videoHeight * scale;
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
const dataUrl = canvas.toDataURL("image/jpeg", 0.6);
This keeps payload sizes manageable while retaining enough visual detail for Gemini to identify products and labels.
Rate Limit Resilience
When Gemini returns a 429 with retry in Xs, the API extracts the retry delay and passes it to the client. The UI then disables the action button and shows a live countdown:
{cooldown > 0 ? (
<>Wait {cooldown}s</>
) : (
<><Leaf className="h-4 w-4" /> Analyze Carbon Footprint</>
)}
I also added zero-quota detection to distinguish between "wait and retry" (transient rate limit) and "this key has no access" (permanent). The Gemini SDK returns limit: 0 in the error message for keys with no free-tier allocation — catching this prevents users from waiting forever for a retry that will never work.
Data Model
Each scan is stored as a Receipt document in MongoDB:
interface IReceiptItem {
name: string;
quantity: number;
unit: string; // "kg", "item", "liter"
category: string; // "meat", "dairy", "produce", "electronics", etc.
carbonKg: number;
impactLevel: "low" | "medium" | "high";
suggestedSwap?: string;
swapSavingsKg?: number;
}
The dashboard aggregates this data using MongoDB's aggregation pipeline to compute monthly trends, category breakdowns, and impact distributions — all served from a single /api/v1/receipts/stats endpoint.
Prize Categories
-
Best Use of Google Gemini — Gemini (
gemini-2.5-flash) is the core engine powering all carbon analysis. Three specialized prompts handle image, text, and live camera inputs, with structured JSON output, embedded carbon reference data, and multimodal image understanding. BYOK support lets users bring their own Gemini API key for unlimited use. - Best Use of GitHub Copilot — The entire project was built with GitHub Copilot as an AI pair programmer, from scaffolding components and writing API routes to debugging rate limit issues and optimizing camera frame handling.
United States
NORTH AMERICA
Related News
How Braze’s CTO is rethinking engineering for the agentic area
10h ago
Amazon Employees Are 'Tokenmaxxing' Due To Pressure To Use AI Tools
21h ago

Implementing Multicloud Data Sharding with Hexagonal Storage Adapters
15h ago

DeepMind’s CEO Says AGI May Be ~4 Years Away. The Last Three Missing Pieces Are Not What Most People Think.
15h ago

CCSnapshot - A Claude Code Configs Transfer Tool
21h ago