MCPInstall

wrapped-video

This skill should be used when the user asks to "make a Spotify Wrapped style video", "build a year in review / year-in-review video", "create a personalized data video", "generate a recap video", "build a wrapped video generator", "turn a data table into shareable videos", or "make per-user stat videos". Covers the data row → one shareable video pattern, the Wrapped scene grammar (big-number reveals, top-X lists, superlatives), animated data counters, vertical 9:16 framing, and batch-rendering many personalized videos from one template.

Installs
1.4K
Last 24h
+48
Trending rank
#3439
Security
Not audited

Install

Works with every agent the skills CLI supports.

npx skills add https://github.com/iart-ai/explainer-video-skills --skill wrapped-video
  1. 01

    Install

    Run the command in your project. The CLI asks which agents to install for.

  2. 02

    Describe the task

    Ask your agent for something this skill covers. It loads wrapped-video automatically when relevant.

  3. 03

    Review the result

    The agent follows the SKILL.md steps, scripts and references bundled with the skill.

SKILL.md

The instructions your agent reads when the skill is triggered.

Wrapped Video

Build a "Spotify Wrapped"-style recap: take a row of data about one person (or account, team, year) and turn it into a punchy, shareable vertical video. The core idea is one template × a data table → many personalized videos. Write the template once, then render a unique film for every row.

When to use

  • Year-in-review / "your 2026 wrapped" recaps for any product with per-user stats.
  • Personalized data videos: fitness year, reading year, spending recap, gaming stats, sales rep recap, student progress.
  • Any time the deliverable is "the same video, but with each person's numbers" — at 1 or 100,000 copies.

This is a data → share-bait pattern, not a hand-edited film. If there is no data table (or no per-record data), use a different skill.

The two non-negotiables

  1. Data drives everything. Every headline, number, name, and color comes from props, never hardcoded. A scene that can't be filled from a data row does not belong in a Wrapped.
  2. Built to be screenshotted. Each scene must read in under 2 seconds and look good frozen — that frozen frame is what gets shared to a story. Design for the pause, not the play.

The Wrapped scene grammar

A Wrapped is a fixed sequence of short scene types, each ~2.5–4s. Pick 5–7 and order them as a build. Same grammar every year; only the data and palette change.

Scene typeJobData shape
Intro / "Your 2026, wrapped"Brand the moment, set palettename, year
Big-number revealOne hero stat, counts up hugeone number + unit + label
Top-X listRanked 1→5, staggered inarray of {rank, label, value}
Superlative / persona"You're in the top 1%", an archetypecomputed tier/label
Comparison"more than 92% of listeners"percentile or ratio
Time/heatmap"your busiest month was March"series or peak
Outro / share cardLogo + handle + CTA, holds stillname, handle

Order as a crescendo: small context first, biggest/most personal stat as the climax, then the still share card. See references/scene-grammar.md for a full 7-scene storyboard with timings.

The recap story arc

The scene grammar is the skeleton; the arc is what makes a Wrapped feel like a gift instead of a dashboard. A recap is a tiny five-beat drama about one viewer — sequence it so each reveal feels bigger and more personal than the last.

BeatJobMaps to
Build-upBrand the moment, promise it's theirsIntro: "{name}, your {year}"
Escalating revealsStack stats that rise in stakesTop-X, genres, time patterns
The "big number"One hero stat, max scale, held longestBig-number / count-up climax
Personalized superlativeName who they are, not just what they didPersona/percentile tier
Shareable payoffA still poster they want to postOutro share card

Sequence stats for rising impact — smallest first, biggest last. Rank every stat by emotional payload (raw size, rarity, how flattering) and play them in ascending order. Never open on the hero number: there's nowhere to climb after it, and the rest of the film feels like a comedown. Hold the climax stat largest and longest; everything before it is set-up.

The hook is "this is about YOU." A Wrapped wins because the viewer is the protagonist. Earn that in the first 2 seconds: lead with their name, use their per-user accent, and write every line in second person ("You listened to 412 artists"). Generic copy ("Top genre: Indie") breaks the spell — reframe as "You're an Indie kind of person." If a frame would read identically for two different users, it isn't pulling its weight.

Design the final share-frame as the destination. The whole arc exists to deliver a poster worth posting. The outro is not a credits roll — it's the payoff: the headline superlative or hero number restated, name + @handle, logo, one short CTA, holding completely still ≥2s so a screenshot or auto-loop lands clean. Decide this frame first and build the crescendo toward it. Copywriting tiers and the full storyboard are in references/scene-grammar.md.

Data → video shape

Define a typed schema for one record. The whole video is a pure function of it.

// src/schema.ts
import { z } from "zod";
export const wrappedSchema = z.object({
  name: z.string(),
  year: z.number(),
  minutesListened: z.number(),
  topArtists: z.array(z.object({ rank: z.number(), label: z.string(), value: z.number() })),
  topGenre: z.string(),
  percentile: z.number(), // 0–100, "top X%"
  accent: z.string(),     // per-user palette, e.g. "#1DB954"
});
export type Wrapped = z.infer<typeof wrappedSchema>;

Register it as defaultProps + schema on the composition so each render just swaps props.

// src/Root.tsx
import { Composition } from "remotion";
import { Wrapped as Recap } from "./Wrapped";
import { wrappedSchema } from "./schema";

export const Root = () => (
  <Composition
    id="Wrapped"
    component={Recap}
    schema={wrappedSchema}
    durationInFrames={30 * 22}  // 22s @ 30fps
    fps={30}
    width={1080} height={1920}  // 9:16 vertical — the share format
    defaultProps={{ name: "Sam", year: 2026, minutesListened: 41203,
      topArtists: [{ rank: 1, label: "Phoebe Bridgers", value: 312 }],
      topGenre: "Indie", percentile: 3, accent: "#1DB954" }}
  />
);

The signature move: the big-number counter

The count-up is the heartbeat of every Wrapped. Drive it from useCurrentFrame() (never setState/setInterval — that flickers on render), ease it with a spring, and format with toLocaleString().

import { useCurrentFrame, useVideoConfig, spring, interpolate } from "remotion";

export const BigNumber: React.FC<{ value: number; label: string; accent: string }> =
({ value, label, accent }) => {
  const frame = useCurrentFrame();
  const { fps } = useVideoConfig();
  const progress = spring({ frame, fps, config: { damping: 200 } }); // 0→1, settles
  const shown = Math.round(interpolate(progress, [0, 1], [0, value]));
  const pop = interpolate(progress, [0, 1], [0.6, 1]); // overshoot-free scale-in
  return (
    <div style={{ display: "flex", flexDirection: "column", alignItems: "center",
        justifyContent: "center", height: "100%", transform: `scale(${pop})` }}>
      <span style={{ fontSize: 220, fontWeight: 900, color: accent, lineHeight: 1,
          fontVariantNumeric: "tabular-nums" }}>{shown.toLocaleString()}</span>
      <span style={{ fontSize: 48, color: "#fff", marginTop: 24 }}>{label}</span>
    </div>
  );
};

Use tabular-nums so digits don't jitter width as they roll. For the top-X list, reuse one spring per item with a staggered delay (rank 1 first) — see references/remotion-recipes.md.

Vertical 9:16, designed for the pause

Render 1080×1920. Stories/Reels/TikTok crop and overlay UI, so keep all type and key numbers inside the center 80% height, clear of the top 12% and bottom 18%. One bold idea per frame, oversized type, high-contrast accent on a flat/gradient background. Per-user accent color makes each share feel personal. Full safe-area map in references/scene-grammar.md.

Batch: one template → many videos

The payoff. Render every data row to its own MP4 with renderMedia, passing the row as inputProps. Generate a CSV of jobs, loop, name files per record.

// render-all.ts  — run with: npx tsx render-all.ts
import { bundle } from "@remotion/bundler";
import { renderMedia, selectComposition } from "@remotion/renderer";
import { wrappedSchema } from "./src/schema";
import users from "./users.json"; // array of rows matching the schema

const serveUrl = await bundle({ entryPoint: "./src/index.ts" });
for (const user of users) {
  const props = wrappedSchema.parse(user);            // validate the row
  const comp = await selectComposition({ serveUrl, id: "Wrapped", inputProps: props });
  await renderMedia({
    composition: comp, serveUrl, codec: "h264",
    inputProps: props,
    outputLocation: `out/wrapped-${user.id}.mp4`,
  });
  console.log("rendered", user.id);
}

For thousands of rows, fan out across machines/Lambda and dedupe identical prop sets. Pipeline, scaling, and a Node + CLI batch variant are in references/batch-pipeline.md.

Build checklist

  • Every visible string/number comes from props; nothing hardcoded.
  • 5–7 scenes, crescendo order, biggest/most personal stat as the climax.
  • Numbers count up via useCurrentFrame + spring, tabular-nums, locale-formatted.
  • 9:16 1080×1920; key content in center 80%, clear of top 12% / bottom 18%.
  • Each scene reads in <2s and looks good frozen (it will be screenshotted).
  • One schema validates every row before render; batch script names files per record.

Deliver & verify (rendered stills → MP4)

Packaged helper (scripts/): tile your stills with scripts/contact-sheet.sh sheet.png f-hook.png f-mid.png f-end.png, then assert the encode with scripts/probe-mp4.sh out.mp4 [WxH] [fps]. See scripts/README.md.

A Wrapped is a Remotion composition rendered per data row — frame-deterministic, so any exact frame renders headlessly with no seek harness. The deliverable is an MP4 (often many) carrying each person's exact numbers; verify one representative row by stills before you batch.

Output contract:

  • A Remotion project with the composition registered (<Composition> + zod schema + defaultProps), all motion frame-driven (no timers / Date.now() / Math.random() — count-ups via useCurrentFrame + spring).
  • Deliverable = the rendered out/wrapped-*.mp4 per row (plus the project, so any row re-renders).
  • Per-user stats baked into props and validated by the schema before render; 9:16 1080×1920.
  • Duration data-dependent? compute it in calculateMetadata, not by hand.

Verify loop — stills of ONE row → inspect → batch. Render a representative user's frames first (cheap, no encode); catch a layout/data bug once instead of N times.

# Frame-exact stills at start / mid / end for ONE representative row — pass that row as props
npx remotion still Wrapped out/f-start.png --frame=0   --props='{...one user...}'
npx remotion still Wrapped out/f-mid.png   --frame=N   --props='{...one user...}'
npx remotion still Wrapped out/f-end.png   --frame=L   --props='{...one user...}'   # L = durationInFrames - 1

# Inspect: every visible string/number comes from that row and is EXACT (big-number reveal lands on the
# real value, top-X ranks/labels correct); key content inside center 80%, clear of top 12% / bottom 18%.

# Only after the representative stills check out, batch-render every row:
npx tsx render-all.ts
  • npx remotion compositions reads durationInFrames/fps to pick the end frame and the big-number's settle frame.
  • README demo GIF for free: npx remotion render Wrapped out/demo.gif --codec=gif --props='{...}'.

Before you finish:

  1. npx remotion still renders cleanly at frame 0, mid, and last for the representative row — no errors, no missing assets/fonts.
  2. Big-number reveal lands on the EXACT prop value at its settle frame; top-X ranks/labels/values match the row.
  3. 9:16: key numbers/type inside center 80%, clear of top 12% / bottom 18%; each checked frame reads frozen.
  4. Frame-driven only — no Date.now() / Math.random() / timers; schema validates every row before batch.
  5. Representative MP4 encoded and plays; then batch all rows (file per record); (optional) GIF for the README.

Reference files

  • references/scene-grammar.md — full 7-scene storyboard with frame timings, the build/crescendo logic, superlative & percentile copywriting patterns, and the 9:16 safe-area map.
  • references/remotion-recipes.md — runnable scene components: staggered top-X list, percentile bar, scene sequencing with <Series>, transitions, fonts, and the no-flicker animation rules.
  • references/batch-pipeline.md — CSV/JSON → many MP4s: schema validation, the render loop, concurrency, Lambda fan-out, and file naming.

FAQ

What does the wrapped-video skill do?

This skill should be used when the user asks to "make a Spotify Wrapped style video", "build a year in review / year-in-review video", "create a personalized data video", "generate a recap video", "build a wrapped video generator", "turn a data table into shareable videos", or "make per-user stat videos". Covers the data row → one shareable video pattern, the Wrapped scene grammar (big-number reveals, top-X lists, superlatives), animated data counters, vertical 9:16 framing, and batch-rendering many personalized videos from one template.

How do I install wrapped-video?

Run npx skills add https://github.com/iart-ai/explainer-video-skills --skill wrapped-video in your project. The skills CLI detects the agents you use and copies the skill into the right folder. For Claude Code you can also place the skill folder at ~/.claude/skills/wrapped-video/ (personal) or .claude/skills/wrapped-video/ (project).

Which AI agents can use wrapped-video?

Any agent that supports the open Agent Skills format (a folder with a SKILL.md file), including Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Windsurf, Cline, OpenCode and more.

Is wrapped-video safe to install?

No partner security audit is available yet. Skills can run commands and scripts, so read the SKILL.md and any bundled files before installing.

Who maintains wrapped-video?

It is published by iart-ai in iart-ai/explainer-video-skills. It has 1,381 recorded installs.

More from iart-ai/explainer-video-skills

View all →

explainer-video

iart-ai/explainer-video-skills

This skill should be used when the user asks to "make an explainer video", "turn this into a short explainer", "write a script and storyboard for a product video", "produce a how-it-works/onboarding video", "sync narration and captions", or "build a 30–90s animated explainer". Covers script→storyboard→scene build→narration/caption sync→edit→polish.

Media & Creative1.6K installs

diagram-animation

iart-ai/explainer-video-skills

This skill should be used when the user asks to "animate this diagram", "build a flowchart that reveals step by step", "animate an architecture/sequence diagram", "make a chart animate in", "grow the bars / draw the line / count up the number", "show data flowing along a connector", or "turn a static diagram into a guided reveal". Covers SVG, Framer Motion, D3, and Remotion.

Docs & Writing1.5K installs

whiteboard-animation

iart-ai/explainer-video-skills

This skill should be used when the user asks to "make a whiteboard animation", "draw-on explainer", "VideoScribe style", "hand-drawn explainer video", "animate a sketch being drawn", "do a doodle/scribe video", "show a hand drawing the illustration", or "animate handwriting appearing on a whiteboard". Covers SVG stroke draw-on, a marker hand that follows the path tip, staggered reveal, erase/wipe transitions, and narrated export.

Frontend & Design1.5K installs

isometric-animation

iart-ai/explainer-video-skills

This skill should be used when the user asks to "make an isometric animation", "build a 2.5D isometric scene", "create an isometric infographic", "animate an exploded diagram", "do an isometric city/stack build", "show stacked layers in iso", "extrude blocks with depth", or "add a gentle camera drift to an iso scene". Covers CSS 3D transforms, SVG iso planes, and Three.js OrthographicCamera for true 3D iso — no build step.

Frontend & Design1.5K installs

Popular media & creative skills

View category →

hyperframes

heygen-com/hyperframes

Read first to make, edit, animate or render any video with HyperFrames (HTML rendered to video), including launch films, explainers, music videos, charts, maps, vertical clips, title cards, captions and overlays. Holds the render contract, the work loop and what each kind of video needs.

Media & Creative1.2M installs

media-use

heygen-com/hyperframes

Get or make any media for a HyperFrames video - music, sound effects, images, icons, logos, voiceover, avatar and generated video, transcripts, cutouts, colour grades and looks - with HeyGen or free local tools, and mix placed audio. Also for footage that looks dark, flat or dull, or should be stylized or hidden.

Media & Creative1.1M installs

hyperframes-registry

heygen-com/hyperframes

About 450 ready-made HyperFrames blocks and components installed as editable source - transitions, overlays, titles, kinetic type, captions, charts, map overlays, 3D, camera moves. Use it before hand-building any named visual (CRT scanlines, glitch, film grain, a chart); also for hyperframes add and catalog.

Media & Creative1M installs

hyperframes-creative

heygen-com/hyperframes

Non-animation creative direction for HyperFrames videos. Use for design spec (frame.md / design.md) handling, palettes, typography, narration, beat planning, audio-reactive visuals, composition patterns, and brand / style decisions. For atomic motion patterns and scene blueprints, use hyperframes-animation.

Media & Creative916.5K installs

ai-video-generation

101-skills/superpowers

Generate AI videos with Google Veo, Seedance 2.0, HappyHorse, Wan, Grok and 40+ models via inference.sh CLI. Models: Veo 3.1, Veo 3, Seedance 2.0, HappyHorse 1.0, Wan 2.5, Grok Imagine Video, OmniHuman, Fabric, HunyuanVideo. Capabilities: text-to-video, image-to-video, reference-to-video, video editing, lipsync, avatar animation, video upscaling, foley sound. Use for: social media videos, marketing content, explainer videos, product demos, AI avatars. Triggers: video generation, ai video, text to video, image to video, veo, animate image, video from image, ai animation, video generator, generate video, t2v, i2v, ai video maker, create video with ai, runway alternative, pika alternative, sora alternative, kling alternative, seedance, happyhorse

Media & Creative881.5K installs

ai-image-generation

101-skills/superpowers

Generate AI images with GPT-Image-2, FLUX, Gemini, Grok, Seedream, Reve and 50+ models via inference.sh CLI. Models: GPT-Image-2, FLUX Dev LoRA, FLUX.2 Klein LoRA, Gemini 3 Pro Image, Grok Imagine, Seedream 4.5, Reve, ImagineArt. Capabilities: text-to-image, image-to-image, inpainting, LoRA, image editing, upscaling, text rendering. Use for: AI art, product mockups, concept art, social media graphics, marketing visuals, illustrations. Triggers: flux, image generation, ai image, text to image, stable diffusion, generate image, ai art, midjourney alternative, dall-e alternative, text2img, t2i, image generator, ai picture, create image with ai, generative ai, ai illustration, grok image, gemini image, gpt image, openai image, chatgpt image

Media & Creative880.3K installs