All demos

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-sdk

Render 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=95

The prompt

Reconstructed draft

A 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.