Motion-powered animations for Svelte. Attachments, presence, and layout — made the Svelte way.
Built on Motion
Every Motion feature, none of the wrappers.
Mercury runs Motion's own engine — its animation state, variants, gestures, drag and layout projection — and puts it on your elements through Svelte attachments and transitions. Motion's props keep their names, so you already know the API. Every demo below is live: try them.
- Inbox
- Drafts
- Sent
- Archive
Drag the card by its handle. It stays inside the area, and the ball snaps back.
Card
Layout Animation: Layout ID
Paragraph 1. Mercury's scrollValues() exposes Motion's scroll position
and progress as motion values, which style renders without re-running any Svelte
code.
Paragraph 2. Mercury's scrollValues() exposes Motion's scroll position
and progress as motion values, which style renders without re-running any Svelte
code.
Paragraph 3. Mercury's scrollValues() exposes Motion's scroll position
and progress as motion values, which style renders without re-running any Svelte
code.
Paragraph 4. Mercury's scrollValues() exposes Motion's scroll position
and progress as motion values, which style renders without re-running any Svelte
code.
Paragraph 5. Mercury's scrollValues() exposes Motion's scroll position
and progress as motion values, which style renders without re-running any Svelte
code.
Paragraph 6. Mercury's scrollValues() exposes Motion's scroll position
and progress as motion values, which style renders without re-running any Svelte
code.
Paragraph 7. Mercury's scrollValues() exposes Motion's scroll position
and progress as motion values, which style renders without re-running any Svelte
code.
Paragraph 8. Mercury's scrollValues() exposes Motion's scroll position
and progress as motion values, which style renders without re-running any Svelte
code.
One attachment
State in, motion out.
Derive animate from $state and the element animates whenever it changes. Each re-run of the attachment updates the same Motion node, like a React re-render: only what changed animates, and a hover or drag in progress carries on. Add transition:presence and the element plays its exit before Svelte removes it.
- <motion.div animate whileHover drag>
- {@attach mercury({ animate, whileHover, drag })}
- <AnimatePresence>
- transition:presence
- layout / layoutId
- mercury({ layout, layoutId })
- <MotionConfig>
- {@attach motionConfig({ … })}
- useScroll()
- scrollValues()
<script>
import { mercury, presence } from '@omicrxn/mercury';
let open = $state(false);
</script>
<button
onclick={() => (open = !open)}
{@attach mercury({
animate: { rotate: open ? 180 : 0 },
whileHover: { scale: 1.05 },
whileTap: { scale: 0.9 },
transition: { type: 'spring', bounce: 0.4 }
})}
>
Toggle
</button>
{#if open}
<div
transition:presence
{@attach mercury({
initial: { opacity: 0, y: 8 },
animate: { opacity: 1, y: 0 },
exit: { opacity: 0, y: 8 }
})}
>
Hello
</div>
{/if}