A lightweight React npm package that automatically switches between light and dark themes based on the user's local time, with full manual override support.
npm install @arsalanshaikhh/auto-time-theme-reactbash
npm install @arsalanshaikhh/auto-time-theme-react
`
or
`bash
yarn add @arsalanshaikhh/auto-time-theme-react
`
Live Demo
Try the live demo at: https://demo-qhqosmydg-arsalanshaikhhs-projects.vercel.app
Quick Start
$3
`tsx
import { AutoThemeProvider } from '@arsalanshaikhh/auto-time-theme-react';
function App() {
return (
);
}
`
$3
`tsx
import { useAutoTheme } from '@arsalanshaikhh/auto-time-theme-react';
function ThemeToggle() {
const { theme, mode, setLight, setDark, setAuto, toggleTheme } = useAutoTheme();
return (
Current theme: {theme}
Current mode: {mode}
);
}
`
API Reference
$3
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| lightStart | string | "07:00" | Start time for light mode (HH:MM format) |
| darkStart | string | "22:00" | Start time for dark mode (HH:MM format) |
| defaultMode | "auto" \| "light" \| "dark" | "auto" | Initial mode when no stored preference exists |
| storageKey | string | "auto-theme-mode" | LocalStorage key for storing user preference |
| applyTo | "html" \| "body" | "html" | DOM element to apply the data-theme attribute to |
| onThemeChange | (theme: Theme, mode: Mode) => void | undefined | Callback invoked when the theme changes |
$3
| Property | Type | Description |
|----------|------|-------------|
| theme | Theme | Current theme ("light" or "dark") |
| mode | Mode | Current mode ("auto", "light", or "dark") |
| setLight | () => void | Set the mode to light (manual override) |
| setDark | () => void | Set the mode to dark (manual override) |
| setAuto | () => void | Set the mode to auto (enables time-based switching) |
| toggleTheme | () => void | Toggle between light and dark themes |
$3
`tsx
// Get only the current theme
import { useTheme } from '@arsalanshaikhh/auto-time-theme-react';
const theme = useTheme();
// Get only the current mode
import { useMode } from '@arsalanshaikhh/auto-time-theme-react';
const mode = useMode();
`
Theme Application Strategy
The package does not apply styles directly. It only adds a data-theme attribute to the specified DOM element:
`html
`
Use CSS variables with the attribute selector:
`css
[data-theme="light"] {
--bg-color: #ffffff;
--text-color: #111111;
}
[data-theme="dark"] {
--bg-color: #111111;
--text-color: #ffffff;
}
body {
background-color: var(--bg-color);
color: var(--text-color);
}
`
Default Behavior
- Light Theme: 7:00 AM to 10:00 PM
- Dark Theme: 10:00 PM to 7:00 AM
Time is calculated using the user's local system time. Theme updates automatically when the time crosses a boundary without requiring a page refresh.
Theme Priority Order
1. User manual selection - If the user has selected a manual theme
2. Time-based automatic logic - If mode is set to auto
3. Default fallback - The defaultMode prop value
If the user selects a manual theme, time-based switching is paused until auto mode is restored.
Configuration Examples
$3
`tsx
config={{
lightStart: '06:00', // Light theme starts at 6 AM
darkStart: '20:00', // Dark theme starts at 8 PM
}}
>
`
$3
`tsx
config={{
storageKey: 'my-app-theme-preference',
}}
>
`
$3
`tsx
config={{
onThemeChange: (theme, mode) => {
console.log(Theme changed to ${theme} (mode: ${mode}));
// You can send analytics events here
},
}}
>
`
$3
`tsx
config={{
applyTo: 'body',
}}
>
`
Advanced Usage
$3
`tsx
import { useAutoTheme } from '@arsalanshaikhh/auto-time-theme-react';
function ThemeToggle() {
const { theme, mode, setLight, setDark, setAuto, toggleTheme } = useAutoTheme();
return (
onClick={setLight}
className={mode === 'light' ? 'active' : ''}
>
☀️ Light
onClick={setDark}
className={mode === 'dark' ? 'active' : ''}
>
🌙 Dark
onClick={setAuto}
className={mode === 'auto' ? 'active' : ''}
>
⏰ Auto
);
}
`
$3
`tsx
import { useTheme } from '@arsalanshaikhh/auto-time-theme-react';
function StyledComponent() {
const theme = useTheme();
const isDark = theme === 'dark';
const styles = {
backgroundColor: isDark ? '#111111' : '#ffffff',
color: isDark ? '#ffffff' : '#111111',
};
return Content;
}
`
SSR Compatibility
The package is designed to be safe for server-side rendering:
- No window or document access during initial render
- Theme is applied on client-side mount
- Proper checks for environment before DOM access
`tsx
// This works with Next.js, Gatsby, Remix, etc.
import { AutoThemeProvider } from '@arsalanshaikhh/auto-time-theme-react';
export default function MyApp({ Component, pageProps }) {
return (
);
}
`
Edge Cases Handled
- ✅ Time range crossing midnight
- ✅ Tab sleeping and resuming (visibility change)
- ✅ System time change during app usage
- ✅ Invalid time configuration (falls back to defaults)
- ✅ Disabled localStorage (graceful fallback)
- ✅ SSR environments
Performance Considerations
- No constant polling - Uses setTimeout to schedule only the next required theme switch
- Minimal re-renders - Efficient context design
- Event listener cleanup - Proper cleanup on unmount
- Memoized callbacks - Reduces unnecessary re-renders
Folder Structure
`
src/
├── AutoThemeProvider.tsx # Context provider component
├── useAutoTheme.ts # Main hook and additional hooks
├── timeUtils.ts # Time calculation utilities
├── storage.ts # LocalStorage utilities
├── constants.ts # Default values and constants
├── types.ts # TypeScript type definitions
└── index.ts # Public exports
``