Film grain that makes solid fills and gradients feel photographed, not rendered.
npm install @caustics/noise-grain <script> import { NoiseGrain } from '@caustics/noise-grain'; </script> <NoiseGrain preset="film" />
npm install @caustics/noise-grain import { NoiseGrain } from '@caustics/noise-grain/react'; return <NoiseGrain preset="film" />;
npm install @caustics/noise-grain import { mount } from '@caustics/noise-grain'; mount(document.querySelector('#hero'), { preset: 'film' });
| Prop | Type | Default | Description |
|---|---|---|---|
| preset | string | "film" | Named preset. Overrides individual props when set. |
| colors | string[] | undefined | Override palette. Accepts hex, hsl, or CSS custom properties. |
| reducedMotion | 'pause' | 'static' | 'pause' | Behavior when prefers-reduced-motion is active. |
| class | string | undefined | Additional CSS classes applied to the root element. |
caustics-noise-grain/ ├── svelte/ NoiseGrain.svelte · index.ts · types.ts ├── react/ NoiseGrain.tsx · index.ts · types.ts ├── vanilla/ noise-grain.ts · compiled .js ├── docs/ README.md · API.md · CHANGELOG.md ├── LICENSE.md Caustics Commercial License └── package.json
Noise Grain adds an organic texture layer over any background. At 3% opacity it’s imperceptible but makes the site feel alive — exactly what you see on this page. At higher opacities it creates a film grain aesthetic that pairs beautifully with dark UI. The overlay sits above your content (pointer-events: none, a CSS blend mode), so it never blocks interaction or touches your layout.
Three rendering modes behind one mode prop: a lightweight CSS SVG feTurbulence filter (no per-frame JS), Canvas 2D pixel manipulation, and a WebGL fragment shader (smoothest at full-screen high-DPI). Set mode: 'auto' and the engine resolves to the best available backend — WebGL → Canvas → CSS — falling back gracefully when one isn’t available.
Four presets (Film, Fine, Coarse, Vintage), monochrome or coloured grain, configurable intensity, grain size, animation speed, blend mode, and contrast. Ships Svelte 5, React, and vanilla adapters with a full lifecycle: reduced-motion support (static-frame hold), off-screen pause, WebGL context-loss recovery, and a typed events API. ~8 KB gzipped.
Caustics Commercial License · lifetime updates within v1