New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

@pariharshyamu/morph

Package Overview
Dependencies
Maintainers
1
Versions
2
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@pariharshyamu/morph

Interrupt-safe DOM morphing with spring physics, FLIP animations, Hungarian algorithm matching, and auto-animate via MutationObserver. Works with htmx, Alpine.js, Turbo, or vanilla JS.

latest
npmnpm
Version
2.0.1
Version published
Maintainers
1
Created
Source

@pariharshyamu/morph

Interrupt-safe DOM morphing with spring physics, FLIP animations, and auto-animate.

morph.js v2 patches your DOM like morphdom, but adds silky smooth animations — spring physics, FLIP transitions, choreographed enter/exit/move, and mid-animation interruption handling.

Features

  • Interrupted animation handling — morphs from current visual position, never snaps
  • Scroll-aware FLIP — corrects getBoundingClientRect across scrolled containers
  • Stacking-context correction — handles CSS transform ancestors
  • Hungarian algorithm matching — optimal global assignment, not greedy
  • Spring physics engine — position/velocity integrator, replaces cubic-bezier
  • Simultaneous move + content morph — FLIP + crossfade in one animation track
  • Choreography model — sequence exits, moves, enters independently
  • MorphObserver — auto-animate any DOM mutations on a container
  • htmx extension — hooks into htmx:beforeSwap / htmx:afterSwap
  • Confidence-gated matching — low-confidence pairs become enter/exit instead

Install

npm install @pariharshyamu/morph

Or use a CDN:

<script type="module">
  import morph from 'https://unpkg.com/@pariharshyamu/morph';
</script>

Quick Start

import morph from '@pariharshyamu/morph';

// Morph an element to new HTML
const result = morph(element, '<div class="card">New content</div>');

// Wait for all animations to complete
await result.finished;

API

morph(fromEl, toElOrHTML, options?)

Patches fromEl to match toElOrHTML (a DOM element or HTML string), animating the transition.

Returns: { animations, finished, debug, cancel() }

Options

OptionDefaultDescription
duration400Base duration in ms
easing'spring''spring' or any CSS easing string
spring{ stiffness: 280, damping: 24, mass: 1 }Spring physics parameters
stagger25Stagger delay between elements (ms)
keyAttribute'data-morph-key'Attribute for explicit element matching
matchConfidenceThreshold1.5Below this → treat as enter/exit
respectReducedMotiontrueSkip animation if user prefers reduced motion
morphContenttrueCross-fade content changes during move
debugfalseLog matching info to console

morph.text(el, newText, options?)

Cross-fade text content change with a fade-out → swap → fade-in sequence.

await morph.text(heading, 'New Title').finished;

morph.prepare(fromEl, toEl, options?)

Create a controllable transition that can be triggered later.

const transition = morph.prepare(el, newEl, { duration: 500 });
transition.play(); // triggers when ready

MorphObserver

Auto-animate any DOM mutations on a container:

import { MorphObserver } from '@pariharshyamu/morph';

const observer = new MorphObserver(container, { duration: 350 });
observer.observe();

// Now any mutation to container's children will auto-animate
container.innerHTML = '<div>New content</div>'; // animated!

observer.disconnect();

htmx Extension

<script src="https://unpkg.com/htmx.org"></script>
<script type="module">
  import morph from '@pariharshyamu/morph';
  morph.htmx({ duration: 350 });
</script>

<div hx-ext="morph" hx-get="/api/items" hx-swap="innerHTML">
  <!-- content swaps are now animated -->
</div>

Choreography

Control the timing of exit, move, and enter phases:

morph(el, newHTML, {
  choreography: {
    exit:  { at: 0,    duration: 0.5  },  // fractions of total duration
    move:  { at: 0.15, duration: 0.85 },
    enter: { at: 0.4,  duration: 0.6  },
  }
});

Custom Hooks

morph(el, newHTML, {
  onEnter: (el) => [
    { opacity: 0, transform: 'translateX(-20px)' },
    { opacity: 1, transform: 'translateX(0)' },
  ],
  onLeave: (el) => [
    { opacity: 1 },
    { opacity: 0, transform: 'scale(0.8)' },
  ],
  onMove: (el, fromRect, toRect) => null, // return keyframes or null
});

License

MIT

Keywords

morph

FAQs

Package last updated on 22 Feb 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts