Remotion for Instagram Reels and TikTok Automation: Batch-Generate 100 Videos a Day
Remotion for Instagram Reels and TikTok Automation: Batch-Generate 100 Videos a Day
Short-form vertical video has become the most powerful organic distribution channel available to marketing teams. Instagram Reels consistently outperform static posts in reach, and TikTok’s algorithm rewards volume alongside quality — meaning the teams that publish more relevant content win more views. The bottleneck is no longer creativity. It is production speed.
Remotion — the framework that lets you build videos as React components — offers a genuinely different solution to that bottleneck. Instead of editing clips one at a time in a timeline, you describe your video as code, feed it data, and render as many variants as your pipeline requires. This guide covers everything a social media manager or marketing engineering team needs to know: vertical format setup, hook-first visual storytelling, animated captions, trending motion styles, and scaling to 100+ renders per day with @remotion/lambda.
Why Remotion Fits Vertical Video Production
Traditional video editors treat every export as a manual job. Even with templates, producing 50 product showcase Reels from a catalog means 50 separate sessions of drag, drop, type, render, and export. Remotion treats a video as a function: given a set of input props (product name, price, image URL, CTA text), it outputs a pixel-perfect MP4. Change the data, get a different video.
For Reels and TikTok specifically, this approach unlocks:
- Catalog-driven production — render one Reel per product row in a spreadsheet
- Consistent branding — every video uses identical motion timing and typography, no human error
- Instant A/B variants — swap a color variable or CTA string and re-render in seconds
- Programmatic scheduling — pipe the output files directly into a publishing API (Buffer, Later, or a direct Meta/TikTok API integration)
Setting Up a 9:16 Composition for Reels and TikTok
Both Instagram Reels and TikTok use the 1080×1920 vertical format at 30 fps. The <Composition> definition is the first thing to get right:
// src/Root.tsx
import { Composition } from "remotion";
import { ReelTemplate } from "./ReelTemplate";
export const RemotionRoot: React.FC = () => {
return (
<>
<Composition
id="InstagramReel"
component={ReelTemplate}
width={1080}
height={1920}
fps={30}
durationInFrames={450} // 15 seconds
defaultProps={{
productName: "Sample Product",
productImage: "https://example.com/product.jpg",
price: "$49",
ctaText: "Shop Now",
accentColor: "#FF5733",
}}
/>
</>
);
};
For TikTok, the composition settings are identical — the difference is in the safe zone your layout respects. TikTok’s action bar (like, comment, share, profile buttons) occupies roughly the right 15% of the frame and the bottom 200px. Instagram’s UI sits at the bottom ~300px. A safe rule for both: keep critical text and the main subject within a centered 900×1500px area, with your CTA placed above the 1650px vertical mark.
Duration strategy:
- 7–15 seconds: optimal for product showcases and promotional announcements
- 15–30 seconds: tutorials, before/after reveals, multi-feature highlights
- Keep
durationInFramesatfps * seconds— e.g., a 10-second clip at 30 fps =300frames
Hook-First Visual Storytelling: The First 3 Seconds
Both platforms use watch-time as the primary ranking signal. If a viewer drops off in the first 3 seconds, the video receives almost no distribution. Your Remotion composition should treat frames 0–90 (at 30 fps) as the “hook zone” — the moment that arrests the scroll.
Effective hook patterns for automated Reels:
1. The Attention Interrupt Open on a full-bleed color or image that doesn’t match the scroll feed. A deeply saturated solid color (not white, not grey) with a single large centered word achieves this in one frame.
// Instant full-color frame for frames 0-30
const hookOpacity = interpolate(frame, [0, 5], [0, 1], {
extrapolateLeft: "clamp",
extrapolateRight: "clamp",
});
<AbsoluteFill style={{ backgroundColor: accentColor, opacity: hookOpacity }}>
<div style={{
position: "absolute",
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
fontSize: 120,
fontWeight: 900,
color: "#FFFFFF",
fontFamily: '-apple-system, "Segoe UI", Roboto, sans-serif',
textAlign: "center",
lineHeight: 1.1,
}}>
{hookText}
</div>
</AbsoluteFill>
2. The Pop-In Title Start invisible, spring into place at full size by frame 12:
import { spring, useCurrentFrame, useVideoConfig } from "remotion";
const frame = useCurrentFrame();
const { fps } = useVideoConfig();
const scale = spring({
frame,
fps,
config: { damping: 14, stiffness: 200, mass: 0.8 },
from: 0,
to: 1,
});
3. Number Counter Hook If you are showcasing a stat, open with the number rapidly counting up from zero. A large number in motion is almost impossible to scroll past. (See the counter animation pattern in the financial data visualization article for a full implementation.)
Animated Captions and On-Screen Text Pop-Ins
Captions are not optional for short-form content — research consistently shows that 80%+ of users watch without sound. In Remotion, captions are first-class citizens: they are React components that you control with the same frame-based precision as everything else.
Simple Word-by-Word Caption System
interface CaptionProps {
words: Array<{ text: string; startFrame: number; endFrame: number }>;
}
const AnimatedCaption: React.FC<CaptionProps> = ({ words }) => {
const frame = useCurrentFrame();
return (
<div style={{
position: "absolute",
bottom: 400,
left: 60,
right: 60,
textAlign: "center",
}}>
{words.map((word, i) => {
const isActive = frame >= word.startFrame && frame <= word.endFrame;
const scale = isActive
? spring({ frame: frame - word.startFrame, fps: 30,
config: { damping: 12, stiffness: 300 }, from: 0.8, to: 1 })
: 1;
return (
<span
key={i}
style={{
display: "inline-block",
fontSize: 68,
fontWeight: 800,
color: isActive ? "#FFFF00" : "#FFFFFF",
textShadow: "0 4px 12px rgba(0,0,0,0.6)",
margin: "0 8px",
transform: `scale(${scale})`,
transition: "color 0.1s",
fontFamily: '-apple-system, "Segoe UI", Roboto, sans-serif',
}}
>
{word.text}
</span>
);
})}
</div>
);
};
Auto-Generating Caption Timing
When you are batch-generating from a content schedule, hardcoding word timings is impractical. Instead, build a timing generator that distributes words evenly across the clip duration:
function buildCaptionWords(
text: string,
startFrame: number,
endFrame: number
): Array<{ text: string; startFrame: number; endFrame: number }> {
const words = text.split(" ");
const framesPerWord = Math.floor((endFrame - startFrame) / words.length);
return words.map((word, i) => ({
text: word,
startFrame: startFrame + i * framesPerWord,
endFrame: startFrame + (i + 1) * framesPerWord - 1,
}));
}
For production pipelines with voiceover audio, use Remotion’s @remotion/captions package (released in Remotion 4.x) which accepts SRT or VTT files and syncs captions to audio timestamps automatically.
Trending Visual Styles Replicated in React
Short-form platforms cycle through visual trends quickly, but several styles have proven durable enough to build automation templates around.
Style 1: Gradient Text with Reveal Wipe
const wipe = interpolate(frame, [20, 60], [0, 100], {
extrapolateLeft: "clamp",
extrapolateRight: "clamp",
});
<div style={{
background: "linear-gradient(135deg, #FF6B6B, #4ECDC4, #45B7D1)",
WebkitBackgroundClip: "text",
WebkitTextFillColor: "transparent",
clipPath: `inset(0 ${100 - wipe}% 0 0)`,
fontSize: 96,
fontWeight: 900,
fontFamily: '-apple-system, "Segoe UI", Roboto, sans-serif',
}}>
{headlineText}
</div>
Style 2: Staggered Card Stack
Render 3–5 product benefit cards that fly in sequentially, each offset by 8 frames:
const cards = benefits.map((benefit, i) => {
const delay = i * 8;
const y = interpolate(frame - delay, [0, 20], [200, 0], {
extrapolateLeft: "clamp",
extrapolateRight: "clamp",
easing: Easing.out(Easing.cubic),
});
const opacity = interpolate(frame - delay, [0, 15], [0, 1], {
extrapolateLeft: "clamp",
extrapolateRight: "clamp",
});
return { ...benefit, y, opacity };
});
Style 3: Kinetic Zoom Product Reveal
Scale a product image from 120% to 100% while a text label fades in — a subtle Ken Burns effect that implies motion without distraction:
const scale = interpolate(frame, [0, 60], [1.2, 1.0], {
extrapolateLeft: "clamp",
extrapolateRight: "clamp",
easing: Easing.out(Easing.quad),
});
<Img
src={productImage}
style={{ width: "100%", height: "100%", objectFit: "cover",
transform: `scale(${scale})` }}
/>
Batch Rendering with @remotion/lambda
Once your template is working locally, @remotion/lambda is the path to rendering 100 videos per day without occupying a local machine. Lambda renders each video in a separate AWS Lambda function invocation — individual 15-second Reels typically complete in under 30 seconds of wall-clock time.
Setup Overview
npm i @remotion/lambda
npx remotion lambda policies validate
npx remotion lambda sites create --site-name=reel-factory
Triggering a Batch Render from a Data Source
import { renderMediaOnLambda, getRenderProgress } from "@remotion/lambda/client";
interface ProductRow {
productName: string;
price: string;
imageUrl: string;
ctaText: string;
}
async function renderBatch(products: ProductRow[]) {
const renders = await Promise.all(
products.map((product) =>
renderMediaOnLambda({
region: "us-east-1",
functionName: "remotion-render-4-0-0-mem2048mb-disk2048mb-240sec",
serveUrl: process.env.REMOTION_SERVE_URL!,
composition: "InstagramReel",
inputProps: {
productName: product.productName,
price: product.price,
productImage: product.imageUrl,
ctaText: product.ctaText,
accentColor: "#FF5733",
},
codec: "h264",
imageFormat: "jpeg",
maxRetries: 3,
outName: `reel-${product.productName.replace(/\s+/g, "-").toLowerCase()}.mp4`,
})
)
);
return renders.map((r) => r.renderId);
}
Monitoring Progress and Fetching Output URLs
async function pollUntilDone(renderId: string, bucketName: string) {
while (true) {
const progress = await getRenderProgress({
renderId,
bucketName,
functionName: process.env.REMOTION_FUNCTION_NAME!,
region: "us-east-1",
});
if (progress.done) return progress.outputFile;
if (progress.fatalErrorEncountered) throw new Error(progress.errors[0].message);
await new Promise((res) => setTimeout(res, 3000));
}
}
Throughput at scale: Lambda’s default concurrency limit is 1,000 concurrent invocations per AWS account per region. A 15-second Reel at 1080×1920/30fps typically renders in 20–35 seconds. With 50 concurrent Lambda invocations, a batch of 100 videos completes in roughly 2–4 minutes of total elapsed time.
Practical Workflow for Social Media Teams
Here is a complete end-to-end workflow that a marketing team can operate without writing code day-to-day:
1. Content spreadsheet as the source of truth
Maintain a Google Sheet (or Airtable base) with columns: productName, price, imageUrl, ctaText, accentColor, publishDate, platform.
2. Automated fetch and render trigger
A Node.js script (run on a schedule via GitHub Actions, n8n, or a cron job) reads new rows, calls renderMediaOnLambda, stores the output S3 URL back in the sheet.
3. Review queue Before publishing, a human reviewer screens the S3 URLs in a lightweight internal tool (a simple React page that shows the video and approve/reject buttons).
4. Scheduled publish Approved videos are queued in a publishing tool that calls the Meta Graph API or TikTok for Developers API at the scheduled time.
This pipeline eliminates the manual steps between “we have product data” and “video is live on TikTok” — the only human touchpoints are content strategy and the final review.
RenderComp: Production-Ready Reels Templates
Building and refining a vertical video template from scratch — getting the safe zones right, polishing the spring curves, making the caption system robust across varying text lengths — takes days of iteration. RenderComp offers a library of production-tested Remotion templates purpose-built for Instagram Reels and TikTok, including:
- Vertical 9:16 compositions pre-sized at 1080×1920
- Hook-first opening sequences with configurable timing
- Word-by-word caption components compatible with
@remotion/captions - Staggered card and product showcase layouts
- Lambda-ready export configurations
Every template ships with full TypeScript types, documented props, and example data-driven render scripts. Drop your data in, customize colors and fonts, and start rendering the same day.
FAQ
Q: Do Instagram Reels and TikTok have different technical requirements for uploaded videos?
A: Both accept H.264-encoded MP4 at 1080×1920 with AAC audio. The main practical difference is safe zones — TikTok’s action buttons sit on the right side, Instagram’s UI is at the bottom. Remotion’s @remotion/lambda renders H.264 by default. Keep essential content within a centered 900×1500px area to be safe on both platforms.
Q: Can I add voiceover audio to my Reels generated by Remotion?
A: Yes. The <Audio> component accepts a src prop pointing to any MP4-compatible audio file (MP3, AAC, WAV). Pass the audio URL as a prop to your composition, adjust startFrom and endAt for trimming, and Remotion will mux audio and video automatically at render time.
Q: How do I handle product images that are the wrong aspect ratio?
A: Use objectFit: "cover" on the <Img> component and control the frame/crop with CSS objectPosition. For square product images in a vertical frame, center-crop works well. Alternatively, place the image in a contained box and add a blurred, full-bleed version of the same image as the background layer.
Q: What is the cost of rendering 100 Reels per day on AWS Lambda? A: Exact costs depend on memory allocation and render duration. A typical 15-second 1080×1920 Reel with a 3,008 MB Lambda function and a 30-second render duration costs roughly $0.05–$0.12 per video. At 100 videos/day, you are looking at $5–$12/day in Lambda costs, plus S3 storage and data transfer.
Q: Can I use @remotion/lambda without an AWS account?
A: @remotion/lambda specifically requires AWS. For alternatives, Remotion Cloud Run supports Google Cloud, and Remotion Server-Side Rendering can be used with any Node.js host (Railway, Fly.io, a VPS). For low volumes (under 10 videos/day), local rendering via npx remotion render is free and simple.
Q: How do I keep brand colors and fonts consistent across 100 batch-rendered videos?
A: Define all brand tokens in a single TypeScript file (e.g., src/brand.ts) and import them into your composition. Pass nothing brand-related as per-video input props — only content data (product name, image, price) should vary. This way, a single source-of-truth file controls every video’s visual identity.
Q: Is Remotion suitable for TikTok trends that rely on fast cuts and music sync?
A: Remotion gives you frame-level control, so music sync is achievable by analyzing a track’s BPM and computing beat timestamps as frame numbers. Fast cut sequences are <Series> components where each <Series.Sequence> is a single beat long. It requires more setup than a traditional editor, but the result is perfectly reproducible and batch-renderable.
Now available
Get 1,000+ Remotion Templates
Pay once — no subscription. Lifetime updates. TypeScript-first.
View pricing →