Chrome Extension Extension Configuration — Best Practices
3 min readExtension Configuration Patterns
Configuration management is critical for building flexible, user-customizable Chrome extensions. This guide covers patterns for implementing robust configuration systems.
Default Configuration
Always provide hardcoded default values merged with user overrides:
const DEFAULT_CONFIG = {
theme: 'system',
notifications: true,
syncEnabled: false,
maxResults: 50,
} as const;
async function loadConfig(): Promise<Config> {
const userConfig = await chrome.storage.local.get(null);
return { ...DEFAULT_CONFIG, ...userConfig };
}
Schema Validation
Validate configuration on load and reject invalid values:
const configSchema = z.object({
theme: z.enum(['light', 'dark', 'system']).default('system'),
notifications: z.boolean().default(true),
maxResults: z.number().min(1).max(100).default(50),
});
function validateConfig(raw: unknown): Config {
return configSchema.parse(raw);
}
Configuration Versioning
Migrate config across extension updates:
const CONFIG_VERSION = 2;
const migrations: Record<number, (config: Config) => Config> = {
1: (cfg) => ({ ...cfg, theme: 'system', version: 2 }),
};
async function migrateConfig(config: Config): Promise<Config> {
let current = config;
for (let v = (config.version || 1); v < CONFIG_VERSION; v++) {
current = migrations[v](current);
}
return { ...current, version: CONFIG_VERSION };
}
Layered Configuration
Priority: defaults < user settings < enterprise policy:
async function getEffectiveConfig(): Promise<Config> {
const [defaults, user, policy] = await Promise.all([
loadDefaults(),
chrome.storage.local.get(null),
chrome.storage.managed.get(null),
]);
return { ...defaults, ...policy, ...user };
}
Observing Config Changes
Use chrome.storage.onChanged for reactive updates:
chrome.storage.onChanged.addListener((changes, area) => {
if (area === 'local') {
const newConfig = validateConfig(changes);
applyConfig(newConfig);
}
});
Typed Config with TypeScript
Use interfaces for type-safe configuration:
interface ExtensionConfig {
theme: 'light' | 'dark' | 'system';
notifications: boolean;
syncEnabled: boolean;
maxResults: number;
version: number;
}
Config UI Patterns
- Options page forms: Group settings by category (general, appearance, advanced, experimental)
- Import/Export: JSON serialization for backup and sharing
- Reset to defaults: Clear user overrides, restore factory settings
Sync vs Local Storage
- chrome.storage.sync: User preferences that follow the user across devices
- chrome.storage.local: Machine-specific settings (window size, debug flags)
Feature Toggles
Enable/disable features via boolean flags:
const FEATURES = {
experimentalFeatures: false,
newDashboard: true,
} as const;
Cross-References
Part of the Chrome Extension Guide by theluckystrike. Built at zovo.one.