Install
$ agentstack add skill-sailingnaturali-claude-skills-record-web-gif ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Record a Web App to a GIF
Drive Chrome with puppeteer-core (your system Chrome — no chromium download), capture frames over CDP, and assemble a clean GIF with ffmpeg. One bundled script does all of it.
Prerequisites
ffmpegon PATH (brew install ffmpeg).puppeteer-coreresolvable from where you run the script:npm i puppeteer-corein a scratch
dir and run the script from there (it uses your installed Chrome, so no large download).
- Google Chrome (or Chromium) installed. Override with
--chrome PATHor$CHROME_PATH.
Quick start
Record a 12s clip and write the GIF in one command:
node record-gif.mjs "http://localhost:5173/" out.gif \
--duration 12000 --fps 15 --size 1000x630 --scale 800
For an app where you press a button to start an animation, and you want the UI chrome out of the frame:
node record-gif.mjs "http://localhost:5173/?demo=1" out.gif \
--wait-text Start --start-text Start --hide ".controls" \
--duration 31000 --fps 15
Options
| Flag | Purpose | Default | |------|---------|---------| | --duration MS | clip length | 12000 | | --fps N | target capture rate | 15 | | --size WxH | capture viewport | 1000x630 | | --scale W | GIF width (height auto) — shrink for size | = capture width | | --headless | run headless (see WebGL note) | off (headful) | | --wait-text "T" | wait for an enabled ` with this text before starting | — | | --start-text "T" | click the with this text to begin | — | | --hide "SEL" | CSS selector to hide while recording (repeatable) | — | | --settle MS | pause after load (lets tiles/fonts settle) | 1500 | | --chrome PATH | Chrome/Chromium executable | auto-detect | | --keep-frames` | keep the temp frame dir | off |
The GIF is assembled with a 2-pass palette (palettegen/paletteuse) at the effective capture rate, so playback is real-time with clean colors.
WebGL / canvas apps (MapLibre, three.js, charts) — read this
Naive headless capture of a WebGL or ` app often yields a **blank** frame or a crashed page: recent Chrome can't create a software WebGL context (Could not create a WebGL context … BindToCurrentSequence failed`), MapLibre throws, and React unmounts. Two facts:
- Headless needs
--enable-unsafe-swiftshader(plus--use-angle=swiftshader). This script
adds those automatically in --headless mode so the app renders — but software WebGL is slow to capture (~6 fps), so pans look choppy.
- Headful (the default here) uses the GPU and captures smoothly (~12–15 fps). It opens a
visible Chrome window for the duration. Prefer it for anything with camera motion.
Common mistakes
- Blank/dark GIF of a map or canvas app → you ran headless without the swiftshader flags, or
the app crashed. Use headful (default), or confirm webgl works (the script's flags handle it).
- Choppy motion → software WebGL headless caps at ~6 fps. Re-record headful.
- GIF too big for a README → lower
--scale(e.g. 720), drop--fpsto 12, or trim
--duration. Dark/flat UIs compress well; ~5–8 MB at 800px/15fps for ~30s is typical.
- Animation never plays / controls in frame → use
--start-textto trigger it and--hide
to drop the UI chrome (Start/Replay buttons, panels) for a clean recording.
Cannot find package 'puppeteer-core'→ run the script from a dir where it's installed
(bare ESM imports resolve from the script's location upward, not from $NODE_PATH).
Why this approach
puppeteer-core + system Chrome avoids a 150 MB chromium download and matches the browser the app is actually tested in. CDP Page.captureScreenshot in a fixed-interval loop gives predictable frame timing; ffmpeg's two-pass palette beats a naive single-pass GIF on banding. The script is in this folder: [record-gif.mjs](record-gif.mjs).
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: sailingnaturali
- Source: sailingnaturali/claude-skills
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.