README.md

astro-dither

Dither for Astro, based on Leo's dithercn.

npm version npm downloads CI MIT licence

Website (placeholder URL, deployment pending) · Docs · Examples · npm

The landing page hero: a dithered aurora over a starfield

Animated dither backgrounds, gradients and image effects for Astro. No React.

Features

  • No React. Plain Astro components and one custom element. Nothing to hydrate.
  • 19 effects in one registry: aurora, waves, plasma, silk, smoke, contours, ripples, metaballs, tunnel, retro-grid, starfield, eclipse, globe, gradient, glow, mesh, beams, noise, rise.
  • Image dithering that keeps the real img and its alt text in the tree.
  • One shared WebGL context for every ordered-dither surface on a page, so many tiles cost about the same as one.
  • Pauses itself offscreen and in hidden tabs. Respects prefers-reduced-motion.
  • Typed props per effect. Your editor lists only the settings an effect has.
  • Copy-source CLI for projects that want the code in their own repo.

Install

sh
1pnpm add astro-dither
sh
1npm i astro-dither
sh
1bun add astro-dither

Quick start

astro
1---
2import { DitherAurora } from "astro-dither";
3---
4
5<section style="height: 100svh">
6 <DitherAurora />
7</section>

Any of the 19 effects works the same way:

astro
1<DitherEffect effect="plasma" />

Components

ComponentWhat it doesDocs
DitherPaper's animated dither shapes: sphere, warp, wave, ripple, swirl, dots.API
DitherImageOrdered dithering over any image. Keeps the img and its alt.API
DitherGradientLinear, radial, conic or wave gradients.API
DitherAuroraThe aurora effect with all its knobs.API
DitherEffectAny of the 19 effects below, animated or still.API
DitherGlobeAn orthographic globe dithered from a land mask.API

Effects

GroupEffects
Gradients and glowsgradient, glow, mesh, beams, rise
Texturesnoise, plasma, silk, smoke, waves
Patternscontours, ripples, metaballs, tunnel, retro-grid
Scenesaurora, starfield, eclipse, globe

Every effect takes the same props: params (its own typed settings), palette (2 to 8 colours), cell, matrix (Bayer 2x2, 4x4, 8x8 or noise), speed, class. The full parameter tables are in the package README.

Copy the source

Prefer owning the code instead of a dependency? Copy the components into your project:

sh
1npx astro-dither add aurora
  • npx astro-dither add aurora image globe copies several at once.
  • --dir src/components/ui changes the target directory (default src/components/dither).
  • --force overwrites existing files; without it, changed files are skipped.
  • npx astro-dither list shows all six components.
  • all copies everything, including the engine.

Relative imports and assets (like the globe's land mask) are followed automatically.

How it works

Each component renders a <dither-surface> element with its settings serialised into a data attribute at build time. A small custom element mounts in the browser, opens one WebGL2 context shared by every ordered-dither surface on the page, and draws each effect's GLSL field through a Bayer threshold matrix into the palette. DitherImage uses the same idea on an image texture, in its own context, and leaves the original img in place so alt text, readers and no-JS still work.

Browser support and accessibility

  • Requires WebGL2. Where a surface cannot start it stays blank; DitherImage falls back to the plain img.
  • Backgrounds render aria-hidden so screen readers skip them.
  • prefers-reduced-motion gets a still frame: every surface draws its stillTime frame once and stops.
  • IntersectionObserver and visibilitychange pause rendering offscreen and in hidden tabs.

Repository layout

1packages/astro-dither/ the npm package (components, engine, CLI, tests)
2site/ the Astro site on astro-dither.vercel.app
3scripts/ repo scripts (favicon generator)
4assets/ icon and README images
5.github/ CI workflow, issue templates, dependabot

Development

Requires Node 22.23.4 or newer (.nvmrc) and pnpm (packageManager pins 12.11.2).

sh
1pnpm install # install the workspace
2pnpm dev # site at http://localhost:4321
3pnpm test # vitest on the package
4pnpm check # astro check on package and site
5pnpm build # build the site into site/dist
6node scripts/favicon.mjs # regenerate favicons into site/public

Deploying the site

The site deploys to Vercel from the repo root. Import the GitHub repo and Vercel reads vercel.json: framework astro, install pnpm install --frozen-lockfile, build pnpm build, output site/dist. Nothing else to set. The production URL is picked up automatically for absolute OG tags; set SITE_URL only if you need to override it.

Releasing

  1. Bump version in packages/astro-dither/package.json.
  2. Add an entry to packages/astro-dither/CHANGELOG.md.
  3. pnpm run ci should be green.
  4. pnpm --filter astro-dither publish --access public.

Contributing

See CONTRIBUTING.md. Bug reports and feature requests go through GitHub issues; security reports through private vulnerability reporting.

Credits

Licence

MIT, Screen 2026.