# Glimm: Shader Driven Page Transitions

> Source: <https://glimm.dev/>
> Published: 2026-06-24 04:33:41+00:00

# glimm

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](#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](#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](#triggers) 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](#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](#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)

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](#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](#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' | 6 presets or BYO {a,b,c,d}. |
| direction | 'ltr' | 'rtl' | 'ttb' | 'btt' | 'ltr' | Sweep axis + side. |
| easing | EasingName | (p) => number | 'easeInOutCubic' | 10 built-ins or custom curve. |
| 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](#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 pause 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.
- Loading 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.
