glimm is a React and Next.js library for delightful shader-driven page transitions. It sweeps a single WebGL band across your screen during route changes or any state change you select. The new view appears underneath as the band moves. It is GPU-composited, under 10 KB, and has zero performance impact.
npm install glimm
Zero runtime dependencies. React 18+ and Next 13+ are peer deps.
Installation You can install glimm using npm, or share the following prompt with a coding agent to set it up for you.
npm install glimm
Quick start
Getting started takes a single step. Wrap your app in GlimmProvider
so glimm is available on every route. From there, you choose how a transition gets triggered using one of the options below. The provider stays idle until it's actually needed: it builds its one WebGL context on the very first sweep, so an app that never transitions costs nothing to set up.
Triggers
There are three ways to trigger a transition, and you can use any combination across your app. TransitionLink
replaces standard links when the destination is known upfront. useTransitionRouter()
handles programmatic navigation, like redirects after form submissions. Or drop in <InterceptLinks />
at the root level to automatically apply transitions to all internal links without touching existing code.
Presets
glimm includes 6 built-in color palettes, each tuned to a different mood using cosine gradients. Pass any palette name as a string to the palette
option. If the presets don't fit your design, you can create a custom palette using the {a,b,c,d}
format, covered in Custom palette below.
Easing
Easing controls how the band speeds up and slows down as it crosses the screen. Front-loaded curves like back
and easeOutQuart
start fast, so the sweep feels snappy and immediate. Symmetric curves like easeInOutCubic
ease in and out evenly, for a calmer, more composed feel. Pass any of the 10 built-in curves as a string, or provide your own as a (p: number) => number
function.
Band width
bandTight
controls how concentrated the band's gaussian falloff is. Lower values produce a wider, softer band; higher values make a narrower, more focused beam.
[Custom palette](#custom-palette)
Each palette is a cosine palette: `color(t) = a + b·cos(2π·(c·t + d))`
. Each of a
, b
, c
, d
is an RGB triplet — hit Shuffle to roll one, then copy the snippet below.
Props
Everything you can pass to GlimmProvider
(as defaults) or any trigger (as per-call overrides). Every option is optional.
| Prop | Type | Default | Description |
|---|---|---|---|
| palette | PaletteName | Palette | 'prism' |
| direction | 'ltr' | 'rtl' | 'ttb' |
| easing | EasingName | (p) => number | 'easeInOutCubic' |
| sweepMs | number | 800 | Band traversal duration. |
| outroMs | number | 350 | Post-traversal alpha fade. |
| midpoint | number | 0.5 | When routes swap mid-sweep. |
| peakAlpha | number | 1 | Caps band peak (0..1.5). |
| brightness | number | 1 | RGB scale; ~0.85 on dark. |
| bandTight | number | 14 | Tightness; lower = wider. |
| waveAmount | number | 1 | Edge wave turbulence. |
| rippleAmount | number | 1 | Vertical ripple texture. |
| waveSpeed | number | 1 | Shader animation speed. |
Best practices glimm is recommended for highlighting moments rather than just motion. Each sweep serves as a form of punctuation, reserved for state changes that require attention while allowing the rest of the app to remain quiet.
Use glimm for:
- Moments like publishing, submitting or completing where the action deserves a celebration.
- Confirmed actions: a brief can help users notice the new state.
- Focused modes: use it during checkout, presentations, or review screens where previous context has been replaced with new information.
- Section-level navigation: apply it for navigation that is clearly different, not for every page change in the same area.
Avoid using glimm for:
- Every internal navigation: although
<InterceptLinks />
makes it easy to use everywhere, sweeping the screen with every click reduces its impact. - Passive interactions: includes hover effects, focus, tooltips, dropdowns, and menus.
- Repeated actions in a loop: example includes adding rows, checking off items, or moving through a list.
- or skeleton states: glimm is meant for punctuation, not for spinning indicators.
To determine if a moment needs a glimm sweep, consider whether you would mention it in a changelog or launch post. If yes, then glimm is likely a good fit. If it's just “the user clicked something,” skip it. Using glimm sparingly makes the moments it does highlight more meaningful.