minhvo.vercel.app
Wed Sep 17 2025

react-theme-switch-animation
React
TypeScript
Next.js
View Transitions
Animation
Library
npm
Open Source
React Hook for smooth dark/light theme transitions using the View Transitions API — circle, blur-circle, and QR-scan effects.
Overview
A tiny React Hook (≈8 KB) that turns the dark/light toggle into a cinematic reveal, powered by the browser's View Transitions API. Currently 57+ stars on GitHub and shipping in production sites including this one.
Usage
'use client'
import { useModeAnimation, ThemeAnimationType } from 'react-theme-switch-animation'
export default function ThemeToggle() {
const { ref, toggleSwitchTheme, isDarkMode } = useModeAnimation({
animationType: ThemeAnimationType.CIRCLE,
duration: 750,
})
return (
<button ref={ref} onClick={toggleSwitchTheme}>
{isDarkMode ? '🌙' : '☀️'}
</button>
)
}Animation Types
| Type | Effect |
|---|---|
CIRCLE | Crisp circular reveal expanding from the toggle button to the farthest viewport corner |
BLUR_CIRCLE | Soft-edged radial reveal using an SVG Gaussian-blur mask |
QR_SCAN | Horizontal "scan line" wipe reminiscent of a QR scanner |
Technical Highlights
- Origin-aware reveal: uses
getBoundingClientRect()on the toggle button, then computesMath.hypotto all four viewport corners — the animation always covers the full viewport regardless of where the button lives document.startViewTransitionfor the snapshot,flushSyncto commit the theme class inside the transition frame, thendocumentElement.animate({ clipPath: ... }, { pseudoElement: '::view-transition-new(root)' })drives the reveal — no<style>injection required for theCIRCLEvariant- High-DPI adaptation: at ≥3000×2000 it shaves animation duration by 20%, enables
backface-visibilityandtranslate3dhacks for smoother GPU compositing - Accessibility: respects
prefers-reduced-motion— gracefully degrades to an instant theme swap - External state:
isDarkMode+onDarkModeChangeprops let the hook drop into existing state managers (next-themes, Redux, Jotai, etc.)
Stack
- TypeScript library compiled to ESM + CJS
- Zero runtime dependencies beyond React
- Tested against React 16.8+ on Next.js 13/14/15, CRA, and Vite
Role & Responsibilities
- Authored the hook, the three animation strategies, and the High-DPI adaptation
- Wrote the docs, the demo app, and shipped to npm
- Maintain the issue tracker and review community PRs