Remotion for SaaS Product Tours and Onboarding Videos
Remotion for SaaS Product Tours and Onboarding Videos
User onboarding is the single highest-leverage moment in a SaaS product’s lifecycle. A user who activates in the first session retains at a dramatically higher rate than one who drifts through a confusing interface for ten minutes and quietly churns. Video is consistently one of the most effective onboarding formats — users watch rather than read, context is communicated faster, and the emotional tone of a well-made video builds trust before the user has touched a single feature.
The problem is that traditional onboarding video is expensive to maintain. A screen recording becomes stale the moment you ship a UI update. Personalizing it per customer tier, per industry, or per language is prohibitively expensive with traditional tooling. Remotion changes that calculus entirely.
Why Programmatic Video Beats Screen Recording for SaaS
Screen recording tools like Loom or OBS are capture-based. The video is a pixel snapshot of a real application at a real moment in time. The moment your UI changes, the video is wrong. The moment a customer asks for a version with their logo and team name in it, you are back in a video editor.
Remotion is code-based. The video is a React component tree that renders frame by frame. There is no UI to capture — you build a React approximation of your product’s interface and animate it directly. This means:
Instant updates. When your real UI ships a change, you update the mock component. One line of code, new video.
Unlimited personalization. Every frame is driven by props. Pass in { customerName, planTier, logoUrl } and every text label, color, and graphic adjusts automatically.
Automation at scale. A Node.js script can call Remotion’s rendering API to generate thousands of personalized videos per day — one per customer, triggered by signup events.
Perfect pixels every time. No recording artifacts, no cursor jitter, no notification pop-ups. The mock interface always looks its best.
Building UI Mock Animations
The key insight is that you do not need to show the real application. You need to show a convincing approximation of the key interactions. Users watching an onboarding video do not audit pixel-perfect fidelity — they follow the narrative.
Here is a minimal but realistic example: a mock SaaS dashboard panel with an animated metric card.
import { useCurrentFrame, interpolate, spring, useVideoConfig } from "remotion";
const MetricCard: React.FC<{
label: string;
value: number;
delay: number;
}> = ({ label, value, delay }) => {
const frame = useCurrentFrame();
const { fps } = useVideoConfig();
const slideY = spring({
frame: frame - delay,
fps,
config: { stiffness: 120, damping: 18 },
from: 40,
to: 0,
});
const opacity = interpolate(frame - delay, [0, 20], [0, 1], {
extrapolateLeft: "clamp",
extrapolateRight: "clamp",
});
const displayValue = Math.round(
interpolate(Math.max(0, frame - delay), [0, 45], [0, value], {
extrapolateRight: "clamp",
})
);
return (
<div
style={{
transform: `translateY(${slideY}px)`,
opacity,
background: "rgba(255,255,255,0.08)",
borderRadius: 12,
padding: "24px 28px",
width: 220,
fontFamily: '-apple-system, "Segoe UI", Roboto, sans-serif',
}}
>
<div style={{ color: "#94a3b8", fontSize: 14, marginBottom: 8 }}>
{label}
</div>
<div style={{ color: "#f1f5f9", fontSize: 36, fontWeight: 700 }}>
{displayValue.toLocaleString()}
</div>
</div>
);
};
export const DashboardScene: React.FC<{ customerName: string }> = ({
customerName,
}) => {
return (
<div
style={{
width: 1920,
height: 1080,
background: "linear-gradient(135deg, #0f172a 0%, #1e293b 100%)",
display: "flex",
flexDirection: "column",
alignItems: "center",
justifyContent: "center",
gap: 24,
}}
>
<div
style={{
color: "#e2e8f0",
fontSize: 28,
fontFamily: '-apple-system, "Segoe UI", Roboto, sans-serif',
marginBottom: 16,
}}
>
Welcome back, {customerName}
</div>
<div style={{ display: "flex", gap: 20 }}>
<MetricCard label="Active Users" value={1284} delay={0} />
<MetricCard label="Revenue MTD" value={48200} delay={10} />
<MetricCard label="Churn Rate" value={2} delay={20} />
</div>
</div>
);
};
Each MetricCard slides in with a spring animation staggered by the delay prop, and the displayed number counts up from zero. No screen recording needed — this is just React.
Feature Highlight Animation Patterns
Onboarding videos typically need to draw attention to specific UI elements. The canonical pattern is a spotlight effect: dim everything except the feature you are pointing at.
import { useCurrentFrame, interpolate } from "remotion";
export const Spotlight: React.FC<{
targetX: number;
targetY: number;
targetW: number;
targetH: number;
children: React.ReactNode;
}> = ({ targetX, targetY, targetW, targetH, children }) => {
const frame = useCurrentFrame();
const opacity = interpolate(frame, [0, 15], [0, 0.75], {
extrapolateRight: "clamp",
});
return (
<div style={{ position: "relative", width: 1920, height: 1080 }}>
{children}
{/* Dark overlay with a cut-out rectangle */}
<svg
style={{ position: "absolute", top: 0, left: 0 }}
width={1920}
height={1080}
>
<defs>
<mask id="spotlight-mask">
<rect width={1920} height={1080} fill="white" />
<rect
x={targetX}
y={targetY}
width={targetW}
height={targetH}
rx={8}
fill="black"
/>
</mask>
</defs>
<rect
width={1920}
height={1080}
fill={`rgba(0,0,0,${opacity})`}
mask="url(#spotlight-mask)"
/>
</svg>
</div>
);
};
Combine this with a bouncing arrow component (animated with interpolate on translateY) and a text callout that fades in with opacity, and you have the complete feature highlight pattern used in most SaaS product tour videos.
Cursor Animation
A surprisingly effective touch is animating a fake cursor that moves to the highlighted element and clicks:
const cursorX = interpolate(frame, [0, 30, 60], [200, 200, targetX + 10], {
extrapolateRight: "clamp",
});
const cursorY = interpolate(frame, [0, 30, 60], [900, 900, targetY + 10], {
extrapolateRight: "clamp",
});
const cursorScale = interpolate(frame, [60, 65, 70], [1, 0.85, 1], {
extrapolateLeft: "clamp",
extrapolateRight: "clamp",
});
<div
style={{
position: "absolute",
left: cursorX,
top: cursorY,
transform: `scale(${cursorScale})`,
fontSize: 28,
userSelect: "none",
pointerEvents: "none",
}}
>
▶
</div>
The cursor glides from a neutral position to the target element (frames 30–60) and briefly scales down at frame 65 to simulate a click.
Data-Driven Customization
The most powerful capability of Remotion for SaaS is making every video unique to its viewer. Define an input props schema with zod and pass it to your composition:
import { z } from "zod";
import { useCurrentFrame, Composition, useInputProps } from "remotion";
export const onboardingSchema = z.object({
customerName: z.string(),
planTier: z.enum(["starter", "growth", "enterprise"]),
logoUrl: z.string().url().optional(),
primaryColor: z.string().default("#6366f1"),
featureSet: z.array(z.string()),
});
export type OnboardingProps = z.infer<typeof onboardingSchema>;
Now every visual — the welcome message, the color accent, the feature steps shown — is driven by this schema. When you render, you pass a JSON payload:
{
"customerName": "Acme Corp",
"planTier": "enterprise",
"primaryColor": "#0ea5e9",
"featureSet": ["analytics", "integrations", "sso"]
}
The video renders with Acme Corp’s name, their brand color, and only the features their plan includes. The same Remotion composition generates a completely different video for every customer.
Automated Video Generation at Scale
Remotion exposes a Node.js rendering API that lets you trigger renders programmatically. Combined with a serverless rendering backend, you can generate hundreds of personalized onboarding videos automatically.
Here is the conceptual flow for a SaaS signup pipeline:
import { renderMedia, selectComposition } from "@remotion/renderer";
async function generateOnboardingVideo(customer: OnboardingProps) {
const composition = await selectComposition({
serveUrl: "https://your-remotion-bundle.vercel.app",
id: "OnboardingVideo",
inputProps: customer,
});
await renderMedia({
composition,
serveUrl: "https://your-remotion-bundle.vercel.app",
codec: "h264",
outputLocation: `./output/${customer.customerName.replace(/\s+/g, "-")}.mp4`,
inputProps: customer,
});
}
In production, replace outputLocation with an upload to S3 or Cloudflare R2, then trigger an email or in-app notification with the video link. The entire pipeline — signup event → render trigger → video delivery — can complete in under five minutes.
For higher throughput, Remotion Lambda distributes rendering across AWS Lambda concurrently, enabling hundreds of simultaneous renders.
Integrating with Product Analytics
The next level of sophistication is using product analytics data to decide which onboarding video to send. If your analytics platform (Mixpanel, Amplitude, PostHog) tracks feature adoption, you can route customers to different video variants:
async function selectAndSendOnboarding(userId: string) {
const events = await analytics.getUserEvents(userId, { days: 7 });
const hasUsedAnalytics = events.some((e) => e.name === "analytics_viewed");
const featureSet = hasUsedAnalytics
? ["integrations", "collaboration", "exports"]
: ["analytics", "dashboards", "filters"];
await generateOnboardingVideo({
customerName: await getCustomerName(userId),
planTier: await getCustomerPlan(userId),
featureSet,
});
}
Users who have already explored the analytics module get an onboarding video focused on deeper features. Users who have not yet discovered analytics get a video that highlights that module first. This is behavioral personalization at a granularity that screen recording tools simply cannot achieve.
Structuring a Multi-Scene Onboarding Video
A complete onboarding video typically has three to five scenes. Use Remotion’s <Sequence> component to organize them:
import { Sequence, useVideoConfig } from "remotion";
export const OnboardingVideo: React.FC<OnboardingProps> = (props) => {
return (
<>
{/* Scene 1: Welcome (0–90 frames) */}
<Sequence from={0} durationInFrames={90}>
<WelcomeScene customerName={props.customerName} />
</Sequence>
{/* Scene 2: Feature 1 highlight (90–180 frames) */}
<Sequence from={90} durationInFrames={90}>
<FeatureScene
feature={props.featureSet[0]}
color={props.primaryColor}
/>
</Sequence>
{/* Scene 3: Feature 2 highlight (180–270 frames) */}
<Sequence from={180} durationInFrames={90}>
<FeatureScene
feature={props.featureSet[1]}
color={props.primaryColor}
/>
</Sequence>
{/* Scene 4: CTA (270–360 frames) */}
<Sequence from={270} durationInFrames={90}>
<CtaScene planTier={props.planTier} />
</Sequence>
</>
);
};
Each scene component receives only the props it needs. The total duration at 30 fps is 12 seconds — long enough to be useful, short enough to hold attention.
Production Checklist for SaaS Onboarding Videos
Before shipping your onboarding video pipeline, verify these points:
- All customer-supplied strings (names, company names) are safely escaped before being inserted into components — treat them like user-generated content
- The logo URL uses Remotion’s
<Img>component, not a raw<img>tag, to ensure the asset loads before the frame renders - Videos are tested with edge-case inputs: very long company names, missing optional fields, non-Latin characters
- Render time is profiled per tier — enterprise customers with more feature steps should still render in an acceptable window
- Output video files are served from a CDN, not as direct S3 downloads, to ensure fast playback
Get Started Faster with RenderComp Templates
Building a complete SaaS onboarding video pipeline is achievable in a weekend with the right starting point. RenderComp provides production-ready Remotion templates including SaaS dashboard mockups, feature highlight animations, and onboarding video compositions — all built with TypeScript and parameterized for data-driven customization. Visit rendercomp.com to browse the library and accelerate your build.
FAQ
Q1: Does Remotion require capturing the real application UI?
No. Remotion is a React rendering framework — you build a visual representation of your UI using standard React components and CSS. No browser automation, no screen capture, and no dependency on your live application is involved.
Q2: How long does it take to render a 30-second onboarding video?
Render time depends on composition complexity and hardware. On a modern laptop, a 30-second 1080p video typically renders in 1–3 minutes using the Remotion CLI. With Remotion Lambda, the same render can complete in under 30 seconds by distributing frames across concurrent Lambda functions.
Q3: Can I include narration or voiceover in programmatic onboarding videos?
Yes. Remotion’s <Audio> component accepts a file path or URL and renders the audio track in sync with the video. For automated pipelines at scale, pair Remotion with a text-to-speech API to generate personalized narration from a script template, then pass the audio URL to the composition as a prop.
Q4: How do I handle customers with non-ASCII names or Japanese characters?
React renders Unicode strings natively, so non-ASCII characters in customer names will display correctly as long as the font being used contains those glyphs. For Japanese or CJK characters in a serverless render environment, you may need to explicitly load the appropriate font files using Remotion’s font loading utilities.
Q5: Can I add closed captions or subtitles to generated videos?
Yes. You can render subtitle text directly into the video as overlaid text components synchronized to your narration script, using <Sequence> to control timing. For external subtitle files (SRT/VTT), you would parse the subtitle file, convert timestamps to frame numbers, and drive text visibility with useCurrentFrame().
Q6: Is Remotion suitable for generating hundreds of videos per day?
Yes. Remotion Lambda is designed for high-throughput rendering. Each render runs in a separate Lambda invocation, and multiple renders can run in parallel. The practical throughput depends on your AWS Lambda concurrency limits, which are configurable. Teams running personalization at scale typically pre-warm Lambda instances during peak signup hours.
Q7: How do I update the onboarding video when I ship a UI change?
Because the UI is a React mock rather than a screen recording, you update the mock component to reflect the new design. This is typically a few lines of JSX. Once committed, any new renders automatically use the updated UI — no re-recording sessions required.
Q8: What video format should I output for web-based onboarding delivery?
H.264 (MP4) is the broadest compatibility choice for web delivery and works in all major browsers without plugins. For highest quality at lower file sizes, consider H.265 (HEVC) or VP9 for browsers that support them. Use Remotion’s codec option in your render configuration to switch between formats.
Now available
Get 1,000+ Remotion Templates
Pay once — no subscription. Lifetime updates. TypeScript-first.
View pricing →