Skip to content
Kura UI

Grain

beta

Film-grain overlay from a cached SVG-noise tile, with blend modes and an optional compositor-only flicker — texture for gradients and heroes.

@kura-ui/react/grainCopy page for agents.mdregistry.json

Grain over a gradient

minimal

Blend modes, opacity, scale, flicker

Compare every blend mode on a light and a dark surface.

full

On a mesh gradient

The classic pairing: MeshGradient with Grain as its last child.

composition

A little grain turns a gradient into a print.

Installation

npx shadcn@latest add https://kuro.abstergo.fyi/r/grain.json

Copies the source into components/kura/grain with its dependencies (kura-theme, utils). Tokens come from the kura-theme item.

When to use it

Use it for

  • Adding a print-like finish on top of a mesh-gradient, aurora or photo.
  • Hiding colour banding on large, low-contrast gradients.
  • Giving a flat hero or empty-state panel a subtle tactile texture.

Reach for something else when

  • As the background itself — combine it with mesh-gradient or aurora.
  • Over body text or dense UI: noise reduces legibility.
  • Signalling activity — grain is texture; use border-beam or thinking-indicator.

Props

PropTypeDefaultDescription
opacitynumber0.12Strength of the grain, 0–1. 0.08–0.2 is subtle; 0.3+ is stylised.
blend"overlay" | "soft-light" | "multiply" | "screen" | "normal""overlay"mix-blend-mode. overlay works on mid and dark tones; multiply suits light surfaces; screen suits very dark ones.
scalenumber1Grain size multiplier: 1 is fine film grain, 2–3 is coarse.
animatedbooleanfalseFlicker the grain like projected film (a stepped transform, compositor-only). Off by default.
fpsnumber12Flicker rate when animated. 8–15 reads as film; higher looks like TV static.

All native attributes of the root element, className and ref pass through.

Anatomy

  1. GrainAbsolutely positioned overlay (`inset-0`, pointer-events none, overflow hidden) carrying opacity and blend mode. `data-animated` mirrors `animated`.data-slot="grain"
  2. LayerOversized noise layer (200%) that the flicker translates.data-slot="grain-layer"

Accessibility

  • Decorative and aria-hidden; it never receives pointer events.
  • Keep opacity low over text; grain can lower perceived contrast.
  • Reduced motion: The flicker stops; the grain stays as a static texture.

Notes for agents

  • The parent must be positioned (`relative`) — Grain is `absolute inset-0`. Render it last so it sits on top, and lift text above it with `relative z-10` if needed.
  • Server-safe: no hooks, no 'use client'.
  • On near-white surfaces `overlay` is almost invisible by design; use `blend="multiply"` with opacity ~0.06 there.
  • One Grain per surface; it tiles a 180px image, so cost does not grow with size.