Chrome Extension Pomodoro Timer — Developer Guide
5 min readBuild a Pomodoro Timer Extension
What You’ll Build
- 25-minute work sessions with 5-minute breaks
- Badge countdown showing minutes remaining
- Desktop notifications when timer ends
- Sound alert via offscreen document
- Session tracking and statistics
- Customizable durations and auto-start options
Manifest
- permissions: alarms, notifications, offscreen, storage
- action with popup
- background service worker for timing
Step 1: Timer State Management
Create a state object to track the timer:
// background/timer-state.js
const DEFAULT_SETTINGS = {
workDuration: 25,
breakDuration: 5,
autoStartBreak: false,
autoStartWork: false,
soundEnabled: true
};
let timerState = {
isRunning: false,
isWorkSession: true,
timeRemaining: 25 * 60,
completedPomodoros: 0,
settings: { ...DEFAULT_SETTINGS }
};
Step 2: Alarm-Based Timing
Use chrome.alarms for reliable timing in the service worker:
// background/alarm-timer.js
chrome.alarms.create('pomodoro-timer', { periodInMinutes: 1 });
chrome.alarms.onAlarm.addListener((alarm) => {
if (alarm.name === 'pomodoro-timer' && timerState.isRunning) {
timerState.timeRemaining -= 60;
updateBadge();
if (timerState.timeRemaining <= 0) {
handleSessionComplete();
}
}
});
function updateBadge() {
const minutes = Math.ceil(timerState.timeRemaining / 60);
chrome.action.setBadgeText({ text: String(minutes) });
chrome.action.setBadgeBackgroundColor({ color: '#e74c3c' });
}
See permissions/alarms.md for more details.
Step 3: Notification Alerts
Notify users when sessions complete:
// background/notifications.js
function notifySessionComplete() {
const title = timerState.isWorkSession
? 'Work Session Complete!'
: 'Break Time Over!';
const message = timerState.isWorkSession
? 'Great job! Take a break.'
: 'Ready for another focus session?';
chrome.notifications.create({
type: 'basic',
iconUrl: 'icons/icon-48.png',
title,
message,
priority: 2
});
}
See permissions/notifications.md.
Step 4: Sound Alerts via Offscreen Document
Play audio using an offscreen document for AUDIO_PLAYBACK:
// background/audio-manager.js
async function playAlertSound() {
await chrome.offscreen.createDocument({
url: 'offscreen.html',
reasons: ['AUDIO_PLAYBACK'],
justification: 'Play timer completion sound'
});
// Audio plays automatically via offscreen document
setTimeout(() => {
chrome.offscreen.closeDocument();
}, 3000);
}
<!-- offscreen.html -->
<audio id="alert" src="alert.mp3" autoplay></audio>
Step 5: Popup UI
Create the popup interface:
<!-- popup.html -->
<div class="pomodoro-app">
<div class="timer-display">
<span id="time">25:00</span>
<span id="session-type">Work</span>
</div>
<div class="controls">
<button id="start">Start</button>
<button id="pause">Pause</button>
<button id="reset">Reset</button>
</div>
<div class="stats">
<span>Pomodoros: <span id="count">0</span></span>
</div>
<a href="options.html" class="settings">Settings</a>
</div>
Step 6: Statistics Storage
Track completed pomodoros using webext-storage patterns:
// background/statistics.js
async function recordPomodoro() {
const today = new Date().toISOString().split('T')[0];
const data = await chrome.storage.local.get(['stats']);
const stats = data.stats || { daily: {}, weekly: {} };
stats.daily[today] = (stats.daily[today] || 0) + 1;
stats.completed = (stats.completed || 0) + 1;
await chrome.storage.local.set({ stats });
}
function getWeeklyStats() {
// Return completed pomodoros for the past 7 days
}
Step 7: Options Page
Allow customizable durations:
<!-- options.html -->
<form id="settings-form">
<label>
Work Duration (minutes)
<input type="number" id="work-duration" value="25" min="1" max="60">
</label>
<label>
Break Duration (minutes)
<input type="number" id="break-duration" value="5" min="1" max="30">
</label>
<label>
<input type="checkbox" id="auto-start-break">
Auto-start break after work
</label>
<label>
<input type="checkbox" id="auto-start-work">
Auto-start work after break
</label>
<label>
<input type="checkbox" id="sound-enabled">
Enable sound alerts
</label>
<button type="submit">Save Settings</button>
</form>
Step 8: Badge Management
See patterns/badge-management.md for advanced badge patterns including color changes for different session types.
Summary
You now have a complete Pomodoro timer extension with:
- Reliable timing via chrome.alarms
- Visual countdown in the badge
- Audio alerts through offscreen documents
- Session statistics tracking
- Customizable settings
- Auto-start options
This extension demonstrates key Chrome extension patterns including service worker timing, cross-context communication, and persistent state management. -e —
Part of the Chrome Extension Guide by theluckystrike. Built at zovo.one.