shadcn.io is not affiliated with official shadcn/ui
A seeded maze fills the box, its walls at a soft 40% and fading toward the edges, while a few lights explore its corridors from the middle outward: each trails a short tail, lights up the walls around it as it passes, runs into side corridors and turns back at dead ends. The maze is carved when the page renders and repeats with no visible seam on wide screens; the walls are one still masked layer, the lights are small dots moved from cell to cell by translate keyframes the install adds to your stylesheet, and their glow shows through a second copy of the maze's mask, so only the nearby walls catch it. Nothing repaints and no script runs.
Use it for puzzle, game or security pages. For a board of traces with signals, use Circuit; for lights racing along an open grid, Laser Grid; for cells that evolve on a grid, Life.
Installation
Usage
import { Labyrinth } from "@/components/ui/labyrinth";Labyrinth is a container: give it a size and put your content inside. The maze sits behind the content and the box clips it.
<Labyrinth className="flex min-h-[420px] items-center justify-center">
<h1 className="text-5xl font-semibold">Find the way through</h1>
</Labyrinth>For a backdrop behind the whole page, leave it empty and fix it under everything else:
<Labyrinth className="fixed inset-0 -z-10" />Demos
Theme colours
By default the maze keeps its signature neon: indigo walls and cyan lights, a deeper cyan on light themes. Here wallColor and lightColor take your theme's colours instead: faint walls in the foreground and lights in the primary colour.
Tighter maze
A denser maze in a dark card: cellSize={24}, count={8} lights and speed={1.5}. On a dark surface in a light theme, pass the pale cyan as lightColor so the lights stay bright.
Accessibility
The maze is decorative: it's hidden from screen readers and lets every click through to your content. With reduced motion the lights stop where they are, a still picture of the maze with a few lit corners. Nothing flashes: the lights glide a cell at a time and the walls brighten and fade as they pass. The walls show at 40% and fade toward the edges, but they still cross under every letter, so keep copy in your foreground colour, put a softly faded panel behind long text or pass a fainter wallColor (about 25% of your foreground); avoid backdrop-blur, which would re-blur the moving lights on every frame.
FAQ
Is the maze different on every visit?
No: it's carved from seed when the page renders, so the server and the browser draw the same maze. Change seed for another one.
What are the lights doing?
Each follows the corridors around its start for 30 steps, on into side corridors and back out of dead ends, the way the maze was carved; then it retraces its way home and starts again, so it never jumps. Its tail is eight fainter dots a fraction of a step behind it, and its glow lights only the walls, through the maze's own mask.
How do I make the maze denser?
Lower cellSize (40 by default); the walls stay 1.5px at any size. count and speed set how many lights explore and how fast.
Why does a small card show fewer lights?
The lights walk the maze's own corridors, so they start from fixed places around the centre: the first ones close to it, the rest over up to 1280×720. count is about how many explore a 1440×900 box; a small card shows a couple.
Can I use my theme's colours instead of neon?
Yes: pass wallColor and lightColor, as in "Theme colours", or set --labyrinth-wall-color and --labyrinth-light-color from your own CSS.
API Reference
Labyrinth
<div> data-slot="labyrinth"
cellSize?number
The side of one maze cell, in pixels; walls stay 1.5px. @default 40.
- Default
40
count?number
About how many lights explore a 1440×900 box. They walk the maze's own corridors from around the centre, over at most 1280×720 (where a radial fade keeps the maze): a small card shows a couple.
- Default
5
lightColor?string
The lights' colour, any CSS colour: their heads, their tails and the walls they light around them.
- Default
a neon cyan, deeper on light themes
seed?number
Another maze: each whole number carves a different one and sends the lights on different tours.
- Default
0
speed?number
How fast the lights move, as a multiplier: 1 is a cell every 380ms.
- Default
1
wallColor?string
The walls' colour, any CSS colour. @default a neon indigo at 40%.
render?ReactElement | ((props: object, state: object) => ReactElement)
Replace the host element or compose it with another component.
- Type
ReactElement | ((props: object, state: object) => ReactElement)
className?string
Merged with the part's classes.
--labyrinth-light-colorstring
The lights' colour (a neon cyan).
--labyrinth-speedstring
How fast the lights move, a multiplier (1).
--labyrinth-wall-colorstring
The walls' colour (a neon indigo at 40%).
Related
- Pro


Traces with signals
- Pro


Lights on an open grid
- Pro


Paths Background
WavesSVG light paths


Grid Pattern
GridsStatic lines
- Pro


Life Background
GenerativeCells evolving on a grid
- Pro


Hexagon Background
GridsAnother tiling