Inspiration
The prompt asked for a future where clean energy is "easier, more affordable, and more accessible for everyone" — and the more we looked at how people actually try to electrify their homes today, the clearer it became that the sticker price was never the real barrier. The real barrier is invisible friction: not knowing which appliance to replace, not knowing what it costs installed, not knowing which rebates you even qualify for, not knowing that claiming them means three specific documents and a 45-minute form, and — if you rent — not knowing you can't act on any of it without your landlord anyway. Existing tools show you a subsidy amount. None of them show you the paperwork behind it, the payback math against your actual utility rate, or whether the upgrade is even yours to make. We wanted to build the thing that does — essentially "TurboTax for clean energy electrification."
What it does
EcoStep turns a zip code and a few photos into a phased, personalized electrification roadmap:
- Onboarding captures your zip code, home type, current/target monthly bill, and preferences, and immediately computes a EcoScore — a 0–100 measure of how clean your home's energy footprint is, blending your local grid's cleanliness, a solar-ownership bonus, and credit for upgrades you've accepted.
- Scan appliances with your camera — a two-shot capture (a context photo, then a close-up of the spec/label plate) is sent to Gemini, which reads the label and returns structured specs. Manual entry (or gallery upload) is always one tap away, and kicks in automatically after repeated unreadable scans.
- Suggestions arrive tiered (quick wins → structural upgrades), sortable by price, efficiency, or savings, each with a rebate popup showing the real incentive amount, an official government/utility source link, and eligibility — plus a separate paperwork popup breaking down exactly which documents are required and how many hours each takes.
- Upload your utility bill (photo or PDF, also read by Gemini) and every suggestion's savings estimate switches from a generic assumption to your actual electricity rate, with a real cash-positive/payback verdict per appliance and a 24-month projected-savings / energy-conserved chart on a dedicated Progress page.
- Home-tenure awareness: if you're in an apartment, EcoStep flags which upgrades are "landlord-controlled" versus genuinely yours to make, and downweights them in your roadmap instead of recommending a furnace swap to someone who can't legally install one.
- Everything works fully as a guest (local-only); signing in (optional, Supabase-backed) syncs the same roadmap across devices.
How we built it
Stack: Next.js 16 (App Router, Turbopack) + TypeScript + Tailwind v4, Supabase (Postgres + Auth) for optional accounts, Gemini (@google/genai) for every vision task, Framer Motion for the animation layer.
The core design principle was keeping all reasoning as pure, unit-tested functions decoupled from the UI (lib/intelligence/, utils/), so three of us could build against the same data shapes in parallel without stepping on each other's rendering code. The EcoScore, for instance, is a simple additive model:
$$ \text{EcoScore} = \operatorname{clamp}!\left( G_{\text{zip}} \;+\; 15 \cdot \mathbb{1}[\text{solar}] \;+\; \operatorname{clamp}!\left(\sum_{i} \frac{e_i}{100} \cdot T_{\text{tier}_i},\ 0,\ 45\right), \ 0,\ 100 \right) $$
where $G_{\text{zip}}$ is the local grid's cleanliness baseline (0–40), and each accepted upgrade $i$ contributes its conversion efficiency $e_i$ weighted by its tier ($T \in {5, 10, 15}$). Affordability per suggestion follows the same pattern — a bill-adjusted score built from net cash impact, payback speed, and budget fit:
$$ \text{score} = \operatorname{clamp}!\Big( 50 \;+\; 1.5\,\Delta_{\text{monthly}} \;+\; \max(0,\ 36 - m_{\text{payback}}) \;+\; b_{\text{budget}}, \ 0,\ 100 \Big) $$
$$ b_{\text{budget}} = \begin{cases} +15 & \text{if net upfront cost} \le \text{budget} \ -15 & \text{otherwise} \end{cases} $$
Gemini shows up twice, both times as structured extraction, not conversation — once turning an appliance label photo into a typed AuditResult via a response-schema-constrained call, and again turning a utility bill (image or PDF, same code path) into a typed set of usage/rate fields that feed directly into the affordability math above. Neither is a chatbot; both are the model doing OCR-plus-reasoning that would otherwise require a human filling out a form.
We worked as three people on three branches (dev1-frontend-ui, dev2-backend-ai, dev3-data-logic), regularly reconciled into a shared test branch using isolated git worktrees — letting merge conflicts get resolved deliberately (keeping both people's features, never silently dropping one) without disturbing whoever was still actively editing the main working copy.
Challenges we ran into
- The classic controlled-input trap.
Number(e.target.value) || 0on a number input snaps to"0"on every keystroke, making a field impossible to clear before typing a new value — we independently reintroduced this bug in three separate forms before standardizing a fix (string state, blur-time normalization,step="any"so decimals don't silently block submission). - Dark mode was quietly broken app-wide. Tailwind v4's
dark:variant defaults toprefers-color-scheme, not whatever the in-app Light/Dark toggle sets — so every dark-themed class had been responding to the OS setting, not the app's own switch, this whole time. Found by literally screenshotting dark mode and eyeballing it, fixed with a custom variant plus resolving "System" to an explicit value with a livematchMedialistener. - An invalid color token, eight times over.
brand-150/brand-950were referenced across the app but never defined in the theme — Tailwind silently generated no CSS for them, leaving dark-navy text sitting on a fully transparent box over a near-black page. Only caught by inspecting computed styles directly, not by looking at the code. - Gemini model churn mid-build — an earlier Gemini model was retired for new API keys partway through, forcing a same-day migration plus a fallback chain that automatically retries across several model versions if one is unavailable.
- Windows + Turbopack + deep temp paths don't mix — merge work had to happen in short-path git worktrees (
C:\eco-test-wt) to avoidMAX_PATHbuild failures.
Accomplishments that we're proud of
- Taking incentive data that used to just say "$350 rebate" and making it say which three documents, how many hours, by what deadline, from which official source — the single change most directly answerable to "more accessible."
- Replacing generic savings assumptions with real math against a bill the user actually uploaded.
- Telling renters the truth: which upgrades are genuinely theirs to make, instead of a roadmap they have no power to execute.
- A guest-first design where an account is purely additive, never a gate.
- Three people, one shared branch, zero lost work — the unglamorous kind of accomplishment that's easy to skip celebrating.
What we learned
- Schema-constrained structured extraction is a fundamentally better fit for "AI in a real product" than chat — the same pattern read an appliance nameplate and a utility bill equally well, because in both cases we already knew the shape of the answer we needed.
- Contrast and color-token bugs hide extremely well in code review; they only show up when you actually render the target theme and look — or better, measure computed styles.
- Keeping calculation logic pure and tested, separate from components, is what made a three-person hackathon merge survivable at all.
What's next for EcoStep
- Ship the backend intelligence that's already built and tested but not yet wired into the UI: neighborhood buying circles (group-discount matching with nearby households), outage resilience planning (battery/backup sizing against your critical loads), and an AI coach that proactively nudges you toward your next best action.
- Replace the curated static incentive table with a live, continuously updated incentives database/API.
- Let users request contractor quotes directly from an accepted roadmap step.
- Deepen home-eligibility modeling — HOA rules, condo boards, historic-district restrictions — so the "who can actually act on this" logic gets as sharp as the financial math already is.
Built With
- eslint9
- googlegemini
- react19
- reactcontext
- supabase
- tailwindcss
- typescript
- vercel
- vitest


Log in or sign up for Devpost to join the conversation.