All demos

shadcn/ui — Not a library. Your code.

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/shadcn-ui

Render it locally

Renders the MP4 on your machine with the Remotion CLI.

$ pnpm dlx remotion render shadcn-ui out/shadcn-ui.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 proper product demo for shadcn/ui, styled exactly like the real thing — zinc-950 canvas, Geist Sans and Geist Mono, hairline grid, white marker highlights, no color. Open with a ticker-style hook that cycles "a component library? a package?" and lands on "No — it's your code", then a beat on the pain of fighting an installed black-box library. Introduce shadcn/ui with the "Open Source. Open Code." line, run a terminal typing npx shadcn add button and show the file landing in the project, then open button.tsx in a glass code block with the cva variants to sell "change anything, it's yours". Add four pillar cards (Open Code, Composable, Themeable, AI-Ready), show shipping a custom component with npx shadcn add @acme/card, roll up the proof numbers (100,000+ stars, 20,000+ projects, works across Next.js/Vite/Remix/Astro/Laravel), and close with the wordmark and npx shadcn init pointing to ui.shadcn.com. Use remocn components throughout.

The code

The exact source the AI wrote — the same files the install command puts in your project.

import React, { type ReactNode } from "react";
import {
  AbsoluteFill,
  Easing,
  Series,
  interpolate,
  interpolateColors,
  spring,
  useCurrentFrame,
  useVideoConfig,
} from "remotion";
import {
  TransitionSeries,
  linearTiming,
  type TransitionPresentation,
  type TransitionPresentationComponentProps,
} from "@remotion/transitions";
import { loadFont as loadSans } from "@remotion/google-fonts/Geist";
import { loadFont as loadMono } from "@remotion/google-fonts/GeistMono";

import { RemocnUIProvider } from "@/lib/remocn-ui";
import { VideoScopeStyle } from "@/demos/_ui/video-scope";
import { SharedAxisZ } from "@/components/remocn/shared-axis-z";
import { TerminalSimulator } from "@/components/remocn/terminal-simulator";
import { GlassCodeBlock } from "@/components/remocn/glass-code-block";
import { RollingNumber } from "@/components/remocn/rolling-number";
import { BlurIn } from "@/components/remocn/blur-in";
import { useBlurInTransition } from "@/components/remocn/use-blur-in-transition";
import { CheckIcon, CopyIcon } from "lucide-react";

// Bind shadcn's real typefaces to the CSS variables the remocn components read.
const { fontFamily: SANS_FAMILY } = loadSans("normal", {
  subsets: ["latin"],
  weights: ["400", "500", "600", "700"],
});
const { fontFamily: MONO_FAMILY } = loadMono("normal", {
  subsets: ["latin"],
  weights: ["400", "500", "700"],
});

const SANS =
  "var(--font-geist-sans), -apple-system, BlinkMacSystemFont, sans-serif";
const MONO = "var(--font-geist-mono), ui-monospace, SFMono-Regular, monospace";

// shadcn/ui palette — monochrome zinc, white ink, hairline borders. No accent
// color: the brand IS the restraint. The marker highlight is white-on-black.
const BG = "#09090b"; //     zinc-950 canvas
const INK = "#fafafa"; //    zinc-50 text
const MUTED = "#a1a1aa"; //  zinc-400
const FAINT = "rgba(250,250,250,0.45)";
const BORDER = "rgba(255,255,255,0.10)";
const CARD = "rgba(255,255,255,0.03)";

// ---------------------------------------------------------------------------
// Scene timings (frames @ 30fps), one per beat. Transitions overlap.
// ---------------------------------------------------------------------------
const S_HOOK = 130; //    ticker-takeover — library? package? → your code
const S_PAIN = 95; //     kinetic pain lines
const S_INTRO = 90; //    Open Source. Open Code.
const S_INSTALL = 125; // terminal — npx shadcn add button
const S_CODE = 135; //    glass code block — it's yours now
const S_BENEFIT = 120; // four pillar cards
const S_DISTRIB = 115; // ship your own — @acme registry
const S_PROOF = 130; //   frameworks + rolling stats
const S_CTA = 100; //     wordmark + init pill

const T_X = 14; //    crossfade
const T_ZOOM = 18; // section turn (zoom-through)

export const SHADCN_DURATION =
  S_HOOK +
  S_PAIN +
  S_INTRO +
  S_INSTALL +
  S_CODE +
  S_BENEFIT +
  S_DISTRIB +
  S_PROOF +
  S_CTA -
  (T_X + T_ZOOM + T_ZOOM + T_X + T_ZOOM + T_X + T_ZOOM + T_ZOOM);

// ---------------------------------------------------------------------------
// Reveal — blur-in wrapper driven by useBlurInTransition.
// ---------------------------------------------------------------------------
const Reveal: React.FC<{
  children: ReactNode;
  delay?: number;
  distance?: number;
  blur?: number;
  duration?: number;
  display?: React.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 — white marker swipe behind a phrase, text flips to black. Pure shadcn.
// ---------------------------------------------------------------------------
const Mark: React.FC<{ children: string; startFrame?: number }> = ({
  children,
  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, "#09090b"],
  );
  return (
    <span
      style={{
        position: "relative",
        display: "inline-block",
        whiteSpace: "nowrap",
      }}
    >
      <span
        aria-hidden
        style={{
          position: "absolute",
          inset: "-0.04em -0.14em",
          background: INK,
          borderRadius: 6,
          transformOrigin: "left center",
          transform: `scaleX(${scaleX})`,
          zIndex: 0,
        }}
      />
      <span style={{ position: "relative", zIndex: 1, color: textColor }}>
        {children}
      </span>
    </span>
  );
};

// ===========================================================================
// Scene 1 — Hook. Ticker-takeover: two labels cycle through one slot, then the
// "No." crashes in and resolves to "It's your code."
// ===========================================================================
const Q1 = "A component library?";
const Q2 = "A package you install?";

const PayoffScene: React.FC = () => (
  <AbsoluteFill
    style={{
      alignItems: "center",
      justifyContent: "center",
      flexDirection: "column",
      gap: 10,
    }}
  >
    <Reveal delay={0} distance={10} blur={6} duration={10}>
      <span
        style={{
          fontFamily: SANS,
          fontWeight: 500,
          fontSize: 30,
          color: MUTED,
        }}
      >
        No.
      </span>
    </Reveal>
    <Reveal delay={6} distance={26} blur={16} duration={20}>
      <h1
        style={{
          margin: 0,
          fontFamily: SANS,
          fontWeight: 600,
          fontSize: 76,
          letterSpacing: "-0.03em",
          color: INK,
          textAlign: "center",
        }}
      >
        It&apos;s <Mark startFrame={22}>your code</Mark>.
      </h1>
    </Reveal>
  </AbsoluteFill>
);

const HookScene: React.FC = () => (
  <AbsoluteFill style={{ padding: "0 90px" }}>
    <Series>
      <Series.Sequence durationInFrames={40} layout="none">
        <SharedAxisZ
          fromText=""
          toText={Q1}
          fontSize={52}
          fontWeight={600}
          color={INK}
        />
      </Series.Sequence>
      <Series.Sequence durationInFrames={42} layout="none">
        <SharedAxisZ
          fromText={Q1}
          toText={Q2}
          fontSize={52}
          fontWeight={600}
          color={INK}
        />
      </Series.Sequence>
      <Series.Sequence durationInFrames={48} layout="none">
        <PayoffScene />
      </Series.Sequence>
    </Series>
  </AbsoluteFill>
);

// ===========================================================================
// Scene 2 — Pain. Four short lines land solo, the last one emphasized.
// ===========================================================================
const PAIN_LINES = [
  "You install the library.",
  "You fight its styles.",
  "You override its CSS.",
];

const PainScene: React.FC = () => (
  <AbsoluteFill
    style={{
      alignItems: "center",
      justifyContent: "center",
      flexDirection: "column",
      gap: 14,
    }}
  >
    {PAIN_LINES.map((line, i) => (
      <Reveal key={line} delay={4 + i * 14} distance={14} blur={9}>
        <span
          style={{
            fontFamily: SANS,
            fontWeight: 500,
            fontSize: 38,
            color: MUTED,
          }}
        >
          {line}
        </span>
      </Reveal>
    ))}
    <Reveal delay={4 + PAIN_LINES.length * 14 + 6} distance={18} blur={12}>
      <span
        style={{
          fontFamily: SANS,
          fontWeight: 600,
          fontSize: 44,
          color: INK,
        }}
      >
        And it&apos;s still not yours.
      </span>
    </Reveal>
  </AbsoluteFill>
);

// ===========================================================================
// Scene 3 — Product intro. Introducing → shadcn/ui → Open Source. Open Code.
// ===========================================================================
const IntroScene: React.FC = () => (
  <AbsoluteFill
    style={{
      alignItems: "center",
      justifyContent: "center",
      flexDirection: "column",
      gap: 18,
    }}
  >
    <Reveal delay={2} distance={12} blur={8} duration={16}>
      <span
        style={{
          fontFamily: SANS,
          fontWeight: 500,
          fontSize: 24,
          letterSpacing: "0.01em",
          color: MUTED,
        }}
      >
        Introducing
      </span>
    </Reveal>
    <Reveal delay={10} distance={24} blur={16} duration={22}>
      <h1
        style={{
          margin: 0,
          fontFamily: MONO,
          fontWeight: 600,
          fontSize: 96,
          letterSpacing: "-0.04em",
          color: INK,
        }}
      >
        shadcn/ui
      </h1>
    </Reveal>
    <Reveal delay={26} distance={16} blur={10}>
      <span
        style={{
          fontFamily: SANS,
          fontWeight: 500,
          fontSize: 30,
          color: FAINT,
        }}
      >
        Open Source.{" "}
        <span style={{ color: INK, fontWeight: 600 }}>Open Code.</span>
      </span>
    </Reveal>
  </AbsoluteFill>
);

// ===========================================================================
// Scene 4 — Install. A real `add` lands the code in the project.
// ===========================================================================
const InstallScene: React.FC = () => (
  <AbsoluteFill style={{ alignItems: "center", justifyContent: "center" }}>
    <div style={{ width: 860 }}>
      <TerminalSimulator
        title="~/my-app"
        fontSize={20}
        charsPerFrame={2}
        chunkSize={2}
        lines={[
          { text: "npx shadcn@latest add button", type: "command", delay: 0 },
          { text: "✓ Checking registry...", type: "log", delay: 12, pause: 10 },
          {
            text: "✓ Created components/ui/button.tsx",
            type: "success",
            delay: 8,
          },
          { text: "It's in your project now.", type: "log", delay: 12 },
        ]}
      />
    </div>
  </AbsoluteFill>
);

// ===========================================================================
// Scene 5 — It's yours now. The button file opens; it's plain React + Tailwind.
// ===========================================================================
const BUTTON_CODE = `import { cva } from "class-variance-authority";

const buttonVariants = cva(
  "inline-flex items-center justify-center rounded-md",
  {
    variants: {
      variant: {
        default: "bg-primary text-primary-foreground",
        outline: "border border-input bg-background",
        ghost: "hover:bg-accent",
      },
      size: {
        default: "h-9 px-4 py-2",
        sm: "h-8 px-3",
        lg: "h-10 px-6",
      },
    },
  },
);`;

const CodeScene: React.FC = () => (
  <AbsoluteFill
    style={{
      alignItems: "center",
      justifyContent: "center",
      flexDirection: "column",
      gap: 26,
    }}
  >
    <Reveal delay={2} distance={16} blur={10}>
      <h2
        style={{
          margin: 0,
          fontFamily: SANS,
          fontWeight: 600,
          fontSize: 38,

Showing the first 400 of 920 lines. View the full file on GitHub.