A Chrome extension that helps users make sustainable choices while shopping online.
- Node.js v22+
npm installThis also sets up Husky git hooks automatically via the prepare script.
npm run devRuns a clean build then starts three file-watchers (popup, content script, background worker) that rebuild their respective outputs into dist/ on every change.
Load the extension in Chrome once:
- Go to
chrome://extensions - Enable Developer mode (top-right toggle)
- Click Load unpacked and select the
dist/folder
After each rebuild, click the reload icon on the extension card in chrome://extensions to pick up the latest changes.
npm run buildProduces a production-ready bundle in dist/.
The extension uses a simple adapter pattern. Adding a new shopping site requires touching two files.
1. Create src/platforms/<name>.ts
import type { Platform } from "./platform"
export class MyShopPlatform implements Platform {
readonly id = "myshop"
readonly displayName = "MyShop"
// Return true when the current URL belongs to this site
matchesUrl(url: string): boolean {
return /myshop\.[a-z.]+/i.test(url)
}
// Return the product name from the DOM, or null if not on a product page
getProductName(): string | null {
const el = document.querySelector("h1.product-title")
return el?.textContent?.trim() ?? null
}
// Return the element the eco-badge should be inserted after
getInjectionPoint(): Element | null {
return document.querySelector("h1.product-title")
}
}2. Register it in src/platforms/index.ts
import { MyShopPlatform } from "./myshop"
const PLATFORMS: Platform[] = [
new AmazonPlatform(),
new EbayPlatform(),
new MyShopPlatform(), // ← add here
]3. Update public/manifest.json
Add the new domain to both host_permissions and content_scripts.matches:
"host_permissions": ["*://*.myshop.com/*"],
"content_scripts": [{ "matches": ["*://*.myshop.com/*"], ... }]Also update the SUPPORTED_PLATFORMS list in src/popup/Popup.tsx so the popup correctly reports the active platform.
Product analysis is behind the AnalysisService interface (src/analysis/index.ts). The current implementation (src/analysis/mock.ts) returns category-based mock data.
To integrate a real LLM:
- Create
src/analysis/llm.tsimplementingAnalysisService. - In
src/content.ts, replacenew MockAnalysisService()with your implementation. - For API key security, move the
analyze()call intosrc/background.tsand usechrome.runtime.sendMessage— the message plumbing is already scaffolded there.
Biome handles both linting and formatting.
# Lint (auto-fix)
npm run lint
# Format (auto-fix)
npm run formatHusky runs both automatically on git commit. The CI workflow (.github/workflows/lint.yml) also runs them on every push and pull request.
This project follows the Conventional Commits specification. Commit messages are validated automatically by the commit-msg Husky hook via commitlint.
Format: <type>(<scope>): <description>
| Type | When to use |
|---|---|
feat |
New feature |
fix |
Bug fix |
docs |
Documentation changes |
style |
Formatting, missing semicolons, etc. (no logic change) |
refactor |
Code change that is neither a fix nor a feature |
chore |
Build process, dependency updates, tooling |
revert |
Reverts a previous commit |
Examples:
feat(platforms): add Walmart platform adapter
fix(content): handle SPA navigation on eBay
chore: upgrade tailwind to v4.3