Skip to content
Native Animation
Talking Companion Introduction animation preview
Onboarding

Talking Companion Introduction

React Native Animated Character Introduction

A friendly character introduces itself line by line, changes expression while speaking, and settles into a ready-to-chat screen.

$9 for this animation

Checkout opens soon. Leave your email and we will tell you the moment you can buy it.

One email when checkout opens. No spam.

Add to your project

Copy the component and its assets into your app with the Native Animation CLI, or paste the agent prompt into Claude Code, Codex or Cursor once the MCP server is connected.

npx nativeanimation add companion-intro

About this animation

A React Native animated character introduction gives a conversation screen a face and a short opening script. This component reveals lines character by character, changes facial expressions, and moves the companion into a ready-to-chat layout with a composer. Facial features are built from Views, Reanimated handles expression crossfades and layout transitions, and Expo Linear Gradient provides the background. Typing uses Unicode-aware character splitting so emoji remain intact, with timers cleared when playback changes or the component unmounts. Use it for an assistant introduction, a journaling welcome, a coaching interface, or conversational onboarding. Configure script lines and expressions, typing speed, colors, fonts, and screen copy. Connect face, script-end, and send callbacks, disable automatic start, or replay and skip the introduction through its ref.

When to use it

  • Introduce a conversational assistant.
  • Welcome users to a journaling screen.
  • Give coaching onboarding a character.
  • Transition a script into a chat composer.

A friendly character introduces itself line by line, changes expression while speaking, and settles into a ready-to-chat screen.

How it works

  1. The layout measures its own container with onLayout; the face, text, controls, and chat composer all scale from that width and height.
  2. A small JavaScript interval reveals Unicode characters with Array.from, so emoji stay intact. A second interval crossfades the smile and an open mouth only while text is being typed.
  3. Four expression layers share the same View-built facial geometry. Reanimated fades and scales those layers over 220 ms whenever the script changes expression.
  4. Reanimated shared values drive the face entrance, its move into the chat layout, the staggered copy, and two slow background blobs without rerendering React on every frame.
  5. The forwarded ref owns replay and skip behavior, while every timer and interval is tracked and cleared when a run is replaced or the component unmounts.

Install

npx expo install expo-linear-gradient react-native-reanimated

Usage

import CompanionIntro from './CompanionIntro';

export function WelcomeScreen() {
  return <CompanionIntro />;
}

Customize the character, script, timing, and callbacks:

import { useRef } from 'react';
import CompanionIntro, {
  type CompanionIntroRef,
} from './CompanionIntro';

export function WelcomeScreen() {
  const introRef = useRef<CompanionIntroRef>(null);

  return (
    <CompanionIntro
      ref={introRef}
      script={[
        { text: 'Good morning!', expression: 'sparkle', holdMs: 700 },
        { text: 'Ready when you are.', expression: 'happy' },
      ]}
      typingSpeed={16}
      title="Start a conversation"
      faceColor="#C8EBD9"
      accentColor="#426FF5"
      onFacePress={() => showBreathingExercise()}
      onSend={(message) => sendMessage(message)}
    />
  );
}

The forwarded ref exposes replay() and skip().

Props

PropTypeDefaultDescription
scriptCompanionLine[]Pip's three-line introductionLines and expressions used during the introduction.
typingSpeednumber14Characters revealed per second.
titlestring'Talk with Pip'Chat screen title.
subtitlestring"What's on your mind today?"Chat screen subtitle.
hintstring'Tap me to breathe'Chat hint and accessible face label.
privacyNotestring'Your conversations stay private'Message above the composer.
inputPlaceholderstring'Share your thoughts…'Chat input placeholder.
faceColorstring'#BFE8D4'Character fill color.
featureColorstring'#22313A'Eye and mouth color.
accentColorstring'#3E7BFA'Microphone button color.
backgroundColors[string, string, string]['#EAF4FF', '#FFE9DC', '#F3E9FF']Diagonal background gradient colors.
fontFamilystringSystem fontFont family for body text and the input.
titleFontFamilystringSystem fontFont family for the chat title.
onScriptEnd() => void—Called after the chat screen appears.
onFacePress() => void—Called when the character is pressed.
onSend(text: string) => void—Called when non-empty input is submitted.
autoStartbooleantrueStarts the entrance and script on mount.
styleStyleProp<ViewStyle>—Outer-container style.
testIDstring—Test identifier for the outer container.

Compatibility

  • Expo SDK 57
  • React Native 0.86
  • Reanimated 4.5
  • iOS: supported, not yet verified on a device
  • Android: supported, not yet verified on a device
  • Web: supported, not yet verified in a browser
  • Works in Expo Go because its native dependencies are included in the SDK

Accessibility

The face is exposed as a labeled button, and each changing phrase uses a polite live region. The sound, send, and voice controls have explicit button labels. With reduced motion enabled, lines appear whole instead of typing, ambient breathing and press bounces stop, and transitions use short fades.

FAQ

Can I change the character script and expressions?
Yes. Supply CompanionLine entries with text, expression, and optional holdMs. typingSpeed controls characters per second, and the ref exposes replay and skip.
Does the introduction connect to an AI service automatically?
No. onSend receives non-empty submitted text, and onFacePress and onScriptEnd expose other actions. You connect those callbacks to your own application services.
How does the character introduction handle Reduce Motion?
Lines appear whole instead of typing, ambient breathing and press bounces stop, and transitions use short fades. The changing phrase remains a polite live-region update.