How to Turn Markdown Changelogs into Automated Product Update Videos
May 22, 2026 · By VideoFlowLearn how to build a TypeScript pipeline that turns Markdown changelogs into automated product update videos with cinematic effects and dynamic captions.
You’ve just shipped three major features, fixed five bugs, and updated your CHANGELOG.md. Now comes the tedious part: creating a 60-second product update video for social media and your customers. Manually recording clips, syncing captions, and adding transitions is a massive time sink that often gets skipped.
What if your video pipeline lived inside your CI/CD? In this guide, we'll show you how to build a system that turns Markdown changelogs into automated product update videos using TypeScript and VideoFlow. By treating video as code, you can generate high-quality MP4s every time you push a release.
Why Automate Your Product Updates?
For engineering-led teams, manual video editing is an anti-pattern. It’s slow, inconsistent, and doesn't scale. Automating this process ensures that every release gets the visibility it deserves without adding friction to your workflow.

By using VideoFlow, you get a portable VideoJSON document that describes your scene. This means you can version-control your video templates just like your frontend components.
Step 1: The Markdown Source
Imagine a standard CHANGELOG.md entry:
## v1.4.0 — The Performance Update
- **WebCodecs Support**: Render videos 10x faster in the browser.
- **GLSL Effects**: 42 new cinematic presets added.
- **Bug Fix**: Resolved memory leak in server-side renderer.
We can parse this into a simple data structure. For this tutorial, we'll focus on the VideoFlow implementation that turns this data into a cinematic video.
Step 2: Building the Scene with VideoFlow
We'll use @videoflow/core to build our video. The goal is to create a title card followed by a sequence of feature highlights.
import VideoFlow from '@videoflow/core';
const $ = new VideoFlow({
width: 1920,
height: 1080,
fps: 30,
backgroundColor: '#0a0a0a'
});
// 1. Add a Background Image with a Blur Effect
const bg = $.addImage(
{ fit: 'cover', opacity: 0.4, filterBlur: 1.5 },
{ source: 'https://images.unsplash.com/photo-1614850523296-d8c1af93d400' }
);
// 2. Add the Release Title
const title = $.addText({
text: 'v1.4.0 — The Performance Update',
fontSize: 8,
fontWeight: 700,
color: '#FF5A1F',
position: [0.5, 0.4]
});
title.fadeIn('600ms');
$.wait('2s');
title.fadeOut('400ms');
// 3. Loop through features (simplified logic)
const features = [
'WebCodecs Support',
'42 New GLSL Effects',
'Server-side Performance'
];
for (const feat of features) {
const item = $.addText({
text: feat,
fontSize: 6,
color: '#ffffff',
position: [0.5, 0.5]
}, {
transitionIn: { transition: 'blurResolve', duration: '800ms' },
transitionOut: { transition: 'fade', duration: '500ms' }
});
$.wait('2.5s');
item.remove();
}
In this snippet, we use the $.addText method to create layers. Notice how we use em units for fontSize (where 1em = 1% of the project width), ensuring our video is resolution-independent. If we decided to render this in 4K later, the layout would stay perfect.
Step 3: Adding Cinematic Captions
For product updates, captions are essential. VideoFlow provides a dedicated CaptionsLayer that handles timing for you. Instead of manually positioning text for every frame, you provide an array of timed entries.
const captions = $.addCaptions(
{
fontSize: 4,
color: '#ffffff',
position: [0.5, 0.85],
textAlign: 'center',
textShadowBlur: 10,
textShadowColor: 'rgba(0,0,0,0.5)'
},
{
captions: [
{ caption: 'Shipping faster than ever.', startTime: 0, endTime: 3 },
{ caption: 'Powered by VideoFlow.', startTime: 3.5, endTime: 6 }
]
}
);
You can learn more about this in our captions layer guide.
Step 4: Headless Rendering
Once the script is ready, you can render it to an MP4 file in a Node.js environment using @videoflow/renderer-server. This renderer uses a headless browser to ensure that your GLSL effects and transitions look exactly like they do in the Playground.
import '@videoflow/renderer-server';
await $.renderVideo({
outputType: 'file',
output: './release-v1.4.0.mp4',
verbose: true
});

How VideoFlow Handles the Heavy Lifting
Building automated product update videos requires a tool that understands both the developer's workflow and cinematic requirements.
- Portable JSON: The output of
$.compile()is a plain JSON document. You can store your changelog templates in a database or pass them between microservices. - The Three-Renderer Rule: You can preview your video in real-time with
@videoflow/renderer-dom, export it in the user's browser with@videoflow/renderer-browser, or batch-render on a server with@videoflow/renderer-server. All three produce byte-for-byte identical results. - Cinematic Primitives: With 27 transition presets and 42 GLSL effects like
bloom,vignette, andchromaticAberration, your automated videos will look like they were hand-crafted by a motion designer.
Get Started
Ready to automate your video pipeline? You can start experimenting right now in our interactive Playground or dive into the Getting Started guide. If you're coming from a different tool, check out our comparison of VideoFlow vs Remotion to see why a JSON-first approach might be better for your next project.
For more automation ideas, check out our previous post on How to Automate Loom-style Product Demos with TypeScript.
You can find the full source code for the core and all renderers on GitHub.