Day.js Date Handling in Chrome Extensions: Complete 2025 Guide
Date and time handling stands as one of the most challenging aspects of JavaScript development, and Chrome extension development introduces additional complexity. When building Chrome extensions, developers must handle dates across multiple contexts: content scripts running in web pages, background service workers, popup pages, and options pages. Each context presents unique challenges for date manipulation chrome developers must understand. This comprehensive guide explores how to implement Day.js effectively in Chrome extensions, covering installation, configuration, and best practices for building robust time-aware extensions.
Understanding how to properly implement time formatting extension capabilities using Day.js will dramatically improve your extension’s user experience. Whether you’re building an extension that tracks browsing history, schedules tasks, logs events, or displays timestamps, this guide provides the essential knowledge you need to succeed.
Why Day.js for Chrome Extensions?
The JavaScript Date object, while built-in, offers limited functionality for complex date operations. Developers often find themselves writing custom utility functions for common tasks like formatting relative time (“2 hours ago”), parsing various date formats, or handling time zones. Day.js emerges as an excellent solution for dayjs extension development for several compelling reasons.
First, Day.js boasts a remarkably small footprint. The base library is only about 2KB minified and compressed, making it ideal for extensions where bundle size directly impacts load times and user experience. Unlike Moment.js, which weighs around 67KB, Day.js provides similar functionality without the performance penalty. This becomes particularly important in Chrome extensions where every kilobyte affects how quickly your extension becomes functional after installation.
Second, Day.js follows a modular plugin architecture. Chrome extensions often need specific date features but not necessarily all of them. With Day.js, you can import only the plugins your extension requires, further optimizing bundle size. Need relative time formatting? Add the relativeTime plugin. Working with time zones? Include the timezone plugin. This flexibility makes Day.js the perfect choice for extensions with specific date handling requirements.
Third, the API design of Day.js feels familiar to developers who have used Moment.js, reducing the learning curve. Most Moment.js operations work identically in Day.js, allowing developers to leverage existing knowledge and code patterns when building Chrome extensions.
Installing Day.js in Your Chrome Extension Project
Setting up Day.js in a Chrome extension project follows standard JavaScript package management practices, though you’ll need to consider how your extension’s JavaScript is bundled and loaded.
Using npm for Package Management
For modern Chrome extension development using build tools like Webpack, Rollup, or Vite, installing Day.js is straightforward. Run the following command in your project directory:
npm install dayjs
This installs Day.js as a dependency in your project. Your build configuration will then bundle Day.js along with your extension’s JavaScript code. When importing Day.js, you can either import the entire library or selectively import only the plugins you need:
import dayjs from 'dayjs';
import relativeTime from 'dayjs/plugin/relativeTime';
import advancedFormat from 'dayjs/plugin/advancedFormat';
import timezone from 'dayjs/plugin/timezone';
import utc from 'dayjs/plugin/utc';
// Extend dayjs with required plugins
dayjs.extend(relativeTime);
dayjs.extend(advancedFormat);
dayjs.extend(timezone);
dayjs.extend(utc);
Using Day.js Directly in Manifest V3
For simpler extensions or those not using a build system, you can include Day.js directly in your extension. Download the minified Day.js library from the official website or npm, then add it to your extension’s directory. Reference it in your HTML files before your main script:
<script src="dayjs.min.js"></script>
<script src="dayjs/plugin/relativeTime.js"></script>
<script src="your-extension-script.js"></script>
When using this approach, ensure you load the plugins after Day.js but before scripts that depend on plugin functionality. The plugin files must be loaded in the correct order for the functionality to work properly.
Configuring Day.js for Chrome Extension Contexts
Chrome extensions operate across multiple execution contexts, each with distinct characteristics and requirements. Understanding these contexts is essential for effective date handling in your extension.
Content Scripts and Date Handling
Content scripts run in the context of web pages, isolated from the extension’s other components. When implementing date manipulation chrome in content scripts, consider the following best practices.
Always initialize Day.js plugins within your content script to ensure they’re available when needed. Since content scripts share the page’s window object, be mindful of variable scope:
// In your content script
(function() {
// Import Day.js plugins
dayjs.extend(dayjs_plugin_relativeTime);
dayjs.extend(dayjs_plugin_advancedFormat);
// Now you can use Day.js for date operations
const timestamp = dayjs('2025-01-29T10:30:00Z');
console.log(timestamp.fromNow()); // "2 hours ago"
console.log(timestamp.format('MMMM D, YYYY')); // "January 29, 2025"
})();
When content scripts interact with dates from the web page, ensure you parse them correctly. Web pages may present dates in various formats, and Day.js’s parsing capabilities combined with custom format plugins help handle these variations:
import dayjs from 'dayjs';
import customParseFormat from 'dayjs/plugin/customParseFormat';
dayjs.extend(customParseFormat);
// Parse various date formats commonly found on web pages
const date1 = dayjs('2025-01-29', 'YYYY-MM-DD');
const date2 = dayjs('29/01/2025', 'DD/MM/YYYY');
const date3 = dayjs('Jan 29, 2025', 'MMM D, YYYY');
Background Service Workers and Timestamp Management
Manifest V3 introduced service workers as the replacement for background pages. Service workers handle extension events and can perform operations even when no extension page is open. Date handling in service workers often involves logging, scheduling, and coordinating across extension components.
When storing dates in Chrome’s storage API, consider storing them as ISO strings for maximum compatibility:
// Storing a date in chrome.storage
chrome.storage.local.set({
lastSync: dayjs().toISOString(),
scheduledTask: {
name: 'Daily Report',
executeAt: dayjs().add(1, 'day').toISOString()
}
});
// Retrieving and parsing stored dates
chrome.storage.local.get(['lastSync'], (result) => {
const lastSync = dayjs(result.lastSync);
console.log(`Last sync: ${lastSync.format('YYYY-MM-DD HH:mm')}`);
});
For extensions that need to schedule future tasks, Day.js makes it easy to calculate durations and determine whether it’s time to execute:
function checkScheduledTasks() {
chrome.storage.local.get(['scheduledTask'], (result) => {
const task = result.scheduledTask;
if (task && dayjs(task.executeAt).isBefore(dayjs())) {
executeTask(task);
}
});
}
Popup and Options Pages
Popup pages and options pages run in their own context and can load Day.js like any regular web page. These contexts typically display dates to users, making formatting crucial for user experience.
Implement time formatting extension capabilities in your popup to display dates in user-friendly formats:
// In popup.js
document.addEventListener('DOMContentLoaded', () => {
const currentDate = dayjs();
// Display formatted date in popup
document.getElementById('current-date').textContent =
currentDate.format('dddd, MMMM D, YYYY');
document.getElementById('current-time').textContent =
currentDate.format('h:mm A');
// Show relative time for some event
const lastAction = dayjs(chrome.storage.local.get('lastAction'));
document.getElementById('last-action').textContent =
lastAction.fromNow();
});
Advanced Day.js Features for Chrome Extensions
Relative Time and Human-Readable Dates
One of the most common requirements for extensions is displaying time in relative formats like “5 minutes ago” or “in 2 hours.” Day.js’s relativeTime plugin makes this straightforward:
import dayjs from 'dayjs';
import relativeTime from 'dayjs/plugin/relativeTime';
dayjs.extend(relativeTime);
// Display relative times
dayjs('2025-01-29').fromNow(); // "2 hours ago"
dayjs('2025-01-31').toNow(); // "in 2 days"
dayjs('2025-01-25').from('2025-01-29'); // "4 days ago"
This functionality proves invaluable for extensions that display timestamps of recent activities, notifications, or browsing history. Users instantly understand “5 minutes ago” far better than “2025-01-29T10:25:00Z.”
Timezone Handling
Extensions serving a global user base must handle timezone differences appropriately. Day.js provides timezone support through its timezone plugin:
import dayjs from 'dayjs';
import timezone from 'dayjs/plugin/timezone';
import utc from 'dayjs/plugin/utc';
dayjs.extend(utc);
dayjs.extend(timezone);
// Convert between timezones
const localTime = dayjs('2025-01-29T10:00:00');
const tokyoTime = localTime.tz('Asia/Tokyo');
const newYorkTime = localTime.tz('America/New_York');
console.log(tokyoTime.format()); // 2025-01-29T19:00:00+09:00
console.log(newYorkTime.format()); // 2025-01-29T05:00:00-05:00
This capability is essential for extensions that coordinate across timezones or display meeting times, flight information, or any time-sensitive data.
Duration Calculations
Extensions often need to calculate durations between dates—whether for tracking time spent on tasks, measuring page load performance, or managing timers:
import dayjs from 'dayjs';
import duration from 'dayjs/plugin/duration';
dayjs.extend(duration);
const start = dayjs('2025-01-29T08:00:00');
const end = dayjs('2025-01-29T12:30:00');
const diff = end.diff(start);
const dur = dayjs.duration(diff);
console.log(`${dur.hours()} hours and ${dur.minutes()} minutes`); // "4 hours and 30 minutes"
// Format as total hours
console.log(dur.asHours()); // 4.5
Best Practices for Day.js in Chrome Extensions
Optimizing Bundle Size
To maintain optimal performance, follow these dayjs extension optimization strategies:
Only import the plugins your extension actually uses. Each plugin adds to your bundle size, so carefully evaluate which features you need:
// Instead of importing everything, import selectively
import dayjs from 'dayjs';
import relativeTime from 'dayjs/plugin/relativeTime';
import advancedFormat from 'dayjs/plugin/advancedFormat';
// Only extend with plugins you need
dayjs.extend(relativeTime);
dayjs.extend(advancedFormat);
Consider using dynamic imports for plugins that aren’t immediately needed, reducing initial load time:
// Lazy load plugins when needed
async function formatWithAdvancedOptions(date) {
const advancedFormat = (await import('dayjs/plugin/advancedFormat')).default;
dayjs.extend(advancedFormat);
return dayjs(date).format('MMMM Do YYYY, h:mm:ss a');
}
Handling Cross-Context Date Sharing
When sharing dates between extension contexts (content scripts, background, popup), always use standardized formats. ISO 8601 strings provide the safest format for cross-context communication:
// Send date from content script to background
chrome.runtime.sendMessage({
type: 'DATE_LOG',
timestamp: dayjs().toISOString() // Always use ISO format
});
// Background receives and parses
chrome.runtime.onMessage.addListener((message) => {
if (message.type === 'DATE_LOG') {
const parsedDate = dayjs(message.timestamp);
// Process the date
}
});
Error Handling and Validation
Always validate dates before performing operations, especially when handling user input or data from web pages:
function safeParseDate(dateInput) {
const parsed = dayjs(dateInput);
return parsed.isValid() ? parsed : null;
}
const userDate = safeParseDate(userInput);
if (userDate) {
console.log(`Valid date: ${userDate.format('YYYY-MM-DD')}`);
} else {
console.error('Invalid date format provided');
}
Real-World Examples: Building Date-Aware Chrome Extensions
Example: Reading Time Tracker Extension
Consider building an extension that tracks how long users spend on web pages. Day.js handles the time calculations elegantly:
// content.js - Track time on page
let startTime = dayjs();
window.addEventListener('beforeunload', () => {
const timeSpent = dayjs().diff(startTime);
const duration = dayjs.duration(timeSpent);
chrome.runtime.sendMessage({
type: 'TIME_LOG',
url: window.location.href,
timeSpent: {
milliseconds: duration.asMilliseconds(),
formatted: `${duration.hours()}h ${duration.minutes()}m ${duration.seconds()}s`
}
});
});
Example: Scheduled Reminder Extension
Extensions that remind users at specific times benefit from Day.js’s scheduling capabilities:
// background.js - Schedule reminders
function scheduleReminder(reminderTime, message) {
const reminderDate = dayjs(reminderTime);
// Calculate milliseconds until reminder
const msUntilReminder = reminderDate.diff(dayjs());
if (msUntilReminder > 0) {
setTimeout(() => {
chrome.notifications.create({
type: 'basic',
iconUrl: 'icons/icon48.png',
title: 'Reminder',
message: message
});
}, msUntilReminder);
}
}
Conclusion
Day.js provides Chrome extension developers with a powerful, lightweight solution for date and time handling. Its small footprint, modular plugin architecture, and intuitive API make it ideal for extensions where performance and bundle size matter. Whether you’re implementing simple timestamp formatting or complex timezone-aware scheduling, Day.js delivers the tools you need.
By following the best practices outlined in this guide—optimizing bundle size with selective plugin imports, using standardized date formats for cross-context communication, and implementing proper error handling—you’ll build robust Chrome extensions that handle dates gracefully. As extensions continue to evolve and serve increasingly sophisticated use cases, Day.js remains a reliable foundation for all your date manipulation chrome and time formatting extension needs.
The key to success lies in understanding your extension’s specific requirements and leveraging Day.js’s modular design to implement only what you need. Start with the basics, add plugins as your requirements grow, and enjoy the benefits of clean, maintainable date handling code in your Chrome extensions.
Additional Resources and Tips
Day.js Plugin Ecosystem
Day.js offers numerous plugins beyond those covered in this guide. Here are some additional plugins that can enhance your Chrome extension’s date handling capabilities.
The calendar plugin displays dates relative to today with calendar-style formatting:
import dayjs from 'dayjs';
import calendar from 'dayjs/plugin/calendar';
dayjs.extend(calendar);
dayjs('2025-01-29').calendar(); // "01/29/2025"
dayjs('2025-01-28').calendar(); // "Yesterday at 4:30 PM"
dayjs('2025-02-01').calendar(); // "Tomorrow at 10:00 AM"
The localizedFormat plugin automatically formats dates according to the user’s locale:
import dayjs from 'dayjs';
import localizedFormat from 'dayjs/plugin/localizedFormat';
dayjs.extend(localizedFormat);
dayjs('2025-01-29').format('L'); // Locale-specific long date
dayjs('2025-01-29').format('LL'); // Locale-specific full date
dayjs('2025-01-29').format('LLL'); // Locale-specific full date with time
The quarterOfYear plugin helps with quarter-based calculations, useful for business extensions tracking quarterly metrics:
import dayjs from 'dayjs';
import quarterOfYear from 'dayjs/plugin/quarterOfYear';
dayjs.extend(quarterOfYear);
dayjs('2025-02-15').quarter(); // 1
dayjs('2025-05-20').quarter(); // 2
Debugging Date Issues in Extensions
When developing Chrome extensions with date handling, debugging can be challenging due to the multiple execution contexts. Here are strategies to identify and resolve common issues.
First, verify that Day.js is loaded correctly in each context. Use console logging to confirm initialization:
console.log('Day.js version:', dayjs.version);
console.log('Current time:', dayjs().format());
Second, when experiencing timezone issues, explicitly set the timezone to avoid browser-specific behavior:
import dayjs from 'dayjs';
import timezone from 'dayjs/plugin/timezone';
import utc from 'dayjs/plugin/utc';
dayjs.extend(utc);
dayjs.extend(timezone);
// Force UTC for consistent behavior
dayjs.utc('2025-01-29T10:00:00').format();
Third, use the debugging tools in Chrome to inspect dates across contexts. The background service worker console output appears in the Extensions management page, while content script logs appear in the page’s console.
Performance Considerations for Large-Scale Extensions
For extensions that process many dates, such as analytics dashboards or history viewers, consider these performance optimizations.
Cache Day.js instances when working with the same date repeatedly:
// Instead of repeatedly parsing the same date
const baseDate = dayjs('2025-01-29');
const formatted1 = baseDate.add(1, 'day').format();
const formatted2 = baseDate.add(2, 'day').format();
const formatted3 = baseDate.add(3, 'day').format();
Use native Date objects when performing simple comparisons that don’t require formatting, as they’re faster for basic operations:
// Simple comparison without full Day.js overhead
const dateA = new Date('2025-01-29');
const dateB = new Date('2025-01-30');
const isBefore = dateA < dateB;
Implement pagination when displaying large lists of dated items to avoid performance bottlenecks when rendering many timestamps simultaneously.
Summary and Next Steps
Day.js transforms date handling in Chrome extensions from a painful development experience into a streamlined process. This guide covered the essential aspects of integrating Day.js into your extensions, from basic installation to advanced timezone handling and performance optimization. The practical examples demonstrated real-world applications that you can adapt for your own projects.
As you build your Chrome extensions, remember to start simple and add complexity only when needed. The modular nature of Day.js means you can begin with the core library and gradually incorporate plugins as your date handling requirements evolve. Focus on maintaining consistent date formats across your extension’s contexts, validate user input thoroughly, and always consider the performance implications of your date handling choices.
With the knowledge from this guide, you’re now equipped to build sophisticated, date-aware Chrome extensions that provide excellent user experiences. Continue exploring Day.js’s documentation for additional features, and don’t hesitate to experiment with different plugins to find the perfect combination for your specific use case.