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

filmless

v0.1.1

Published

Record a web app session, edit it like code, render a crisp README GIF. vhs for web apps.

Readme

filmless

Screen recording you can edit like code. Record a real session in your web app once, then retime it, move a camera over it, and render a crisp, deterministic GIF — from the same take, forever.

Live demo (not a video — the actual DOM replay with edit sliders): filmless.vercel.app

filmless demo

This GIF was rendered by filmless itself: one recorded session, auto-edited by filmless suggest.

Why

  • Screen recordings are single-use. Want the zoom 0.3s later? Re-record everything.
  • filmless records the DOM, not pixels (via rrweb). The edit is a JSON file. The render is a pure function of time — byte-identical every run, at any resolution.
  • Think vhs, but for web apps instead of terminals.

Quickstart

npm i -g filmless      # needs Node 20+, Chrome, ffmpeg

filmless record http://localhost:3000   # interact with your app, Ctrl+C when done
filmless suggest                        # drafts reel.json: auto-zooms on clicks, cuts idle time
filmless render -o demo.gif             # headless re-render → palette-optimized GIF

Preview and tune the edit live:

filmless preview        # http://localhost:4300 — edit reel.json, refresh

The edit file

reel.json is the whole edit. Version it next to your code.

{
  "session": "session.json",
  "output": { "file": "demo.gif", "width": 1120, "fps": 30, "gifFps": 20, "colors": 96 },

  // session time (ms): speed through or cut the boring parts
  "retime": [
    { "from": 4200, "to": 9800, "speed": 4 },
    { "from": 12000, "to": 15000, "cut": true }
  ],

  // output time: [t, centerX, centerY, zoom] — repeat a keyframe to hold the shot
  "camera": [
    [0,    960, 540, 1.0],
    [1200, 960, 540, 1.0],
    [1700, 640, 380, 1.5],
    [3500, 640, 380, 1.5]
  ],

  "cursor": { "show": true, "clickRipples": true, "smooth": 120 }
}

filmless suggest generates a draft from your session (zoom toward clicks, collapse gaps > 2s, wide bookends). Then you just adjust numbers.

Commands

filmless record <url>  [-o session.json] [--viewport 1280x800] [--canvas]
filmless suggest [session.json] [-o reel.json]
filmless render  [reel.json | session.json] [-o demo.gif] [--frames a,b] [--mp4] [--auto]
filmless preview [reel.json] [--port 4300]
  • render session.json with no reel = plain 1x render.
  • --frames 120,180 renders a slice for fast iteration.
  • --auto = suggest + render in one shot.

How it works

  1. record opens your app in Chrome and captures every DOM mutation, input, scroll, and mouse move as rrweb events. Data, not pixels — so text stays text.
  2. render rebuilds the session in headless Chrome and steps it frame by frame with replayer.pause(t) — each frame is a pure function of time. CSS transitions are disabled at replay so nothing depends on wall-clock. Camera is a single transform on a wrapper; the cursor is synthetic and smoothed.
  3. ffmpeg packs the frames with a diff-based palette (palettegen stats_mode=diff + paletteuse diff_mode=rectangle) — UI demos with static backgrounds compress extremely well.

The official rrweb→video tool (rrvideo) plays the session in real time and screenshots on a timer — dropped frames, no editing. Stepping virtual time instead is the whole trick.

Limitations (honest ones)

filmless replays the DOM, so anything that never enters the DOM never renders:

  • cross-origin iframes (Stripe checkout, embedded YouTube)
  • <video> pixel content — playback events replay, pixels don't
  • browser-native UI: file pickers, permission prompts, <select> popups
  • canvas requires --canvas at record time (heavier sessions)
  • native desktop apps — for terminals, use vhs

Requirements

  • Node ≥ 20
  • Chrome/Chromium/Edge (auto-discovered; override with CHROME=/path/to/chrome)
  • ffmpeg on PATH (brew install ffmpeg / apt install ffmpeg)

License

MIT