The lightbox for Svelte.
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.
A Svelte 5 port of ramka, the React lightbox by Artur Bień, ported with his blessing. Using React? Install @ramka/react.
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.
Morph view transitions
Shared-element View Transitions morph anything into the lightbox and back: images, video, plain HTML. Browsers without the API get a clean crossfade.
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.
Headless and unstyled
Composable Svelte 5 components in the shape you know from Bits UI and Melt: Trigger, Slides, Zoom, Captions, Thumbnails, Counter. Snippets and bindings instead of render props. 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, and thumbnails.
Typed and small
Fully typed, tree-shakeable, zero runtime dependencies beyond Svelte itself. The same engine as the React original, rewritten on runes.
Images, video, anything
Photos, videos, 3D models, or any Svelte content. Plain img with width and height, srcset, or enhanced:img from SvelteKit.
“I’d rather eat glass than build this again.”
Artur Bień · creator of ramka
Exhibit A: what building a lightbox does to a person. ramka exists so it never has to happen to you, now in Svelte too.
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 |