Glimm: Shader Driven Page Transitions

handfuloflight1 pts0 comments

glimm — shader-driven page transitions

glimm<br>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.<br>$npm install glimm<br>Zero runtime dependencies. React 18+ and Next 13+ are peer deps.

Preview

Demos

Demo 1<br>Demo 2<br>Demo 3<br>Demo 4

Installation<br>You can install glimm using npm, or share the following prompt with a coding agent to set it up for you.

$npm install glimm<br>Tell your coding agent<br>Add glimm to my Next.js app.

1. Install it: npm install glimm<br>2. In my root layout, import { GlimmProvider, InterceptLinks } from 'glimm/next', wrap the body's children in , and render just inside it:

{children}

Keep the rest of my layout markup unchanged.

Quick start<br>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.

app/layout.tsx<br>// app/layout.tsx<br>import { GlimmProvider } from 'glimm/next'

export default function RootLayout({ children }) {<br>return (<br>>{children}>

Triggers<br>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 at the root level to automatically apply transitions to all internal links without touching existing code.

useTransitionRouter()

import { TransitionLink } from 'glimm/next'

href="/about" sweep={{ palette: 'berry' }}><br>About

Presets<br>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.

prism<br>berry<br>lagoon<br>citrus<br>azure<br>ember

Easing<br>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.

snaplineareaseeaseOutQuarteaseInCubiceaseInOutCubiceaseOutExpoback

Preview

Band width<br>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.

bandTight 14

Drag across the band to tune its width. Lower = wider, softer; higher = tighter, more concentrated.

Preview

Custom palette<br>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.

Shuffle<br>custom-palette.tsx

palette={{<br>a: [0.46, 0.88, 0.33],<br>b: [0.60, 0.58, 0.74],<br>c: [0.50, 0.50, 0.50],<br>d: [0.54, 0.22, 0.84],<br>}}<br>{children}

Props<br>Everything you can pass to GlimmProvider (as defaults) or any trigger (as per-call overrides). Every option is optional.

PropTypeDefaultDescriptionpalettePaletteName | Palette'prism'6 presets or BYO {a,b,c,d}.direction'ltr' | 'rtl' | 'ttb' | 'btt''ltr'Sweep axis + side.easingEasingName | (p) => number'easeInOutCubic'10 built-ins or custom curve.sweepMsnumber800Band traversal duration.outroMsnumber350Post-traversal alpha fade.midpointnumber0.5When routes swap mid-sweep.peakAlphanumber1Caps band peak (0..1.5).brightnessnumber1RGB scale; ~0.85 on dark.bandTightnumber14Tightness; lower = wider.waveAmountnumber1Edge wave turbulence.rippleAmountnumber1Vertical ripple texture.waveSpeednumber1Shader animation speed.

Best practices<br>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:<br>•Moments like publishing, submitting or completing where the action deserves a celebration.<br>•Confirmed actions: a brief pause can help users notice the new state.<br>•Focused modes: use it during checkout, presentations, or review screens where previous context has been replaced with new information.<br>•Section-level navigation: apply it for navigation that is clearly different, not for every page change in the same area.

Avoid using glimm for:<br>•Every internal navigation: although makes it easy to use everywhere, sweeping the screen with every click reduces its impact.<br>•Passive interactions: includes hover effects, focus, tooltips, dropdowns, and...

glimm palette band next sweep transitions

Related Articles