The lightbox for React.
Unstyled, accessible primitives built on native scrolling and view transitions. Morph, swipe, zoom, and pull-to-dismiss, all out of the box.
Click any image. Swipe, pinch to zoom, pull to dismiss.
Powering galleries at
- Mintlify
- Whop
- Paper
- Operate
Everything a lightbox should do.
An image viewer that feels like the native photos app, from gestures to keyboard and screen-reader support. Zero opinions about how your gallery looks.
Native scrolling
Slides ride real CSS scroll snapping, not a transform-emulated carousel. Swiping feels native because it is.
Pinch to zoom
Pinch on touch or trackpad, double-tap to zoom, ctrl + scroll to zoom at the cursor. Pan with a finger, mouse, or arrow keys.
Pull to dismiss
Drag down on touch or wheel on a trackpad to close, like every photos app. Elastic, interruptible, and aware of zoom and in-flight swipes.
Headless and unstyled
Composable primitives with the API you know from Radix UI and Base UI: Trigger, Slides, Zoom, Captions, Thumbnails, Counter. Right at home in a shadcn/ui codebase. You own every pixel.
Accessible by default
A focus-trapped dialog with full keyboard navigation: arrows, Escape, and zoom shortcuts. Screen-reader naming hooks built in, and prefers-reduced-motion respected.
RTL support
One dir="rtl" mirrors slide order, arrow keys, thumbnails, and even the morph geometry.
Typed and tiny
Fully typed, tree-shakeable, zero runtime dependencies. The zoom, morph, and pull engines lazy-load on demand, so a full gallery ships around 19 KB gzipped up front.
Images, video, anything
Photos, videos, 3D models, or any React content. Responsive srcset images and first-class Next.js Image support.

“I’d rather eat glass than build this again.”
Artur Bień · the guy who built this
Exhibit A: what building a lightbox does to a person. ramka exists so it never has to happen to you.
Dropping frames strictly prohibited.
How it compares.
Nobody chooses a lightbox. You inherit one from 2013, or you decide to build your own. Here is how that goes.
| ramka | the one you’d build | that 2013 plugin | |
|---|---|---|---|
| Morph transitions | FLIP, take 3 | fade() | |
| Native scrolling | translateX | arrows | |
| Pinch, pan, flick | sprint 14 | mouse only | |
| Pull to dismiss | in the backlog | Esc | |
| Keyboard, a11y | TODO | nope | |
| Respects reduced motion | oops | always has | |
| Your design, not a theme | to be fair, yes | skin.css |
Launch week: intro pricing
From $79. Once.
Free for open source under the GPL. For proprietary software, a one-time license (solo or whole-team, depending on the tier) is yours forever. No subscription, no per-seat pricing.
Proceeds fund the ongoing fight against scroll emulation.