VideoFlowcodeGitHubTry itCoreRenderersReact Video EditorPlaygroundExamplesDocscodeGitHubTry it
← Back to Blog

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.How to Build Personalized "Year in Review" Videos at Scale with TypeScript

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.

JSON transformation pipeline

A typical recap involves three layers of data:

  1. Static Assets: Background music, brand logos, and transition templates.
  2. User Data: Total tasks completed, hours saved, or projects launched.
  3. 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.

The three official renderers matrix

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.

VideoFlow

Open-source toolkit for composing videos from code.

Product

CoreRenderersReact Video EditorPlayground

Learn

DocsAPI referenceExamplesvs. Remotionvs. FFmpeg

Project

GitHubLicenseContactTermsPrivacy

From the blog

All posts →Automating YouTube Shorts: Build a Vertical Video Factory in 30 Lines of TypeScriptVideo as Data: Building an LLM-Powered Video Generation PipelineWhy VideoFlow is the Best Open Source Remotion AlternativeGlobal by Default: Automating Video Localization with TypeScriptHow to Render MP4s in Node.js without Installing FFmpegOne JSON, Three Aspect Ratios: Building Resolution-Agnostic Video PipelinesState-Driven Video: Syncing Your React UI with a Programmatic TimelineTesting Your Video: How to Build a CI/CD Pipeline for Programmatic Media
© 2026 VideoFlow. Apache-2.0 core.