What Makes a Good Browser Extension? Lessons from Building One
I've used dozens of browser extensions and built a few. After launching Weather & Clock Dashboard, I have a clearer sense of what separates good extensions from ones that get uninstalled after a week.
1. Do one thing well
The extensions I keep installed have a single clear purpose. uBlock Origin blocks ads. LastPass manages passwords. My extension shows weather and clocks.
Extensions that try to do too much end up doing nothing particularly well. They also request more permissions, which erodes trust.
2. Ask for minimal permissions
Every permission you request is a reason for the user to hesitate during install. Mozilla's AMO shows users exactly what your extension can access before they install it.
For my extension, I need:
-
storage— to save user preferences (dark mode, clock timezones) -
geolocation— to get location for weather
That's it. No tabs, no webRequest, no <all_urls>. Users can see at a glance that I'm not doing anything suspicious.
3. Work offline gracefully
This one surprised me. People open new tabs when they have no internet. If your extension shows a blank page or a broken spinner when offline, you've just made their experience worse than the default.
try {
const weather = await fetchWeather(lat, lon);
renderWeather(weather);
} catch (err) {
// Show cached weather if available, or a friendly offline state
const cached = await browser.storage.local.get('lastWeather');
if (cached.lastWeather) {
renderWeather(cached.lastWeather, { isStale: true });
} else {
renderOfflineState();
}
}
4. Respect the user's browser settings
prefers-color-scheme exists. Use it. Don't make users manually toggle dark mode if their OS is already in dark mode.
const savedTheme = await browser.storage.local.get('theme');
const theme = savedTheme.theme ??
(matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light');
5. Load fast
A new tab opens on every keystroke in the address bar. If your extension takes 300ms to load, that's perceptible. A few ways to keep it fast:
- No frameworks — React adds ~40KB gzipped. For a new tab extension, that's overhead.
- Inline critical CSS — No render-blocking stylesheets.
- Cache aggressively — If you're fetching data, cache it. Don't hit the network on every tab open.
My extension loads in under 50ms before the network request. The cached weather shows immediately; it updates in the background.
6. Be honest in your description
Your AMO description is a promise. If you say "live weather" but it's actually cached for 24 hours, you've created a mismatch between expectation and reality.
I cache weather for 10 minutes. My description says "live weather." That's fair — 10 minutes is current in any meaningful sense for weather.
7. Don't over-engineer the settings
Settings UX is often where extensions go wrong. I've seen extensions with 50-option settings panels where 45 options will never be touched.
For Weather & Clock Dashboard, the settings are:
- Dark/light/auto mode
- Units (°C/°F)
- Up to 4 world clock timezones
- Default search engine
Four decisions. That's it. If a setting doesn't affect 80% of users' daily experience, it probably shouldn't exist.
8. Make uninstalling easy
This sounds counterintuitive, but users who can easily uninstall are more likely to try an extension in the first place. If you make it feel risky or difficult to remove something, people won't install it.
Summary
The best extensions are invisible when they work and immediately useful when you need them. Build the smallest thing that solves the problem well.
Weather & Clock Dashboard is my attempt at that. MIT licensed, ~500 lines, no backend.
Top comments (0)