npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

ai-footprint

v0.1.0

Published

Deterministic CO2 and energy impact calculator for AI inference calls

Readme


Why ai-footprint?

Most libraries rely on opaque vendor estimates. ai-footprint is intentionally input‑driven: you provide measurable facts (power draw, parameters, region, throughput), and it returns a deterministic estimate.

Use cases

  • Carbon reporting and sustainability dashboards
  • Comparing model configurations and batch sizes
  • Batch/weekly/monthly footprint reporting
  • Research or internal cost/impact analysis

Table of Contents


Features

  • Deterministic, input‑driven estimation
  • Model‑type specific usage metrics (tokens, audio seconds, pixels, images)
  • Returns kWh and grams of CO2
  • TypeScript‑first API
  • Extensible categories and region grid‑intensity mapping
  • Optional advanced inputs (measured time, PUE, power breakdown, quantization metadata)
  • Batch aggregation for weekly/monthly totals
  • Uncertainty ranges for min/max emissions

Install

npm install ai-footprint

Quickstart

import { estimateImpact, usage } from "ai-footprint";

const result = estimateImpact({
  gpuPowerW: 350,
  modelParamsB: 70,
  region: "eu",
  usage: usage.chat(1200, 400),
  throughput: {
    tokensPerSecond: 90
  }
});

console.log(result.energyKwh, result.co2Grams);

Core Concepts

What you provide

  • Hardware: GPU power draw in watts (average during inference)
  • Model: parameter count (e.g., 7B, 70B)
  • Region: location or explicit grid carbon intensity (gCO2/kWh)
  • Workload metrics: based on model type (tokens, seconds, pixels, etc.)

What you get

  • Energy (kWh) used by the request
  • Emissions (gCO2) for the energy used

Model Categories

The library uses categories aligned with common API types:

  • chat.completions — input + output tokens
  • text.completions — input + output tokens
  • embeddings — input tokens only
  • ocr — input + output tokens
  • audio.transcription — seconds of audio processed
  • audio.translation — seconds of audio processed
  • audio.speech — seconds of audio generated
  • image.generation — pixels + number of images

Regions, Aliases, and Fallbacks

The library accepts a region string and normalizes it. If a region is not recognized, it falls back to the global average and prints a warning in the console.

Supported base regions with per‑country values

  • global, eu, us, uk
  • fr, de, it, es, nl, se, no, fi, ca, jp, sg, au, in, br
  • at, be, ba, bg, hr, cy, cz, dk, ee, gr, hu, ie, xk, lv, lt, lu, mt, me, mk, pl, pt, ro, rs, sk, si, ch, tr

Common aliases (normalized)

  • gb, united kingdomuk
  • usa, us-east, us-west, us-centralus
  • eu-west, eu-central, europe, eu (ember)eu

Name‑based aliases from the dataset

  • czechiacz
  • switzerlandch
  • turkeytr
  • kosovoxk
  • north macedoniamk
  • montenegrome
  • serbiars
  • bosnia and herzegovinaba

Additional country codes (mapped to global)

  • ae, ar, bd, cl, cn, co, dz, eg, hk, id, il, ke, kr, ma, mx, my, ng, nz, pe, ph, pk, sa, th, tw, vn, za

If you want exact local values, pass gridCarbonIntensityGPerKwh directly.


Examples

Minimal: embeddings

import { estimateImpact, usage } from "ai-footprint";

const result = estimateImpact({
  gpuPowerW: 250,
  modelParamsB: 7,
  region: "us",
  usage: usage.embeddings(1800),
  throughput: { tokensPerSecond: 300 }
});

Minimal: audio transcription

import { estimateImpact, usage } from "ai-footprint";

const result = estimateImpact({
  gpuPowerW: 300,
  modelParamsB: 1.5,
  region: "uk",
  usage: usage.audioTranscription(120),
  throughput: { audioSecondsPerSecond: 0.5 }
});

Minimal: image generation

import { estimateImpact, usage } from "ai-footprint";

const result = estimateImpact({
  gpuPowerW: 320,
  modelParamsB: 20,
  region: "de",
  usage: usage.imageGeneration(1024, 1024, 2),
  throughput: { pixelsPerSecond: 120000 }
});

Measured latency (processing time overrides derived time)

import { estimateImpact, usage } from "ai-footprint";

const result = estimateImpact({
  gpuPowerW: 400,
  modelParamsB: 70,
  region: "us",
  processingTimeSeconds: 1.84,
  usage: usage.chat(1200, 400)
});

PUE (data center overhead)

import { estimateImpact, usage } from "ai-footprint";

const result = estimateImpact({
  gpuPowerW: 350,
  modelParamsB: 70,
  region: "eu",
  overheadFactor: 1.2, // use this as PUE if preferred
  usage: usage.chat(1200, 400),
  throughput: { tokensPerSecond: 90 }
});

Power breakdown (GPU + CPU + network)

import { estimateImpact, usage } from "ai-footprint";

const gpuPowerW = 300;
const cpuPowerW = 60;
const networkPowerW = 15;

const result = estimateImpact({
  gpuPowerW: gpuPowerW + cpuPowerW + networkPowerW,
  modelParamsB: 13,
  region: "fr",
  usage: usage.chat(800, 200),
  throughput: { tokensPerSecond: 120 }
});

Dynamic grid intensity

import { estimateImpact, usage } from "ai-footprint";

const result = estimateImpact({
  gpuPowerW: 350,
  modelParamsB: 70,
  gridCarbonIntensityGPerKwh: 210,
  usage: usage.chat(1200, 400),
  throughput: { tokensPerSecond: 90 }
});

Quantization, batch size, and efficiency factors

import { estimateImpact, usage } from "ai-footprint";

const result = estimateImpact({
  gpuPowerW: 220,
  modelParamsB: 70,
  region: "eu",
  usage: usage.chat(2000, 400),
  throughput: { tokensPerSecond: 240 }
});

Batch Aggregation

import { aggregateImpacts, estimateImpact, usage } from "ai-footprint";

const impacts = [
  estimateImpact({
    gpuPowerW: 350,
    modelParamsB: 70,
    region: "eu",
    usage: usage.chat(1200, 400),
    throughput: { tokensPerSecond: 90 }
  }),
  estimateImpact({
    gpuPowerW: 250,
    modelParamsB: 7,
    region: "us",
    usage: usage.embeddings(1800),
    throughput: { tokensPerSecond: 300 }
  })
];

const total = aggregateImpacts(impacts);
console.log(total.count, total.energyKwh, total.co2Grams);

Uncertainty Ranges

import { estimateImpactRange, usage } from "ai-footprint";

const result = estimateImpactRange(
  {
    gpuPowerW: 350,
    modelParamsB: 70,
    region: "eu",
    usage: usage.chat(1200, 400),
    throughput: { tokensPerSecond: 90 }
  },
  {
    gpuPowerW: { min: 300, max: 420 },
    pue: { min: 1.1, max: 1.4 },
    tokensPerSecond: { min: 70, max: 110 }
  }
);

console.log(result.energyKwhMin, result.energyKwhMax);
console.log(result.co2GramsMin, result.co2GramsMax);

Notes and Best Practices

  • Use measured processingTimeSeconds when available.
  • Prefer explicit gridCarbonIntensityGPerKwh if you can fetch it from a live data source.
  • If you don’t know throughput, you can still get a minimal estimate by assuming a conservative value.
  • If you pass an unknown region, the library will warn in console and fall back to global.

Data Source

The per‑country dataset is decoupled in src/data/grid-carbon-intensity.2025.json (year 2025).
Source: Our World in Data — https://ourworldindata.org/grapher/carbon-intensity-electricity


License

MIT