Inspiration
Most carbon footprint calculators ask a lot of you before they give anything back — long forms, vague sliders, numbers with no visible source. I wanted something closer to the opposite: point at something in your everyday life, get one honest number, and see exactly where that number came from. The idea for Carbonly started from a simple frustration — I'd see a carbon estimate somewhere online and have no idea if it was a real published figure or someone's rough guess. So the core design constraint became: every number in this app has to trace back to a link a user can click and verify themselves.
What it does
Carbonly lets you snap or upload a photo of a meal, journey, or energy use, confirm what it is, and instantly see a sourced CO₂e estimate — for example, \( 100\text{ g} \) of beef versus \( 100\text{ g} \) of tofu, or a car journey versus the same distance by rail. It then suggests a lower-impact swap within the same unit and category, so the comparison is always apples-to-apples. Logged choices roll up into a private, on-device monthly dashboard with a goal meter and a category breakdown, so the app isn't just a one-off calculator — it's meant to make patterns visible over time.
How I built it
Carbonly is deliberately framework-free: plain HTML, CSS, and vanilla JavaScript, packaged as an installable PWA with a manifest and a service worker for offline caching. The heart of the app is a single items object where every entry stores its emissions factor with its source unit intact — kilograms of CO₂e per kilogram, per vehicle-km, per passenger-km, per kWh — rather than silently normalizing everything into one unit behind the scenes. That was a conscious choice: normalizing early hides the assumptions, and I wanted the assumptions visible.
Food factors come from Poore & Nemecek's global life-cycle dataset via Our World in Data; travel and electricity factors come from the UK Government's greenhouse gas conversion factors. Because the food data is published per kilogram but the app deals in realistic 100 g portions, I divided every food factor by ten and documented that transformation directly in the README so nothing gets lost between "what the source says" and "what the app shows."
Challenges I ran into
The honest one: real photo recognition needs an external vision API and a server-side key, and Carbonly is a static, no-backend app by design. Rather than fake it or quietly bolt on a hidden key, I decided the app should be upfront about it — it captures and previews your real photo, but asks you to confirm what's in it rather than pretending to "see." That felt more honest than a magic-looking demo that would fall apart in real use.
The other recurring challenge was keeping comparisons meaningful across very different measurement bases — a car's per-vehicle-km factor isn't quite the same thing as a train's per-passenger-km factor, since occupancy changes the real-world number. Instead of hiding that nuance, I surfaced it directly in the UI copy next to the estimate, so the tool stays useful without overclaiming precision it doesn't have.
What I learned
Building the sourcing-first constraint into the data model from day one — rather than bolting citations on afterward — made the whole app easier to trust and easier to extend; adding a new comparison item is just one line with a link attached, not a separate research pass. I also learned a lot about the sharper edges of shipping a PWA: manifest correctness, icon requirements across platforms, and the offline-caching lifecycle are all more finicky than they look, and it's easy to build the supporting scaffolding (service worker, install prompts) without actually wiring it into the app's runtime behavior — a gap that's now on my list to close before the app is truly "installable" in practice.
What's next
Turning the currently-styled "Carbon Sprint" quiz into a working feature, properly registering the service worker for real offline support, and expanding the comparison library beyond the current eight items — while keeping the one rule that got the project this far: no number without a link.
Built With
- 5.6
- codex
- gpt
Log in or sign up for Devpost to join the conversation.