How to Build Personalized "Year in Review" Videos at Scale with TypeScript
May 21, 2026 · By VideoFlowLearn how to build a scalable pipeline for personalized SaaS recap videos using TypeScript, VideoJSON, and the VideoFlow renderers.
Every December, SaaS users brace for the deluge of "Year in Review" emails. Most are static, boring, and quickly archived. But when Spotify or Strava drops a personalized recap video, it becomes a social media event. For engineering teams, building these at scale has historically meant wrestling with fragile FFmpeg shell scripts or expensive, black-box APIs.
With VideoFlow, you can treat these videos like dynamic web components. By combining a fluent TypeScript builder with a portable JSON architecture, you can generate thousands of unique MP4s without the infrastructure headache.
The Architecture of a Personalized Recap
To build a "Year in Review" feature, you need a pipeline that can ingest user data and output a rendered video. Traditional approaches often treat video as a monolithic binary. In contrast, VideoFlow encourages you to store your videos as JSON.

A typical recap involves three layers of data:
- Static Assets: Background music, brand logos, and transition templates.
- User Data: Total tasks completed, hours saved, or projects launched.
- Dynamic Logic: Conditional scenes (e.g., if a user hit a "Top 1%" milestone, show a special badge).
Building the Recap with @videoflow/core
The core of the system is the VideoFlow builder. Instead of calculating frame offsets manually, you use primitives like $.group and $.wait. Here is how you might structure a simple milestone card:
import VideoFlow from '@videoflow/core';
const buildRecap = (userData) => {
const $ = new VideoFlow({ width: 1080, height: 1920 }); // Vertical for social
// Background image with a subtle blur effect
const bg = $.addImage(
{ fit: 'cover', opacity: 0.7, filterBlur: 0.2 },
{ source: 'https://assets.acme.com/recap-bg.jpg' }
);
// Milestone Group
$.group({ position: [0.5, 0.5] }, {}, () => {
$.addText({
text: 'You crushed it!',
fontSize: 6,
color: '#FF5A1F',
position: [0.5, 0.4]
}).fadeIn();
$.addText({
text: `${userData.taskCount} Tasks Completed`,
fontSize: 8,
fontWeight: 800,
position: [0.5, 0.55]
}, {
transitionIn: { transition: 'numberCountUp', duration: '1s' }
});
});
$.wait('3s');
return $.compile();
};
This pattern allows you to iterate on the design in the interactive Playground and then deploy the same logic to your production server.
The Three-Renderer Advantage
One of the biggest challenges in programmatic video is the gap between "designing" and "rendering." VideoFlow solves this with its three-renderer rule. You can use the same VideoJSON output across different environments:
@videoflow/renderer-dom: For real-time scrubbing and live preview inside your dashboard while the user waits.@videoflow/renderer-browser: For zero-cost, client-side MP4 export using WebCodecs directly in the user's tab.@videoflow/renderer-server: For headless, batch rendering on Node.js when you need to send the video via email or push notification.

You can find detailed implementation details in our official renderers guide.
Scaling to Thousands of Users
When rendering for a large user base, cost and concurrency are the primary constraints. Because VideoFlow is open source (Apache-2.0), you aren't paying a per-minute fee to a third-party API. You can spin up a cluster of Node.js workers using @videoflow/renderer-server and scale horizontally.
Unlike FFmpeg-based solutions, VideoFlow's server renderer uses headless Chromium to drive the render. This means you have access to the full power of GLSL effects and complex typography without having to manage complex command-line flags. If you are currently using shell scripts, check out our VideoFlow vs FFmpeg comparison to see how much cleaner your code can be.
Get Started with Automated Video
Personalized video is no longer a luxury reserved for the Fortune 500. With the VideoFlow Core API, any TypeScript developer can build a cinematic recap engine in an afternoon.
Ready to build your first recap? Check out the Quick Start guide or dive into the source code on GitHub. If you want to give your users a way to edit their own recaps before sharing, the React Video Editor is a drop-in component that handles the heavy lifting for you.