EcoTrace
Make sustainability part of your development pipeline.
EcoTrace is a VS Code extension that detects carbon-heavy web patterns in your code, shows CO₂ estimates per page load, and provides quick fixes — directly in your editor. It also ships a standalone CLI for use in CI/CD pipelines.
Features
- Inline diagnostics — squiggles on carbon-heavy patterns (images, videos, scripts, iframes, JS patterns)
- CO₂ estimates — based on actual local file sizes using the Sustainable Web Design model (0.25g CO₂/MB)
- Quick fixes — one-click fixes via the lightbulb menu (
Cmd+.)
- Grade system — A through F based on total CO₂ per page load
- Session tracking — shows grade change since you opened the file
- Save notifications — alerts when your grade improves or drops on save
- Carbon report — per-file breakdown with projected daily impact at different traffic levels
- Workspace dashboard — all files ranked by carbon cost
- Ignore comments — suppress specific rules inline
- CLI — run the same analysis outside VS Code, in terminals and CI pipelines
Rules
| Rule |
Severity |
How it's detected |
missing-lazy-load |
Warning |
<img> without loading="lazy" |
non-optimal-image-format |
Warning |
.png, .jpg, .jpeg, .bmp src attributes |
autoplay-video |
Error |
<video autoplay> without preload="none" |
render-blocking-script |
Warning |
<script src> without defer, async, or type="module" |
iframe-lazy-load |
Warning |
<iframe> without loading="lazy" |
google-fonts-multiple |
Warning |
More than one @import from fonts.googleapis.com |
aggressive-interval |
Info |
setInterval with interval < 100ms |
full-lodash-import |
Info |
import _ from 'lodash' |
missing-remove-listener |
Info |
addEventListener with no matching removeEventListener |
console-log |
Info |
console.log( in JS/TS files |
Grade thresholds
| Grade |
CO₂ per load |
| A |
0g |
| B |
< 0.5g |
| C |
< 1.0g |
| D |
< 2.0g |
| F |
≥ 2.0g |
CO₂ methodology
- Transfer-based rules (images, video, scripts, iframes): actual file size is read from disk via
fs.statSync. If the file can't be resolved locally (external URL, not found), a fallback average is used.
- Format waste (PNG/JPEG → WebP): waste =
fileSize × FORMAT_WASTE_RATIO (PNG saves 70%, JPEG saves 30%)
- Behaviour-based rules (CPU/memory): fixed estimates since they're not data-transfer based
- Model: Sustainable Web Design — 0.25g CO₂ per MB transferred
Fallback sizes used when file can't be resolved:
| Asset |
Fallback |
| Image |
200KB |
| Video |
3MB |
| Script |
80KB |
| iframe |
500KB |
Ignoring rules
Add an ignore comment on the same line or the line above:
<!-- ecotrace-ignore: missing-lazy-load -->
<img src="https://github.com/carbonscript-xyz/ecotrace/raw/HEAD/hero.png" />
<img src="https://github.com/carbonscript-xyz/ecotrace/raw/HEAD/hero.png" /> <!-- ecotrace-ignore: missing-lazy-load -->
// ecotrace-ignore: console-log
console.log("debug");
Commands
| Command |
Description |
EcoTrace: Show Carbon Report |
Per-file report with grade, CO₂/load, session diff, and traffic projections |
EcoTrace: Show Workspace Dashboard |
All files in the workspace ranked by carbon cost |
EcoTrace: Fix All Auto-fixable Issues |
Applies all quick fixes in the active file at once |
CLI
The same analysis engine is available as a standalone CLI — no VS Code required. Use it in terminals, pre-commit hooks, and CI pipelines.
Usage
node dist/cli.js <files...> [options]
After publishing to npm:
npx ecotrace-cli <files...> [options]
Options
| Flag |
Description |
--threshold, -t <grade> |
Fail (exit 1) if any file is below this grade |
--format, -f <text\|json> |
Output format (default: text) |
--root, -r <path> |
Workspace root for resolving root-relative asset paths |
--quiet, -q |
Only print files with issues |
--no-color |
Disable ANSI colours |
Examples
# Basic scan
node dist/cli.js src/index.html
# Fail CI if any file is below grade C
node dist/cli.js src/**/*.html src/**/*.ts --threshold C
# JSON output (for dashboards or parsing)
node dist/cli.js src/**/*.html --format json | jq '.files[0].grade'
# Only show files with issues
node dist/cli.js src/**/*.html --quiet --threshold B
Exit codes
| Code |
Meaning |
0 |
All files pass the threshold (or no threshold set) |
1 |
One or more files below threshold, or no files provided |
GitHub Actions
name: EcoTrace
on: [push, pull_request]
jobs:
eco-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
- run: npx ecotrace-cli src/**/*.html --threshold C
Local testing (before publishing)
cd ecotrace
pnpm run compile
node dist/cli.js src/index.html --threshold B
Project structure
src/
analyzer.ts — pure analysis engine (no VS Code dependency)
shared by both the extension and CLI
extension.ts — VS Code extension, wraps analyzer with vscode APIs
cli.ts — standalone CLI entry point
dist/
extension.js — bundled extension (loaded by VS Code)
cli.js — bundled CLI (executable, has #!/usr/bin/env node)
Development
pnpm install
pnpm run compile # type-check + lint + build both extension and CLI
pnpm run watch # watch mode for extension development
pnpm run check-types # TypeScript type check only
Press F5 in VS Code to launch an Extension Development Host for testing.
Roadmap
- [ ] CLI published to npm as
ecotrace-cli
- [ ] Bundle size analysis (webpack/vite stats integration)
- [ ] Grid carbon intensity — weight CO₂ by deployment region (Electricity Maps API)
- [ ] Third-party script scoring (GTM, HubSpot, Intercom, etc.)
- [ ] Unused CSS detection
- [ ] Historical tracking — CO₂ delta across git commits