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

sardonic

v1.0.3

Published

Corner-dwelling chaos creature inspired with a glitchy aesthetic

Readme

sardonic 📺

Corner-dwelling chaos cat inspired by Max Headroom's glitchy aesthetic

"M-M-M-sardonic reporting for d-d-duty!"

The Philosophy

Max Headroom was groundbreaking. In 1985, that stuttering, glitching, rotating talking head was like nothing else on television. The genius wasn't just the character—it was the chaos:

  • Random rotation angles
  • Unpredictable pauses
  • Visual noise and distortion
  • That VHS aesthetic
  • The feeling that reality was breaking down

Nobody has ever beaten Max Headroom. All we can do is pay homage.

sardonic brings that aesthetic to your narration videos. A corner-dwelling cat that seems to be talking, glitching, existing in that liminal space between signal and noise.

What It Does

Takes multiple image frames (like different cat expressions generated by Midjourney) and creates a chaotic talking head animation by:

  1. Random Selection: Picks frames randomly
  2. Random Duration: Each frame plays 0.1-2 seconds (configurable)
  3. Random Rotation: Rotates ±15° (configurable) around center
  4. Glitch Effects: Scanlines, noise, chromatic aberration
  5. Corner Overlay: Places in video corner with alpha transparency

The result: A cat that looks like it's talking, with Max Headroom's signature chaos.

Quick Start

# Create sardonic animation
sardonic --frames "cat-*.jpg"

# Overlay on existing video
sardonic --overlay narration.mp4 --position bottom-right

# Full glitch chaos
sardonic --glitch 3 --rotation 30 --duration 45

Installation

Requires:

  • Node.js
  • ffmpeg
  • ImageMagick (for rotation)
npm install  # (no dependencies needed!)

Usage

Basic Animation

sardonic \
  --frames "sunglasses-kitten*.jpg" \
  --duration 30 \
  --size 320 \
  --glitch 2

Overlay on Video

# Two-step process
sardonic --frames "cat*.jpg" -o headroom.mp4
sardonic --overlay my-narration.mp4 -o final.mp4

# One-step process
sardonic --frames "cat*.jpg" \
  --overlay my-narration.mp4 \
  --position bottom-left \
  --margin 40 \
  -o final.mp4

Command Line Options

Basic Options

  • -f, --frames <pattern> - Frame file pattern (default: sunglasses-kitten*.jpg)
  • -D, --dir <path> - Directory with frames (default: .)
  • -d, --duration <sec> - Animation duration (default: 15)
  • -s, --size <pixels> - Output size, square (default: 320)
  • -r, --rotation <deg> - Max rotation angle (default: 15)
  • -g, --glitch <0-3> - Glitch level (default: 1)
  • -o, --output <file> - Output filename

Overlay Options

  • -O, --overlay <video> - Input video to overlay on
  • -p, --position <pos> - Position: bottom-right, bottom-left, top-right, top-left
  • -m, --margin <pixels> - Margin from edges (default: 20)

Glitch Levels

Level 0: Clean

  • No effects
  • Just rotation and timing
  • Good for professional contexts

Level 1: Classic (Default)

  • Scanlines (the Max Headroom signature)
  • Subtle but recognizable
  • Perfect balance

Level 2: Medium Chaos

  • Scanlines
  • Temporal noise
  • VHS feel

Level 3: MAXIMUM CHAOS

  • Scanlines
  • Heavy noise
  • Chromatic aberration
  • Full 1980s video breakdown

The Midjourney Workflow

This is where it gets powerful. Here's the strategy:

1. Generate Base Character

sunglasses cat portrait, 80s aesthetic, neon colors,
pixelated background, VHS quality, Max Headroom style
--ar 1:1 --stylize 750

2. Generate Expressions (using Character Reference)

[paste image URL] --cref [character URL] --cw 100

Variations to generate:
- mouth open
- mouth closed
- eyes wide
- eyes squinting
- tongue out
- winking
- side glance
- surprised look

3. Generate Glitch Frames (optional)

[paste image URL] VHS distortion, signal interference,
scan lines, color bleeding, tracking errors --cref [character URL]

4. Name Your Files

sunglasses-kitten-open.jpg
sunglasses-kitten-closed.jpg
sunglasses-kitten-wink.jpg
sunglasses-kitten-surprise.jpg
sunglasses-kitten-glitch1.jpg
sunglasses-kitten-glitch2.jpg

5. Run sardonic

sardonic --frames "sunglasses-kitten*.jpg" \
  --duration 60 --glitch 2 --rotation 20

The magic: Random selection + random rotation + random timing = talking head

Why This Works

The human brain is incredible at pattern recognition. When we see:

  1. An image rotating slightly
  2. Changing at irregular intervals
  3. Different mouth positions
  4. All synced roughly to audio rhythm

We perceive: "This character is talking!"

Add scanlines and glitch? "This character is from 1985!"

It's the same principle that made Max Headroom work. The chaos approximates life.

Technical Details

How Rotation Works

Uses ImageMagick to rotate each frame around its center:

convert input.jpg \
  -resize 320x320^ \
  -gravity center \
  -extent 320x320 \
  -background none \
  -rotate 12.5 \
  -extent 320x320 \
  output.png

The double extent ensures the rotated image stays centered and doesn't get cropped.

How Glitches Work

Scanlines (Level 1+):

geq='r=r(X,Y):g=g(X,Y):b=b(X,Y):a=if(not(mod(Y\,3)),255,a(X,Y))'

Makes every 3rd line more opaque.

Noise (Level 2+):

noise=alls=10:allf=t+u

Temporal noise that varies per frame.

Chromatic Aberration (Level 3):

split, offset red/green channels, overlay

Simulates lens distortion.

How Overlay Works

ffmpeg's overlay filter with alpha channel:

[1:v]format=yuva420p[overlay];
[0:v][overlay]overlay=x:y:shortest=1

Positions calculated dynamically based on video size.

Creative Tips

Syncing to Narration

For best results:

  1. Generate sardonic to match narration length
  2. Edit your narration with clear phrases
  3. The random cuts will naturally sync to speech patterns
  4. Works surprisingly well without explicit timing!

Multiple Characters

# Generate separate headrooms for different speakers
sardonic --frames "host*.jpg" -o host.mp4
sardonic --frames "guest*.jpg" -o guest.mp4

# Overlay both (requires manual ffmpeg)
ffmpeg -i video.mp4 -i host.mp4 -i guest.mp4 \
  -filter_complex "[0:v][1:v]overlay=W-w-20:H-h-20[tmp];[tmp][2:v]overlay=20:H-h-20" \
  output.mp4

Match Your Aesthetic

Corporate/Professional:

  • --glitch 0 - No effects
  • --rotation 5 - Subtle movement
  • Clean frames, neutral expressions

Retro/Fun:

  • --glitch 2 - Medium chaos
  • --rotation 15 - Default energy
  • Neon colors, sunglasses

Experimental/Art:

  • --glitch 3 - Maximum chaos
  • --rotation 45 - Wild rotation
  • Include glitch frames, distorted expressions

Frame Count Sweet Spot

  • 2-3 frames: Minimal, clean cuts
  • 4-6 frames: Good variety (recommended)
  • 8-12 frames: Lots of expression
  • 15+ frames: May become too chaotic

More frames = more unique moments = more apparent "talking"

Examples

Example 1: Educational Video

# Generate professor cat expressions
# sunglasses-prof-explaining.jpg
# sunglasses-prof-thinking.jpg
# sunglasses-prof-pointing.jpg

sardonic \
  --frames "sunglasses-prof*.jpg" \
  --duration 180 \
  --glitch 1 \
  --rotation 10 \
  --overlay lecture.mp4 \
  --position top-right \
  -o lecture-with-prof.mp4

Example 2: Podcast

# Generate multiple emotion frames
sardonic \
  --frames "podcast-cat*.jpg" \
  --duration 3600 \
  --glitch 2 \
  --rotation 15 \
  --size 400 \
  -o podcast.mp4

Example 3: Live Stream Overlay

# Create looping headroom for OBS
sardonic \
  --frames "stream-cat*.jpg" \
  --duration 600 \
  --glitch 1 \
  --size 256 \
  -o stream.mp4

# Import into OBS as video source
# Set to loop
# Position in corner
# Done!

Advanced: Custom Effects

The code is designed to be hackable. Want more effects?

Add Video Distortion

In buildGlitchFilter():

// VHS tracking errors
filters.push('hue=H=2*PI*t');

// RGB shift
filters.push('split[a][b],[a]lutrgb=g=0:b=0[r],[b]lutrgb=r=0:b=0[g]');

Add Frame Stuttering

In generateSequence():

// Repeat same frame 2-3 times (Max Headroom stutter)
if (Math.random() > 0.7) {
  sequence.push({
    ...previousFrame,
    duration: 0.1
  });
}

Add Random Zoom

In createRotatedFrame():

const zoom = 100 + (Math.random() * 20 - 10); // 90-110%
args.push('-resize', `${zoom}%`);

The Max Headroom Legacy

Max Headroom (1985-1987) wasn't just a character. It was a statement about media, reality, and the future.

What made Max special:

  • Artificial but relatable
  • Glitchy but coherent
  • Chaotic but intentional
  • Funny but unsettling

sardonic captures that spirit in miniature. A small chaos agent in your video corner, reminding viewers that media is constructed, reality is malleable, and cats in sunglasses are timeless.

Troubleshooting

"No frames found"

  • Check your --frames pattern
  • Make sure files exist in current directory
  • Try absolute path: --dir /full/path/to/frames

"ImageMagick failed"

  • Install ImageMagick: apt install imagemagick or brew install imagemagick
  • Check image files aren't corrupted

"Overlay looks wrong"

  • Ensure input video and headroom have compatible durations
  • Try different positions: --position bottom-left
  • Adjust margin: --margin 50

"Not glitchy enough"

  • Increase glitch level: --glitch 3
  • Increase rotation: --rotation 30
  • Add more distorted frames to your image set

"Too glitchy"

  • Decrease glitch level: --glitch 0 or --glitch 1
  • Decrease rotation: --rotation 5
  • Use cleaner source images