Skip to content
Esc
↑↓navigate↵open⌘Jpreview
a UI Alchemy project by Omicrxn

Motion-powered animations for Svelte. Attachments, presence, and layout — made the Svelte way.

Explore ↓

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.

Bouncing Easing

Animate

initial, animate and transition, as on a motion.div. Springs, keyframes, easings and per-value transitions, driven by $state.

  • Inbox
  • Drafts
  • Sent
  • Archive

Variants

Name your states once. Labels flow down to children, with staggerChildren, delayChildren and when to orchestrate them.

Drag the card by its handle. It stays inside the area, and the ball snaps back.

Card

Gestures

whileHover, whileTap, whileFocus, whileInView, pan, and Motion's full drag — constraints, elasticity, momentum and drag controls.

One

Presence

Exit animations on Svelte transitions — exit variants, custom, and sync, wait or popLayout modes. No wrapper component.

Layout Animation: Layout ID

Layout

Motion's layout engine: size and position changes, and shared layoutId elements that morph from one into the other.

0%

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.

Motion values

Scroll progress, springs and derived values that render straight to styles, without re-running a line of Svelte.

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}