npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

motionforge

v1.3.0

Published

A React-based framework for creating videos programmatically. Build stunning videos with React components, spring animations, and frame-perfect control.

Readme

MotionForge


✨ Features

  • 🎬 Frame-Based Rendering - Precise control over every frame
  • 🎨 70+ Effect Components - Fade, Scale, Slide, 3D transforms, particles, and more
  • 🌊 Spring Physics - Natural, physics-based animations
  • 📊 Interpolation System - Smooth transitions with 20+ easing functions
  • 🎮 Interactive Player - Real-time preview with timeline controls
  • 📦 Frame Caching - LRU cache for optimized performance
  • 🎥 Video Export - WebM encoding with MediaRecorder API
  • 🎯 TypeScript First - Full type safety out of the box

📦 Installation

# npm
npm install motionforge

# yarn
yarn add motionforge

# pnpm
pnpm add motionforge

# bun
bun add motionforge

🚀 Quick Start

import { 
  AbsoluteFill, 
  useCurrentFrame, 
  interpolate,
  spring,
  Player 
} from 'motionforge';

// Create a video composition
const MyVideo = () => {
  const frame = useCurrentFrame();
  const { fps } = useVideoConfig();
  
  // Spring animation
  const scale = spring({
    frame,
    fps,
    config: { damping: 10, stiffness: 100 }
  });
  
  // Interpolation
  const opacity = interpolate(frame, [0, 30], [0, 1], {
    extrapolateRight: 'clamp'
  });
  
  return (
    <AbsoluteFill 
      style={{ 
        justifyContent: 'center', 
        alignItems: 'center',
        backgroundColor: '#0a0a0a'
      }}
    >
      <h1 style={{ 
        opacity, 
        transform: `scale(${scale})`,
        fontSize: 72,
        color: '#10b981'
      }}>
        Hello MotionForge!
      </h1>
    </AbsoluteFill>
  );
};

// Use with Player
const App = () => (
  <Player
    component={MyVideo}
    durationInFrames={150}
    fps={30}
    width={1920}
    height={1080}
    controls
    loop
  />
);

🎨 Available Components

Layout Components

| Component | Description | |-----------|-------------| | AbsoluteFill | Full-screen container with absolute positioning | | Sequence | Time-based rendering for scene management | | Loop | Loop content infinitely or for a set number of times | | Freeze | Pause content at a specific frame | | Retiming | Variable speed playback | | Reverse | Play content backwards | | Series | Sequential scene management |

Effect Components

import { 
  Fade, Scale, Slide, Rotate,
  Typewriter, Counter, NeonGlow,
  Rotate3D, Cube3D, Perspective3D,
  ParticleSystem, Confetti,
  LetterByLetter, WaveText, RainbowText
} from 'motionforge';

// Example: 3D rotating cube
<Cube3D size={100} durationInFrames={120} />

// Example: Letter by letter animation
<LetterByLetter 
  text="Hello World" 
  animation="scale" 
  delayPerLetter={3} 
/>

// Example: Particle system
<ParticleSystem 
  count={100} 
  direction="up" 
  colors={['#10b981', '#34d399']} 
/>

Animation Functions

import { spring, interpolate, Easing } from 'motionforge';

// Spring physics
const value = spring({
  frame: 30,
  fps: 30,
  config: { damping: 10, stiffness: 100, mass: 1 }
});

// Interpolation with easing
const progress = interpolate(frame, [0, 60], [0, 100], {
  easing: Easing.easeOutCubic,
  extrapolateLeft: 'clamp',
  extrapolateRight: 'clamp'
});

// Available easing functions
Easing.linear
Easing.easeInQuad, Easing.easeOutQuad, Easing.easeInOutQuad
Easing.easeInCubic, Easing.easeOutCubic, Easing.easeInOutCubic
Easing.easeInElastic, Easing.easeOutElastic
Easing.easeInBounce, Easing.easeOutBounce
// ... and more!

🎥 Video Export

import { 
  VideoExportManager, 
  downloadVideo,
  checkEncodingSupport 
} from 'motionforge';

// Check browser support
const support = checkEncodingSupport();
console.log('WebM support:', support.webm);
console.log('Available codecs:', support.codecs);

// Export video
const manager = new VideoExportManager();
const result = await manager.exportFromCanvas(canvas, {
  config: { width: 1920, height: 1080, fps: 30, durationInFrames: 150 },
  onProgress: (progress) => {
    console.log(`Progress: ${progress.percentage.toFixed(1)}%`);
  }
});

if (result.success && result.blob) {
  downloadVideo(result.blob, 'my-video.webm');
}

🎯 Performance Optimization

import { 
  useMemoizedFrame,
  useOptimizedSpring,
  usePrecomputeFrames,
  FrameCache 
} from 'motionforge';

// Memoize expensive computations
const value = useMemoizedFrame(() => expensiveCalculation(), [deps]);

// Pre-compute upcoming frames
const frameCache = usePrecomputeFrames(
  (frame) => computeValue(frame),
  10 // lookahead
);

// Cached spring animation
const scale = useOptimizedSpring({ damping: 10 }, 0, 1);

📚 API Reference

Hooks

| Hook | Description | |------|-------------| | useCurrentFrame() | Returns the current frame number | | useVideoConfig() | Returns video configuration { fps, width, height, durationInFrames } | | useSpring(config) | Creates spring-based animations | | useInterpolate(inputRange, outputRange, options) | Interpolates values with easing |

Utility Functions

| Function | Description | |----------|-------------| | spring({ frame, fps, config }) | Calculate spring animation value | | interpolate(input, inputRange, outputRange, options) | Map values between ranges | | interpolateColors(input, inputRange, outputRange) | Smooth color transitions | | random(seed) | Deterministic random number generator | | noise2D(x, y) | Perlin noise function |

🎨 Theming

MotionForge uses a dark theme by default with emerald green accents. Customize colors using CSS variables:

:root {
  --mf-primary: #10b981;
  --mf-secondary: #34d399;
  --mf-background: #0a0a0a;
  --mf-surface: #0f0f0f;
  --mf-border: rgba(16, 185, 129, 0.3);
}

🎭 Using Lottie in MotionForge

MotionForge provides first-class, production-grade Lottie support. Animations are synchronized with the frame system for deterministic, frame-perfect rendering.

Basic Usage

import { Lottie, AbsoluteFill } from 'motionforge';

const MyComposition = () => {
  return (
    <AbsoluteFill>
      <Lottie
        src="https://assets.lottiefiles.com/packages/lf20_u4j3X6.json"
        width={400}
        height={400}
      />
    </AbsoluteFill>
  );
};

Advanced Configuration

The Lottie component supports several props to control playback and appearance:

| Prop | Type | Default | Description | |------|------|---------|-------------| | src | string \| object | - | URL to JSON or imported JSON object | | frameStart | number | 0 | The frame at which the Lottie starts | | frameEnd | number | - | The frame at which the Lottie ends | | playbackRate | number | 1 | Speed of the animation | | loop | boolean | false | Whether to loop the animation | | width | number \| string | 100% | Width of the container | | height | number \| string | 100% | Height of the container |

Syncing with Sequences

Lottie automatically detects if it's inside a Sequence and adjusts its internal timing to match the relative frame.

<Sequence from={30} durationInFrames={120}>
  <Lottie
    src={myAnimationData}
    playbackRate={1.5}
    loop
  />
</Sequence>

Performance Tips

  1. Pre-loading: For imported JSON objects, Lottie initializes instantly. For URLs, it fetches the data once and memoizes the instance.
  2. SSR Support: The component handles server-side rendering gracefully by only initializing the Lottie engine on the client.
  3. Memoization: Internal animation instances are memoized and properly cleaned up to prevent memory leaks.

📖 Documentation

🤝 Contributing

We welcome contributions! Please see our Contributing Guide for details.

📝 License

MIT License - see LICENSE for details.

🙏 Acknowledgments

Inspired by Remotion - The original React video framework.