R RenderComp
remotion lower-thirds text-animation react motion-graphics

Lower Thirds and Text Animations in Remotion — Complete Guide

By RenderComp Team Editorial policy

This animation is a template included in the RenderComp catalog, rendered from its React component. Browse the catalog

Lower Thirds and Text Animations in Remotion

Lower thirds, kinetic text reveals, and typewriter effects are among the most requested motion graphics elements in video production. In traditional NLEs you build these by hand on a timeline. In Remotion, you write them once as React components and reuse them infinitely, passing different names, titles, and colours as props.

This guide covers three techniques in depth: animated lower thirds, text reveal animations, and typewriter effects. Each section includes working code and notes on where a pre-built template saves you significant time.


What Is a Lower Third?

A lower third is the text overlay that appears in the lower portion of a video frame — typically a speaker’s name and title. In broadcast television, lower thirds are produced by dedicated graphics systems. In Remotion, a lower third is a React component that reads useCurrentFrame().


Building an Animated Lower Third

A well-crafted lower third moves through three phases:

  1. The element slides or fades into view.
  2. The text holds fully visible for the speaker to read.
  3. The element exits before the next cut.

Here is a minimal implementation using interpolate and spring:

import {
  interpolate,
  spring,
  useCurrentFrame,
  useVideoConfig,
} from "remotion";

interface LowerThirdProps {
  name: string;
  title: string;
  accentColor?: string;
}

export const LowerThird: React.FC<LowerThirdProps> = ({
  name,
  title,
  accentColor = "#e63946",
}) => {
  const frame = useCurrentFrame();
  const { fps } = useVideoConfig();

  // Slide up on enter
  const translateY = spring({
    fps,
    frame,
    config: { damping: 14, stiffness: 120 },
    from: 40,
    to: 0,
  });

  // Fade in
  const opacity = interpolate(frame, [0, 12], [0, 1], {
    extrapolateRight: "clamp",
  });

  // Bar width reveal
  const barWidth = interpolate(frame, [0, 20], [0, 6], {
    extrapolateRight: "clamp",
  });

  return (
    <div
      style={{
        position: "absolute",
        bottom: 120,
        left: 80,
        transform: `translateY(${translateY}px)`,
        opacity,
        display: "flex",
        alignItems: "center",
        gap: 16,
        fontFamily: "-apple-system, Segoe UI, Roboto, sans-serif",
      }}
    >
      {/* Colour accent bar */}
      <div
        style={{
          width: barWidth,
          height: 56,
          background: accentColor,
          borderRadius: 2,
        }}
      />
      <div>
        <div
          style={{
            color: "#ffffff",
            fontSize: 28,
            fontWeight: 700,
            letterSpacing: 0.5,
          }}
        >
          {name}
        </div>
        <div
          style={{
            color: "rgba(255,255,255,0.75)",
            fontSize: 18,
            fontWeight: 400,
          }}
        >
          {title}
        </div>
      </div>
    </div>
  );
};

Composing the Lower Third into a Scene

Wrap the component in a <Sequence> to control when it appears:

import { Sequence } from "remotion";
import { LowerThird } from "./LowerThird";

export const InterviewScene: React.FC = () => (
  <>
    {/* Lower third: visible from frame 30 to frame 150 */}
    <Sequence from={30} durationInFrames={120}>
      <LowerThird name="Sarah Chen" title="Head of Product, Acme Inc." />
    </Sequence>
  </>
);

Text Reveal Animations

Text reveals animate individual words or characters into view. Two popular styles are the wipe reveal (text slides in from behind a mask) and the fade-up reveal (each word staggers upward).

Word-by-Word Fade-Up

import { interpolate, useCurrentFrame } from "remotion";

interface WordRevealProps {
  text: string;
  startFrame?: number;
  staggerFrames?: number;
}

export const WordReveal: React.FC<WordRevealProps> = ({
  text,
  startFrame = 0,
  staggerFrames = 6,
}) => {
  const frame = useCurrentFrame();
  const words = text.split(" ");

  return (
    <div
      style={{
        display: "flex",
        flexWrap: "wrap",
        gap: 12,
        fontFamily: "-apple-system, Segoe UI, Roboto, sans-serif",
        fontSize: 64,
        fontWeight: 700,
        color: "#fff",
      }}
    >
      {words.map((word, i) => {
        const wordFrame = startFrame + i * staggerFrames;
        const progress = interpolate(frame, [wordFrame, wordFrame + 15], [0, 1], {
          extrapolateLeft: "clamp",
          extrapolateRight: "clamp",
        });
        return (
          <span
            key={i}
            style={{
              opacity: progress,
              transform: `translateY(${(1 - progress) * 24}px)`,
              display: "inline-block",
            }}
          >
            {word}
          </span>
        );
      })}
    </div>
  );
};

Typewriter Effect

The typewriter effect reveals characters one by one, mimicking the feel of live typing. It works by slicing the string at a frame-derived index:

import { interpolate, useCurrentFrame } from "remotion";

interface TypewriterProps {
  text: string;
  durationInFrames?: number;
  cursorVisible?: boolean;
}

export const Typewriter: React.FC<TypewriterProps> = ({
  text,
  durationInFrames = 90,
  cursorVisible = true,
}) => {
  const frame = useCurrentFrame();

  const characterIndex = Math.floor(
    interpolate(frame, [0, durationInFrames], [0, text.length], {
      extrapolateRight: "clamp",
    })
  );

  const showCursor = cursorVisible && frame % 30 < 15;

  return (
    <div
      style={{
        fontFamily: '"Courier New", Courier, monospace',
        fontSize: 48,
        color: "#e2e8f0",
        whiteSpace: "pre",
      }}
    >
      {text.slice(0, characterIndex)}
      {showCursor && <span style={{ opacity: 1 }}>|</span>}
    </div>
  );
};

Performance Notes

Text animations are inexpensive to render because they rely on pure CSS transforms, with no image or video decoding involved. Even a complex layered lower third with spring animations adds minimal overhead to your render pipeline.


When to Use Pre-Built Templates

The code above gives you the building blocks. In a real production scenario, though, where you have a dozen lower third variants, different brand colours, multiple aspect ratios, and a firm deadline, building everything from scratch compounds quickly.

RenderComp includes a curated set of lower third and text animation templates among its 1,000+ Remotion components. Each one ships with editable props for colour, font size, timing, and position. For agencies and freelancers who regularly produce interview-style or branded content, starting from a battle-tested template is significantly faster than writing spring physics from scratch for every project.


Conclusion

Lower thirds and text animations in Remotion follow the same pattern as every other motion graphics element: frame number in, visual state out. Once you internalise interpolate and spring, you can replicate virtually any text animation from professional broadcast productions and export it as reusable, version-controlled React code. For teams shipping these elements at scale, browsing a template library like RenderComp first is worth the time investment.

Frequently asked questions

How do I make a lower third disappear before the video ends?

Set `durationInFrames` on the wrapping `<Sequence>`. When the sequence ends, the component unmounts. You can also add a fade-out by reading `useCurrentFrame()` relative to the end of the sequence.

Can I animate text along a path in Remotion?

Yes. Use an SVG `<textPath>` element inside your React component. Drive the `startOffset` attribute with `interpolate()` to animate text along a curve.

How do I match the font in my lower third to my brand?

In Remotion you can [load a local font file](/blog/remotion-custom-fonts-loading-guide/) using `@remotion/fonts` or by importing it as a static asset. Avoid loading fonts from external CDNs — load them locally for reproducibility and offline rendering.

What is the best way to animate Chinese, Japanese, or Korean text?

Use a system font stack that includes CJK fonts (e.g., `"Yu Gothic", "Hiragino Kaku Gothic ProN", "Noto Sans JP", sans-serif`). Character-level animations work fine — split the string by character rather than by space since CJK scripts do not use spaces as word boundaries.

Can I use variable fonts in Remotion for animated font weight?

Yes. Pass a CSS `font-variation-settings` style prop and drive the weight axis value with `interpolate()`.

How do I export just the lower third with a transparent background?

Use `npx remotion render --codec=prores-4444` or `--codec=vp8`/`vp9` with `--transparent`. This outputs an [alpha-channel video](/blog/remotion-transparent-background-green-screen-export/) you can composite in any NLE.

Is there a way to preview the lower third against a real video background?

Yes. Use the `<Video>` or `<OffthreadVideo>` component in Remotion to place a background clip in your composition, then layer the lower third on top. Preview in Remotion Studio.

Now available

Get 1,000+ Remotion Templates

Pay once — no subscription. Lifetime updates. TypeScript-first.

View pricing →