render-sdk — One render 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/render-sdkRender it locally
Renders the MP4 on your machine with the Remotion CLI.
$ pnpm dlx remotion render render-sdk out/render-sdk.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 launch video for @remocn/render-sdk. Open with a few pain questions about juggling different render provider APIs, hit a hard "Stop." beat, then land "One API, different providers" and show cards for the render and lambda adapters. Zoom into a terminal install (bun install @remocn/render-sdk), pop open a glass code block with a short usage example, and build out a logo wall of the frameworks it works with — Next.js, React, Remix, React Router. Close with a simple drawn-on box mark, the render-sdk wordmark, the v1.0.0 tag, and the tagline. Keep it clean and technical, built with remocn 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, Series, interpolate, interpolateColors, 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 { SharedAxisZ } from "@/components/remocn/shared-axis-z";
import { LogoEnter, type Logo } from "@/components/remocn/logo-enter";
import { useBlurInTransition } from "@/components/remocn/use-blur-in-transition";
import { BlurIn } from "@/components/remocn/blur-in";
import { TerminalSimulator } from "@/components/remocn/terminal-simulator";
import { CheckIcon, CopyIcon } from "lucide-react";
// Bind both fonts to the CSS variables the remocn components read.
const { fontFamily: SANS_FAMILY } = loadSans("normal", {
subsets: ["latin"],
weights: ["400", "500", "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";
// Render-engine palette — Remotion blue primary, cyan secondary.
const BLUE = "#5b9dff";
const CYAN = "#34d9e6";
const INK = "#fafafa";
const FAINT = "rgba(250,250,250,0.42)";
// ---------------------------------------------------------------------------
// Scene timings (frames @ 30fps), one per beat. Transitions overlap.
// ---------------------------------------------------------------------------
const S_INTRO = 140; // three questions via shared-axis-z
const S_STOP = 46; // STOP — scale-down-fade
const S_ONEAPI = 70; // One API, different providers
const S_ADAPTERS = 85; // render + lambda cards
const S_INSTALL = 72; // terminal install
const S_CODE = 135; // code example (GlassCodeBlock)
const S_WORKING = 80; // working with — logo-enter
const S_OUTRO = 100; // render-sdk + install pill
const T_ZOOM = 18; // intro → stop (punch in)
const T_X = 14; // generic crossfade
const T_BLUR = 16; // adapters → install (background clash)
const T_OUT = 20; // working → outro
export const RENDER_SDK_DURATION =
S_INTRO +
S_STOP +
S_ONEAPI +
S_ADAPTERS +
S_INSTALL +
S_CODE +
S_WORKING +
S_OUTRO -
(T_ZOOM + T_X + T_X + T_BLUR + T_X + T_X + T_OUT);
// ---------------------------------------------------------------------------
// Reveal — blur-in wrapper driven by useBlurInTransition.
// ---------------------------------------------------------------------------
const Reveal: React.FC<{
children: ReactNode;
delay?: number;
distance?: number;
blur?: number;
duration?: number;
display?: CSSProperties["display"];
}> = ({
children,
delay = 0,
distance = 16,
blur = 10,
duration = 20,
display = "block",
}) => {
const style = useBlurInTransition(
[{ at: delay, state: "revealed", duration }],
{ direction: "up", distance, blur },
);
return (
<BlurIn style={style} display={display}>
{children}
</BlurIn>
);
};
// ---------------------------------------------------------------------------
// Mark — inline marker swipe behind a phrase.
// ---------------------------------------------------------------------------
const Mark: React.FC<{
children: string;
color?: string;
startFrame?: number;
}> = ({ children, color = BLUE, startFrame = 8 }) => {
const frame = useCurrentFrame();
const { fps } = useVideoConfig();
const scaleX = spring({
frame: frame - startFrame,
fps,
config: { damping: 15, mass: 0.8 },
});
const textColor = interpolateColors(
interpolate(scaleX, [0.45, 0.85], [0, 1], {
extrapolateLeft: "clamp",
extrapolateRight: "clamp",
}),
[0, 1],
[INK, "#0a0a0a"],
);
return (
<span
style={{
position: "relative",
display: "inline-block",
whiteSpace: "nowrap",
}}
>
<span
aria-hidden
style={{
position: "absolute",
inset: "-0.02em -0.12em",
background: color,
borderRadius: 6,
transformOrigin: "left center",
transform: `scaleX(${scaleX})`,
zIndex: 0,
}}
/>
<span style={{ position: "relative", zIndex: 1, color: textColor }}>
{children}
</span>
</span>
);
};
// ===========================================================================
// Scene 1 — Intro. Three pain questions, each entering via shared-axis-z, in a
// single accent color. A Series resets the frame so each transition plays clean.
// ===========================================================================
const Q1 = "Building a render queue?";
const Q2 = "Two renderers — self-hosted and Lambda?";
const Q3 = "Reusing render code across projects?";
const IntroScene: React.FC = () => (
<AbsoluteFill style={{ padding: "0 90px" }}>
<Series>
<Series.Sequence durationInFrames={42} layout="none">
<SharedAxisZ
fromText=""
toText={Q1}
fontSize={44}
fontWeight={600}
color={"#FFFFFF"}
/>
</Series.Sequence>
<Series.Sequence durationInFrames={46} layout="none">
<SharedAxisZ
fromText={Q1}
toText={Q2}
fontSize={44}
fontWeight={600}
color={"#FFFFFF"}
/>
</Series.Sequence>
<Series.Sequence durationInFrames={52} layout="none">
<SharedAxisZ
fromText={Q2}
toText={Q3}
fontSize={44}
fontWeight={600}
color={"#FFFFFF"}
/>
</Series.Sequence>
</Series>
</AbsoluteFill>
);
// ===========================================================================
// Scene 2 — STOP. scale-down-fade settles a single hard word, then lets it go.
// ===========================================================================
const StopScene: React.FC = () => (
<AbsoluteFill style={{ alignItems: "center", justifyContent: "center" }}>
<SharedAxisZ
fromText={""}
toText={"Stop"}
fontSize={200}
fontWeight={600}
color={"#FFFFFF"}
/>
</AbsoluteFill>
);
// ===========================================================================
// Scene 3 — One API, different providers.
// ===========================================================================
const OneApiScene: React.FC = () => (
<AbsoluteFill
style={{
alignItems: "center",
justifyContent: "center",
flexDirection: "column",
gap: 14,
}}
>
<Reveal delay={4} distance={20} blur={12} duration={22}>
<h1
style={{
margin: 0,
fontFamily: SANS,
fontWeight: 500,
fontSize: 48,
color: INK,
textAlign: "center",
}}
>
Use Render SDK
</h1>
</Reveal>
<Reveal delay={16} distance={16} blur={10}>
<h2
style={{
margin: 0,
fontFamily: SANS,
fontWeight: 600,
fontSize: 32,
color: INK,
textAlign: "center",
}}
>
<Mark color={BLUE} startFrame={26}>
One API
</Mark>{" "}
Different providers
</h2>
</Reveal>
</AbsoluteFill>
);
// ===========================================================================
// Scene 4 — Adapters: render + lambda cards.
// ===========================================================================
const AdapterCard: React.FC<{
accent: string;
title: string;
pkg: string;
desc: string;
call: string;
delay: number;
}> = ({ accent, title, pkg, desc, call, delay }) => (
<Reveal delay={delay} distance={36} blur={12} duration={20}>
<div
style={{
width: 360,
display: "flex",
flexDirection: "column",
gap: 14,
padding: "28px 30px",
borderRadius: 20,
background: "rgba(10,10,10,0.55)",
border: `1px solid ${accent}44`,
boxShadow: "0 20px 50px rgba(0,0,0,0.45)",
}}
>
<div style={{ display: "flex", alignItems: "center", gap: 12 }}>
<span
style={{
width: 11,
height: 11,
borderRadius: "50%",
background: accent,
}}
/>
<span
style={{
fontFamily: SANS,
fontWeight: 700,
fontSize: 28,
color: INK,
}}
>
{title}
</span>
</div>
<span style={{ fontFamily: MONO, fontSize: 16, color: "#a1a1aa" }}>
{pkg}
</span>
<span
style={{
fontFamily: SANS,
fontSize: 18,
color: "rgba(255,255,255,0.7)",
}}
>
{desc}
</span>
<span
style={{
marginTop: 4,
alignSelf: "flex-start",
fontFamily: MONO,
fontSize: 15,
color: accent,
padding: "7px 14px",
borderRadius: 10,
background: `${accent}1f`,
}}
>
{call}
</span>
</div>
</Reveal>
);
const AdaptersScene: React.FC = () => (
<AbsoluteFill
style={{
alignItems: "center",
justifyContent: "center",
flexDirection: "column",
gap: 36,
}}
>
<Reveal delay={2} distance={16} blur={10}>
<h2
style={{
margin: 0,
fontFamily: SANS,
fontWeight: 600,
fontSize: 40,
color: INK,
textAlign: "center",
}}
>
Two adapters, one interface
</h2>
</Reveal>
<div style={{ display: "flex", gap: 36 }}>
<AdapterCard
accent={BLUE}
title="Render"
pkg="@remotion/renderer"
desc="Local & self-hosted rendering."
call="serverAdapter()"
delay={8}
/>
<AdapterCard
accent={CYAN}
title="Lambda"
pkg="@remotion/lambda"
desc="Serverless rendering at scale."
call="lambdaAdapter()"
delay={16}
/>
</div>
</AbsoluteFill>
);
// ===========================================================================
// Scene 5 — Install (no heading). terminal-cursor-zoom dollies across the typed
// install command.
// ===========================================================================
const InstallScene: React.FC = () => (
<AbsoluteFill>
<TerminalSimulator
lines={[{ text: "bun install @remocn/render-sdk", type: "command", delay: 0 }]}
fontSize={22}
title="~/code/my-app"
charsPerFrame={2}
/>
</AbsoluteFill>
);
// ===========================================================================
// Scene 6 — Code Example (from the docs), shown in a GlassCodeBlock.
// ===========================================================================
const CODE_EXAMPLE = `import { RenderSdk } from "@remocn/render-sdk";
import { serverAdapter } from "@remocn/render-sdk/server";
const sdk = new RenderSdk({ adapter: serverAdapter() });
const renderId = await sdk.start({
compositionId: "MyVideo",
inputProps: { title: "Hello" },
});
await sdk.waitForCompletion(renderId, {Showing the first 400 of 900 lines. View the full file on GitHub.