(Draft) What I've learned building VSCarbon
Published at Aug 21, 2025
Learning by building is exciting in the way that I figure things out as I go, feeling like I’m on a quest as each level requires new skills.
Full development cycle
Design pattern
- Adapter. When interest arises, there’s a need to extend VSCarbon to EU countries. It means I have to integrate other APIs (e.g., Electricity Maps, Carbon Aware Computing), creating a new strutural challenge. Luckily, someone recommended adapter pattern. Instead of rewriting core logic for each provider, I can abstract data layer (this feels deja vu because a CTO mentioned abstraction as a way to deal with business diversity in a job interview).
- I was worried it’s gonna be heavy for a VS Code extension because it sounds like big enterprise-y layers, but in my case, it looks less like design pattern boilerplate and more like a simple translation function per API.
Anw, I can define a common interface like this
type CarbonData = {
timestamp: string
region: string
carbonIntensity: number // gCO2/kWh
generationMix?: Record<string, number> // sadly some APIs don't provide energy mix
}
Adapters here are functions that normalise responses. I can add more providers later without changing much UI/logic. So, it’s a cleaner way to avoid if (provider === “UK”) else if (“EU”) everywhere
// National Grid adapter for UK users
export async function fetchUKCarbonData(): Promise<CarbonData[]> {
const res = await fetch('https://api.carbonintensity.org.uk/regional')
const json = await res.json()
return json.data.map((region: any) => ({
timestamp: region.from,
region: region.shortname,
carbonIntensity: region.intensity.actual,
generationMix: region.generationmix.reduce(
(acc: any, g: any) => ({ ...acc, [g.fuel]: g.perc }),
{}
)
}))
}
// Otherwise Electricity Maps adapter for EU/global users
export async function fetchEUCarbonData(countryCode: string): Promise<CarbonData> {
const res = await fetch(
`https://api.electricitymap.org/v3/carbon-intensity/latest?zone=${countryCode}`,
{ headers: { 'auth-token': process.env.ELECTRICITYMAP_TOKEN! } }
)
const json = await res.json()
return {
timestamp: json.datetime,
region: json.zone,
carbonIntensity: json.carbonIntensity,
generationMix: json.productionMix
}
}
Privacy
Instead of detecting user location (which may be inaccurate due to devs using VPN), I let users input their regional postcode (more private and practical as well)
Performance, SEO
Writing
Promoting
and I’m grateful that VSCarbon is receiving interest and support beyond the UK.