DEV Community

Jeremiah Say
Jeremiah Say

Posted on

Building a zero-dependency carbon calculator platform — architecture decisions and why I rejected every framework

When I started building GreenCalculus — a carbon calculator platform
for sustainability officers and CSRD compliance teams — the first
decision wasn't which framework to use. It was whether to use one at all.

I chose not to. Here's why, and what I built instead.

The problem with frameworks for calculation tools

Carbon calculators have a specific job: take a number in, multiply it
by an emission factor, output a result in tCO₂e. That's it.

The interaction model is:

  1. User selects fuel type
  2. User enters quantity
  3. User clicks Calculate
  4. Result appears instantly

There is no routing. There is no global state. There is no component
tree. There is no reason to ship 40kb of runtime to do three
multiplications.

React, Vue, and Svelte are excellent tools. They're the wrong tool
for this job.

What "zero dependencies" actually means

No npm. No bundler. No node_modules. No build step.

The entire calculator is:

  • One HTML file
  • CSS in a <style> block
  • JavaScript in a <script> block
  • Served directly from GitHub Pages

A user on a slow 3G connection in a developing market — where carbon
accounting is growing fastest — loads the calculator in under a second.
There is nothing to parse except the page itself.

This also means zero supply chain risk. No dependency vulnerabilities.
No breaking changes from upstream packages. No npm audit with 47
moderate severity warnings.

CSS @layer architecture

The stylesheet uses the CSS @layer cascade system:

@layer base, layout, components, interactive;
Enter fullscreen mode Exit fullscreen mode

This gives explicit control over specificity without fighting the
cascade. @layer base sets design tokens and resets. @layer layout
handles the 2-column dashboard grid. @layer components styles
individual UI elements. @layer interactive handles state changes.

The result: zero !important declarations in the entire codebase.

Fluid typography with clamp()

Every font size is fluid:

font-size: clamp(1.25rem, 3vw, 1.75rem);
Enter fullscreen mode Exit fullscreen mode

No breakpoint-based font size overrides. No separate mobile stylesheet.
The layout responds smoothly across every viewport without a single
media query for typography.

The design brief calls for GreenCalculus to feel like a "premium
scientific instrument." Fluid type that never jumps or breaks is part
of that feel.

JetBrains Mono + tabular-nums for number stability

This one is underrated. Carbon calculator outputs update in real time
as users type. Without tabular-nums, the result value shifts
horizontally as digits change width — it looks broken even when the
math is correct.

.result-value {
  font-family: 'JetBrains Mono', monospace;
  font-variant-numeric: tabular-nums;
}
Enter fullscreen mode Exit fullscreen mode

Every digit is now the same width. The number is rock-steady during
updates. On a platform where numerical precision is the entire value
proposition, this matters.

2-column dashboard layout — inputs left, results right

B2B sustainability tools are used by people who live in dashboards.
The layout mirrors that mental model:

.gc-calc {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.5rem;
  align-items: start;
}
Enter fullscreen mode Exit fullscreen mode

Left panel: inputs (fuel type, quantity, reporting period).

Right panel: results (tCO₂e output, calculation breakdown, source).

The user never loses sight of their inputs while reading the result.
No scrolling required. No modal. No separate results page.

On mobile it collapses to single column via one media query.

Logical properties for internationalisation

All spacing uses CSS Logical Properties:

margin-block-end: 1.25rem;
padding-inline: 1.5rem;
Enter fullscreen mode Exit fullscreen mode

Instead of margin-bottom and padding-left/right. This is future-proofing
for RTL language support (Arabic, Hebrew) without a single line of
additional CSS. GreenCalculus will eventually serve markets where RTL
is the default — the architecture supports it from day one.

The calculation engine

The core formula for every GHG Protocol Scope 1 calculator:
Emissions (tCO₂e) = Activity Data × Emission Factor × GWP

In JavaScript:

const kg = quantity * FACTORS[fuelKey].factor;
const annualKg = kg / reportingPeriodFraction;
const annualTonnes = annualKg / 1000;
Enter fullscreen mode Exit fullscreen mode

That's the entire calculation. Three lines. No library needed.

Emission factors come from UK DESNZ 2024. GWP values are IPCC AR6
GWP-100 — not AR5. The difference matters: fossil methane GWP is 29.8
under AR6, versus 25 under AR5. A 19% understatement if you're using
old values.

The full open dataset is published separately:

greencalculus/greencalculus-methodology

Precision and rounding rules

Raw outputs are computed to full floating-point precision. Rounding
is applied only at the display step:

const display = annualTonnes >= 1
  ? annualTonnes.toFixed(2)   // results >= 1t: 2 decimal places
  : annualTonnes.toFixed(4);  // results < 1t: 4 decimal places
Enter fullscreen mode Exit fullscreen mode

Never round intermediate values. Always round display values. This
is the GHG Protocol precision standard applied in code.

What I would use a framework for

To be clear: this isn't a framework vs no-framework manifesto.

I would use React or Vue for:

  • A multi-step emissions inventory wizard with complex state
  • A comparison tool pulling live data from multiple APIs
  • A reporting dashboard with filterable tables across 15 Scope 3 categories

For a single-purpose calculation tool with one input → one output,
Vanilla JS is the correct choice. Match the tool to the job.

Live demo

The Scope 1 stationary combustion calculator is live on GitHub Pages:

greencalculus.github.io/greencalculus-calculator-demo

Source is open — MIT licensed:

greencalculus/greencalculus-calculator-demo


The platform is still being built. This is the first calculator of
many. If you're working in sustainability tech or have questions on
the GHG Protocol methodology, I'm happy to discuss in the comments.

Top comments (0)