Batchwork — Unified Batch API
Install this video
Adds the full composition, its remocn dependencies, and the prompt to your Remotion project via the shadcn registry.
$ pnpm dlx shadcn@latest add kapishdima/remocn-demo/batchworkRender it locally
Renders the MP4 on your machine with the Remotion CLI.
$ pnpm dlx remotion render batchwork out/batchwork.mp4 --scale=2 --crf=15 --x264-preset=slower --jpeg-quality=95The prompt
Reconstructed draftA reconstruction of the prompt this video was generated from.
Make a short product spot for batchwork — it's one batch API that works across every AI provider instead of juggling each provider's own batch endpoint. Lean on glass code windows to show the actual API usage and use marker-style highlights to call out the parts that matter (one client, swap the provider, same shape). Keep it tight and code-forward rather than heavy on marketing copy. Build it with remocn's glass code block and highlight components.
The code
The exact source the AI wrote — the same files the install command puts in your project.
import React, { type CSSProperties, type ReactNode } from "react";
import { AbsoluteFill, Easing, interpolate, spring, useCurrentFrame, useVideoConfig } from "remotion";
import { demoAsset } from "@/lib/demo-assets";
import {
TransitionSeries,
linearTiming,
type TransitionPresentation,
type TransitionPresentationComponentProps,
} from "@remotion/transitions";
import { loadFont as loadSans } from "@remotion/google-fonts/Manrope";
import { loadFont as loadMono } from "@remotion/google-fonts/GeistMono";
import { RemocnUIProvider } from "@/lib/remocn-ui";
import { Backdrop } from "@/components/remocn/backdrop";
import { GlassCodeBlock } from "@/components/remocn/glass-code-block";
import { MarkerHighlight } from "@/components/remocn/marker-highlight";
import { useBlurInTransition } from "@/components/remocn/use-blur-in-transition";
import { BlurIn, type BlurInDirection } from "@/components/remocn/blur-in";
// Bind both fonts to the CSS variables the remocn components read.
const { fontFamily: SANS_FAMILY } = loadSans("normal", {
subsets: ["latin"],
weights: ["400", "600", "700", "800"],
});
const { fontFamily: MONO_FAMILY } = loadMono("normal", {
subsets: ["latin"],
weights: ["400", "700"],
});
const SANS = "var(--font-geist-sans), -apple-system, BlinkMacSystemFont, sans-serif";
const MONO = "var(--font-geist-mono), ui-monospace, SFMono-Regular, monospace";
const GREEN = "#4ade80";
const YELLOW = "#facc15";
// ---------------------------------------------------------------------------
// Scene timings (frames @ 30fps). Transitions overlap consecutive scenes.
// ---------------------------------------------------------------------------
const S1 = 76; // hook — holds long enough for the headline to land
const S2 = 58; // subtitle + install
const S3 = 86; // one API for every batch provider
const S4 = 90; // works with any AI SDK model
const S5 = 82; // automatic polling & webhooks
const S6 = 90; // drop straight into Next.js
const S7 = 100; // final logo
// Transition durations — quick enough to feel snappy, long enough to read the
// motion (slide + blur + scale).
const TI = 18; // intro → install (zoom-blur push)
const TK = 16; // kinetic slide between content scenes
const TO = 20; // into the final logo
export const BATCHWORK_DURATION =
S1 + S2 + S3 + S4 + S5 + S6 + S7 - (TI + 4 * TK + TO);
// ---------------------------------------------------------------------------
// Reveal — blur-in wrapper driven by useBlurInTransition.
// ---------------------------------------------------------------------------
const Reveal: React.FC<{
children: ReactNode;
delay?: number;
direction?: BlurInDirection;
distance?: number;
blur?: number;
duration?: number;
display?: CSSProperties["display"];
}> = ({
children,
delay = 0,
direction = "up",
distance = 16,
blur = 10,
duration = 20,
display = "block",
}) => {
const style = useBlurInTransition(
[{ at: delay, state: "revealed", duration }],
{ direction, distance, blur },
);
return (
<BlurIn style={style} display={display}>
{children}
</BlurIn>
);
};
// ---------------------------------------------------------------------------
// Mark — inline marker-highlight swipe behind a phrase, tuned for the dark
// backdrop (white text that turns dark as the marker arrives).
// ---------------------------------------------------------------------------
const Mark: React.FC<{
children: string;
color?: string;
after?: string;
}> = ({ children, color = GREEN, after = "" }) => (
<MarkerHighlight
highlight={children}
after={after}
markerColor={color}
baseColor="#fafafa"
highlightedTextColor="#0a0a0a"
/>
);
// ---------------------------------------------------------------------------
// Provider icons — circular brand monograms.
// ---------------------------------------------------------------------------
const PROVIDERS = [
{ label: "OpenAI", glyph: "✸", bg: "#0a0a0a", fg: "#ffffff" },
{ label: "Claude", glyph: "✳", bg: "#d97757", fg: "#ffffff" },
{ label: "Mistral", glyph: "▲", bg: "linear-gradient(135deg,#ff7000,#ffd21e)", fg: "#0a0a0a" },
{ label: "xAI", glyph: "𝕏", bg: "#111111", fg: "#ffffff" },
{ label: "Gemini", glyph: "✦", bg: "linear-gradient(135deg,#4796e3,#9177c7,#d96570)", fg: "#ffffff" },
{ label: "Perplexity", glyph: "≈", bg: "#20808d", fg: "#ffffff" },
];
const ProviderIcons: React.FC<{
size?: number;
baseDelay?: number;
/** How far each icon slides under the previous one, in px. */
overlap?: number;
}> = ({ size = 110, baseDelay = 4, overlap }) => {
const ov = overlap ?? Math.round(size * 0.36);
return (
<div style={{ display: "flex", alignItems: "center" }}>
{PROVIDERS.map((p, i) => (
<div
key={p.label}
style={{
marginLeft: i === 0 ? 0 : -ov,
// Left icons sit on top so the stack reads as a left-to-right fan.
zIndex: PROVIDERS.length - i,
}}
>
<Reveal delay={baseDelay + i * 4} distance={16} blur={8}>
<div
style={{
width: size,
height: size,
borderRadius: "50%",
background: p.bg,
color: p.fg,
display: "flex",
alignItems: "center",
justifyContent: "center",
fontSize: size * 0.42,
fontWeight: 700,
fontFamily: SANS,
// Dark ring separates the overlapping circles, plus drop shadow.
boxShadow:
"0 0 0 5px rgba(10,10,10,0.9), 0 16px 36px rgba(0,0,0,0.5)",
border: "1px solid rgba(255,255,255,0.18)",
}}
>
{p.glyph}
</div>
</Reveal>
</div>
))}
</div>
);
};
// ---------------------------------------------------------------------------
// Install pill — $ npm install batchwork.
// ---------------------------------------------------------------------------
const InstallPill: React.FC<{ fontSize?: number }> = () => (
<div
style={{
display: "inline-flex",
alignItems: "center",
gap: 10,
padding: "12px 24px",
borderRadius: 999,
background: "rgba(10,10,10,0.55)",
border: "1px solid rgba(255,255,255,0.14)",
boxShadow: "0 16px 40px rgba(0,0,0,0.4)",
fontFamily: MONO,
fontSize: 18,
letterSpacing: "-0.01em",
}}
>
<span style={{ color: GREEN }}>$</span>
<span style={{ color: "#d4d4d8" }}>npm install</span>
<span style={{ color: "#ffffff", fontWeight: 700 }}>batchwork</span>
</div>
);
// ---------------------------------------------------------------------------
// Shared text styles.
// ---------------------------------------------------------------------------
const headingStyle: CSSProperties = {
margin: 0,
fontFamily: SANS,
fontWeight: 500,
fontSize: 42,
lineHeight: 1.12,
color: "#fafafa",
};
const paragraphStyle: CSSProperties = {
margin: 0,
fontFamily: SANS,
fontWeight: 400,
fontSize: 21,
lineHeight: 1.55,
color: "rgba(255,255,255,0.72)",
maxWidth: 470,
};
// ---------------------------------------------------------------------------
// Split scene — text column + glass code window, alternating sides.
// ---------------------------------------------------------------------------
const SplitScene: React.FC<{
textLeft: boolean;
heading: ReactNode;
paragraph: ReactNode;
extra?: ReactNode;
codeTitle: string;
code: string;
}> = ({ textLeft, heading, paragraph, extra, codeTitle, code }) => {
const textCol = (
<div
key="text"
style={{
flex: 1,
padding: "0 56px",
display: "flex",
flexDirection: "column",
justifyContent: "center",
gap: 22,
alignItems: "flex-start",
}}
>
<Reveal delay={3} distance={18}>
<h2 style={headingStyle}>{heading}</h2>
</Reveal>
<Reveal delay={10} distance={14}>
<p style={paragraphStyle}>{paragraph}</p>
</Reveal>
{extra ? (
<Reveal delay={18} distance={12}>
{extra}
</Reveal>
) : null}
</div>
);
const codeCol = (
<div
key="code"
style={{
flex: 1,
display: "flex",
alignItems: "center",
justifyContent: "center",
}}
>
<Reveal
delay={6}
distance={72}
blur={14}
duration={20}
direction={textLeft ? "left" : "right"}
>
<div style={{ position: "relative", width: 600, height: 430 }}>
<GlassCodeBlock
code={code}
title={codeTitle}
width={600}
height={430}
fontSize={13}
staggerFrames={2}
/>
</div>
</Reveal>
</div>
);
return (
<AbsoluteFill style={{ flexDirection: "row", alignItems: "center" }}>
{textLeft ? [textCol, codeCol] : [codeCol, textCol]}
</AbsoluteFill>
);
};
// ---------------------------------------------------------------------------
// Scene 1 — Hook.
// ---------------------------------------------------------------------------
const HookScene: React.FC = () => (
<AbsoluteFill
style={{
alignItems: "center",
justifyContent: "center",
flexDirection: "column",
gap: 44,
}}
>
<Reveal delay={14} distance={22} blur={12} duration={24}>
<h1
style={{
...headingStyle,
fontSize: 56,
textAlign: "center",
lineHeight: 1.05,
}}
>
Save up to{" "}
<Mark color={GREEN}>
50%
</Mark>{" "}
on inference costs
</h1>
</Reveal>
<ProviderIcons size={116} baseDelay={2} />
</AbsoluteFill>
);
// ---------------------------------------------------------------------------
// Scene 2 — Subtitle + install.
// ---------------------------------------------------------------------------
const InstallScene: React.FC = () => (
<AbsoluteFill
style={{
alignItems: "center",
justifyContent: "center",
flexDirection: "column",
gap: 26,
padding: "0 120px",
}}
>
<Reveal delay={4} distance={18}>
<h2
style={{
...headingStyle,
fontSize: 52,
textAlign: "center",
}}
>
Unified batch API for AI providers.
</h2>
</Reveal>
<Reveal delay={14} distance={14}>
<p
style={{
...paragraphStyle,
fontSize: 23,
maxWidth: 720,
textAlign: "center",
color: "rgba(255,255,255,0.78)",
}}
>
Process LLM requests in bulk with a single call for lower costs.
Processing, uploading, polling, and result parsing handled for you.
</p>
</Reveal>
<Reveal delay={26} distance={14}>
<InstallPill fontSize={24} />
</Reveal>
</AbsoluteFill>
);
// ---------------------------------------------------------------------------
// Scene 5 extra — webhook delivery badge.
// ---------------------------------------------------------------------------
const WebhookBadge: React.FC = () => (
<div
style={{
display: "inline-flex",
alignItems: "center",
gap: 10,
padding: "9px 16px",
borderRadius: 10,
background: "rgba(10,10,10,0.5)",
border: "1px solid rgba(74,222,128,0.3)",
fontFamily: MONO,
fontSize: 17,
color: "#d4d4d8",
}}
>
<span style={{ color: GREEN }}>▸</span>
<span style={{ color: "#fafafa" }}>batch.completed</span>
<span style={{ color: "#71717a" }}>→</span>
<span style={{ color: GREEN }}>webhook delivered</span>
</div>
);
// ---------------------------------------------------------------------------
// Scene 7 — Final logo.
// ---------------------------------------------------------------------------
const OutroScene: React.FC = () => {
const frame = useCurrentFrame();
const { fps } = useVideoConfig();
const wordmark = useBlurInTransition(
[{ at: 10, state: "revealed", duration: 26 }],
{ direction: "up", distance: 20, blur: 18 },
);
const dot = spring({ frame: frame - 22, fps, config: { damping: 13 } });Showing the first 400 of 736 lines. View the full file on GitHub.