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

@marvinhuelsmann/screenflow

v0.4.23

Published

CLI tool to create beautiful mockup device screenshots

Downloads

1,525

Readme

screenflow

Wrap iOS simulator screenshots in a pixel-perfect device frame — straight from your terminal. No Figma, no design tools, no fuss.

Installation

brew install marvinhuelsmann/screenflow/screenflow

Usage

screenflow <screenshot>

Output defaults to SVG and is placed next to your input file.

screenflow screenshot.png
# → screenshot_iphone-17-pro_cosmic-orange.svg

Commands

| Command | Description | |---|---| | screenflow <file> | Frame a screenshot (default) | | screenflow video <file> | Create an animated marketing video | | screenflow appstore <file> | Generate a ready-to-upload App Store screenshot | | screenflow mcp install | Register the MCP server with your AI agents (auto-runs on install) | | screenflow devices | List all available devices and their colors | | screenflow config | Show your saved defaults | | screenflow set-default | Set a default device and color interactively | | screenflow author | About the author |

Frame options

| Option | Short | Description | |---|---|---| | --device <device> | -d | Device frame (default: iphone-17-pro) | | --color <color> | -c | Frame color (default: first color for the chosen device) | | --png | | Output as PNG instead of SVG (still images only) | | --jpeg | | Output as JPEG instead of SVG (still images only) | | --mp4 | | Output as MP4 · H.264 on black instead of MOV · HEVC · Transparent (screen recordings only) | | --output <path> | -o | Custom output file path |

Examples

# Default — iPhone 17 Pro, Cosmic Orange frame, SVG output
screenflow screenshot.png

# Deep Blue frame
screenflow screenshot.png --color deep-blue

# Cosmic Orange, exported as PNG
screenflow screenshot.png -c cosmic-orange --png

# Render your screen recording into a static mockup
screenflow simulator.mov

# iPad Pro 11, Space Gray
screenflow screenshot.png -d ipad-pro-11 -c space-gray --png

# Custom output path
screenflow screenshot.png -o framed/app_store.svg

# JPEG for smaller file size
screenflow screenshot.png --jpeg

# Set a persistent default device and color
screenflow set-default

# List all available devices and colors
screenflow devices

Video animation

screenflow video <file> renders an animated MP4 marketing clip. Requires ffmpeg — screenflow will offer to install it automatically via Homebrew if it's not present.

Video options

| Option | Short | Description | |---|---|---| | --style <style> | -s | Animation style (default: zoom-in) | | --duration <seconds> | | Clip length in seconds, 1–60 (default: 9). For a still it's the animation length; for a recording it trims the clip (capped to the recording's length) | | --tilt <degrees> | -t | Perspective tilt downward in degrees, 0–45 (default: 0) | | --fps <fps> | | Frame rate: 24, 30, 60, or 120 (default: 60) | | --device <device> | -d | Device frame | | --color <color> | -c | Frame color | | --output <path> | -o | Custom output file path |

Animation styles

| Style | Description | |---|---| | zoom-in (default) | 2× zoom, pan from bottom to top | | zoom-out | Zoom out 1.8× → 1×, centered | | pan-down | Constant 1.4× zoom, pan from top to bottom | | pan-left | Full device visible, slides from right to left across the frame | | pan-right | Full device visible, slides from left to right across the frame |

# Default zoom-in style (9 seconds)
screenflow video screenshot.png
# → screenshot_iphone-17-pro_cosmic-orange.mp4

# 15-second video
screenflow video screenshot.png --duration 15

# Pan from top to bottom
screenflow video screenshot.png --style pan-down

# Zoom out with specific device and color
screenflow video screenshot.png -d iphone-16-pro -c natural --style zoom-out

# Pan left with custom output
screenflow video screenshot.png --style pan-left -o ~/Desktop/promo.mp4

# Zoom-in with 15° downward tilt
screenflow video screenshot.png --tilt 15

# Zoom-in at 120 fps for 5 seconds
screenflow video screenshot.png --fps 120 --duration 5

Output is always 1920 × 1080 H.264 MP4, CRF 12.

App Store screenshots

screenflow appstore <file> turns a single screenshot into a ready-to-upload App Store screenshot at the mandatory 1242 × 2688 (iPhone 6.5") size: a headline caption on top, the framed device below, on a solid background. The caption is set in SF Pro Display, and its color is chosen automatically for contrast against the background. Use \n in the caption for manual line breaks (long captions also wrap automatically).

App Store options

| Option | Short | Description | |---|---|---| | --caption <text> | | Headline text rendered above the device | | --align <align> | | Caption alignment: left | center | right (default center) | | --bg <color> | | Background color, hex (default #0A84FF) | | --device <device> | -d | Device frame | | --color <color> | -c | Frame color | | --jpeg | | Output as JPEG instead of PNG | | --output <path> | -o | Custom output file path |

# Hero screenshot — blue background, centered caption
screenflow appstore screenshot.png --caption "Find your way, anywhere."
# → screenshot_iphone-17-pro_appstore.png  (1242×2688)

# Light background (caption auto-switches to black), left-aligned
screenflow appstore screenshot.png -d iphone-16-pro -c black \
  --caption "Plan routes in seconds." --align left --bg "#F2F2F7"

# Dark background, long captions wrap automatically
screenflow appstore screenshot.png --bg "#1C1C1E" \
  --caption "Discover every hidden corner of your city with confidence"

# Manual line break with \n
screenflow appstore screenshot.png \
  --caption "Find your way.\nAnywhere, anytime."

Screen recordings & HEIC input

The commands are the same — just hand them a screen recording (.mp4, .mov, .m4v, .webm, .mkv, .avi) or any still image (including .heic/.heif) instead of a PNG/JPG. screenflow detects the input type automatically (requires ffmpeg for video).

| Input | screenflow <file> (default) | screenflow video <file> | |---|---|---| | Still image (PNG/JPG/HEIC) | Static framed image (SVG/PNG/JPEG) | Animated marketing clip (--duration seconds) | | Screen recording (MP4/MOV/…) | Device stays still, the screen plays the recording | Camera animation (zoom/pan/tilt) runs while the screen plays |

For a screen recording the output length defaults to the recording length. With the video command you can pass --duration to trim the clip shorter (it's capped to the recording's own length — a recording can't be extended). --png/--jpeg don't apply to the default command.

# Static framing of a screen recording → transparent .mov (HEVC with alpha), audio kept
screenflow recording.mov -d iphone-17-pro
# → recording_iphone-17-pro_cosmic-orange.mov

# H.264 .mp4 on a black background instead
screenflow recording.mov --mp4
# → recording_iphone-17-pro_cosmic-orange.mp4

# Drop the audio track
screenflow recording.mov --mute

# Animate a screen recording (length = recording), 15° tilt
screenflow video recording.mov --style zoom-in --tilt 15

# HEIC still works just like a PNG
screenflow shot.heic -d iphone-17 --png
  • Default command + recording → transparent .mov (HEVC with alpha) — alpha channel preserved at ~90× smaller files than ProRes, plays natively in QuickTime/Keynote and composites in Final Cut or After Effects; use --mp4 for H.264 on a black background.
  • video command + recording1920 × 1080 H.264 MP4 (the established marketing format).
  • Audio from the recording is kept by default; use --mute to strip it.

Note: transparent .mov output uses HEVC with alpha (hardware-encoded via VideoToolbox on macOS), keeping files small even for large canvases (iMac, iPad).

Use it from AI agents (MCP)

screenflow ships an MCP server (screenflow-mcp) so AI coding agents — Claude Code, Codex, Cursor, Claude Desktop — can frame screenshots, build App Store screenshots and wrap recordings for you. Ask the agent to "put this screenshot in an iPhone mockup" or "make App Store screenshots" and it picks the right tool automatically.

Tools exposed: frame_screenshot, frame_recording, create_appstore_screenshot, list_devices.

Each media tool takes the input one of three ways, in order of preference:

  1. input_path — a real existing file on the machine running the server. Fastest; use it whenever the agent is on the same computer (e.g. Claude Code on your Mac).
  2. input_url — a public URL the server downloads. Fast.
  3. input_base64 — the raw bytes, base64-encoded. Works in any environment (sandboxed/containerised agents with no shared filesystem) but is slow and expensive for large files, because the model has to emit the entire blob — only use it when no path or URL is available.

The result is returned inline as a downscaled preview image (max 1568 px long edge — set inline_max_px: 0 for full resolution inline). Pass output_path to also save the full-resolution file to disk. If a bogus path is passed, the tool replies with guidance to use a URL or base64 instead.

Zero-config setup

Installing the CLI automatically registers the MCP server with every AI agent it finds on your machine — no manual steps:

brew install marvinhuelsmann/screenflow/screenflow   # or: npm i -g @marvinhuelsmann/screenflow

That's it. Restart your agent and ask it to frame a screenshot. Re-run the registration anytime (e.g. after installing a new agent):

screenflow mcp install              # register with all detected agents
screenflow mcp install --dry-run    # preview what it would change
screenflow mcp uninstall            # remove the registration everywhere

Manual setup (optional)

If you'd rather wire it up by hand:

# Claude Code
claude mcp add screenflow -- screenflow-mcp
# Codex — ~/.codex/config.toml
[mcp_servers.screenflow]
command = "screenflow-mcp"
// Cursor / Claude Desktop — mcpServers
{ "mcpServers": { "screenflow": { "command": "screenflow-mcp" } } }

The server communicates over stdio and needs no extra setup; ffmpeg is only required for the recording tool.

Supported Devices

| Device | ID | Colors | |---|---|---| | iPhone 17 Pro | iphone-17-pro | cosmic-orange, deep-blue, silver | | iPhone 16 Pro | iphone-16-pro | black, natural, white | | iPad Pro 11" | ipad-pro-11 | silver, silver-with-apple-pencil, space-gray, space-gray-with-apple-pencil | | iPad Pro 13" | ipad-pro-13 | silver, space-gray | | iPhone Air | iphone-air | black, blue, gold, white | | iPhone 17" | iphone-17 | black, lavender, mist-blue, sage, white | | iPhone 16" | iphone-16 | black, pink, teal, ultramarine, white | | Imac | imac | blue, green, orange, pink, purple, silver, yellow | | Apple Watch Ultra | apple-watch-ultra | black-alpine-loop, black-milanese, natural-alpine-loop, natural-milanese | | Apple Watch Series 11" | apple-watch-series-11 | titanium-gold-magnetic-link-sage-gray, titanium-gold-milanese-loop, titanium-natural-magnetic-link-caramel, titanium-natural-sport-band-stone-gray, titanium-slate-magnetic-link-navy, titanium-slate-milanese-loop |

Updating

brew upgrade screenflow

Project Structure

src/
  index.ts          ← entry point (3 lines)
  cli.ts            ← program setup + command routing
  composer.ts       ← SVG compositing, output rendering + buildFrameAssets (video overlay/mask)
  config.ts         ← Config class (reads/writes ~/.config/screenflow/config.json)
  ui.ts             ← shared terminal helpers (spinner, colors, name formatting)
  ffmpeg.ts         ← shared ffmpeg/ffprobe helpers + input-kind detection
  video-compose.ts  ← ffmpeg filtergraph for compositing a recording inside a frame
  frames/
    index.ts        ← FRAMES registry — source of truth for devices, colors, dimensions
    iphone-17-pro/  ← SVG frame files per color
      cosmic-orange.svg
      deep-blue.svg
      silver.svg
    ipad-pro-11/
    ipad-pro-13/
    iphone-16-pro/
  commands/
    frame.ts        ← frame a screenshot
    video.ts        ← render a 5-second marketing video animation
    setDefault.ts   ← interactive default picker
    devices.ts      ← list devices and colors
    showConfig.ts   ← print saved defaults
    author.ts       ← author info
scripts/
  add-device.js     ← automation: registers a new device across all files

Contributing

Contributions are welcome — new devices, new color variants, bug fixes. Here's how everything fits together.

Setup

git clone https://github.com/marvinhuelsmann/screenflow.git
cd screenflow
npm install

Development

# Run directly without building
npm run dev -- screenshot.png

# Build
npm run build

# Test your build
node dist/index.js screenshot.png

Adding a new device

1. Export the SVG frames from your design tool — one file per color variant. Name each file after its color (e.g. silver.svg, space-gray.svg).

2. Create the device folder and drop in the SVGs:

src/frames/
  iphone-17-pro/       ← existing
  your-new-device/     ← new
    silver.svg
    space-gray.svg

3. Run the add-device script:

npm run add-device your-new-device
# or with a custom display name:
npm run add-device your-new-device 'Your New Device'

The script automatically:

  • Detects the frame type (vector SVG or raster PNG-in-SVG)
  • Calculates the screen coordinates by scanning for the transparent screen area
  • Registers the device in src/frames/index.ts
  • Adds the cp command to the package.json build script
  • Adds the device and its colors to both completion files
  • Adds a row to the device table in README.md

4. Build and test:

npm run build
node dist/index.js screenshot.png --device your-new-device --color silver

The first color registered for a device is used as that device's automatic default.

Vector frames (like the iPhone 17 Pro SVGs) have a <path id="Screen mask"> element. The script registers them but cannot auto-detect screen coordinates from vector paths — check the logged output and correct the values in src/frames/index.ts manually if needed.


Adding a new color to an existing device

  1. Drop the SVG into the device folder (e.g. src/frames/iphone-17-pro/midnight.svg)
  2. Add the color entry in src/frames/index.ts under the device's colors map
  3. Add the color to both completion files (completions/screenflow.fish and completions/_screenflow)
  4. Build and test

Opening a pull request

  1. Fork the repo and create a branch:
    git checkout -b feat/iphone-18-pro
  2. Make your changes and build cleanly:
    npm run build
    node dist/index.js screenshot.png --device iphone-18-pro
  3. Push and open a PR against develop:
    git push origin feat/iphone-18-pro
  4. In the PR description include:
    • Which device / color was added
    • A sample output screenshot so the result can be reviewed visually

License

MIT © Marvin Hülsmann