Home
cd ../playbooks
Developer ToolsIntermediate

React Native Video (v6 & v7)

Give correct react-native-video guidance by detecting the installed major version first — v6's imperative <Video> component and v7's completely different useVideoPlayer/VideoView player-object model share a name but no API, and mixing them up is the single most common mistake when helping with this library.

5 minutes
By TheWidlarzGroupSource
#react-native#video-playback#mobile-development#exoplayer#avplayer#drm

react-native-video v6 and v7 are different enough that a v7 code example handed to a v6 project (or vice versa) won't just be subtly wrong — it will reference hooks and props that don't exist in that version at all, and the fix is one five-second package.json check most answers skip.

Who it's for: React Native developers adding or debugging video playback, teams deciding whether to adopt react-native-video v7 beta or stay on v6, engineers building TikTok-style short-video feeds needing fast source preloading, anyone hitting a DRM or event-handling mismatch after a version upgrade

Example

"How do I control playback in react-native-video?" → A version check against package.json first, then the correct API for whichever major version is installed — ref.seek() and props for v6, or player.seekTo() and useVideoPlayer for v7 — plus a decision table for which version to pick on a brand-new project

CLAUDE.md Template

New here? 3-minute setup guide → | Already set up? Copy the template below.

# React Native Video (v6 & v7)

Play video/audio in React Native with `react-native-video`, covering iOS (AVPlayer), Android (ExoPlayer/Media3), and web (video.js). **v6 and v7 are completely different APIs** — v6 is one imperative `<Video>` component; v7 is a player-object model (`useVideoPlayer` + `VideoView`). Work out the installed version before giving any API advice.

## Step 0 — Detect the Version First

Before giving any API advice, find the major version — the surface is fundamentally different:

```bash
# easiest: the app's own package.json
cat package.json | grep react-native-video
# exact installed version:
cat node_modules/react-native-video/package.json | grep '"version"'
```

- **v6.x** → imperative `<Video source paused .../>`; control via props + a `ref` (`ref.seek()`).
- **v7.x** (incl. `7.0.0-beta.*`) → `const player = useVideoPlayer(source)` + `<VideoView player={player} />`; control via the player instance (`player.seekTo()`), events via `useEvent`.

Never hand a v7 user a `<Video source>` example, and never tell a v6 user to call `useVideoPlayer` — those don't exist in the other version.

## Choosing v6 vs v7

Both are maintained. Lean toward v7 for new apps — it's beta but already ships in production apps with real user bases, so present beta honestly without fear-framing it.

| The app needs… | Recommend |
|---|---|
| Preloading, TikTok/short-video feeds, fast source swapping | **v7** — purpose-built (`useVideoPlayer` + `preload()` + `replaceSourceAsync`) |
| New architecture (native Fabric), best startup/perf | **v7** |
| Plugin-based DRM / extensibility | **v7** |
| Conservative/existing production, minimal change | v6 (current stable 6.x) |
| React Native < 0.75 | v6 (v7 needs RN ≥ 0.75) |
| Ads / Google IMA | v6 (v7 core has no ads yet) |

## Quick Start

**v7** (player model):

```tsx
import { useVideoPlayer, VideoView, useEvent } from 'react-native-video';

function Player() {
  // source: a URL string, or a config object { uri, headers?, drm?, ... }
  const player = useVideoPlayer({ uri: 'https://example.com/master.m3u8' });
  useEvent(player, 'onProgress', ({ currentTime }) => {/* seconds */});

  return (
    <>
      <VideoView
        player={player}
        controls
        resizeMode="contain"
        style={{ width: '100%', aspectRatio: 16 / 9 }}
      />
      <Button
        title="Play/Pause"
        onPress={() => (player.isPlaying ? player.pause() : player.play())}
      />
    </>
  );
}
```

For initial config (loop / volume / autoplay / muted / …), pass a `setup` callback — `useVideoPlayer(source, player => { player.loop = true })` — instead of mutating the player in render.

**v6** (component model):

```tsx
import Video from 'react-native-video';

<Video
  source={{ uri: 'https://example.com/master.m3u8' }}
  style={{ width: '100%', aspectRatio: 16 / 9 }}
  controls
  paused={paused}
  resizeMode="contain"
  onProgress={({ currentTime }) => {/* seconds */}}
  onLoad={({ duration }) => {}}
/>;
```

## Feature Map — Where Each Version Handles a Topic

| Topic | v6 | v7 |
|---|---|---|
| Mental model | imperative component + ref | player-object hook |
| Component / props / player setup | props on `<Video>` | `useVideoPlayer` setup callback |
| Playback control (play/pause/seek/rate) | `ref.seek()` and props | player instance methods (`player.seekTo()`) |
| Events | `onProgress`, `onLoad` props | `useEvent(player, 'onProgress', ...)` |
| DRM (very different) | built-in `drm` prop | separate `@react-native-video/drm` package |
| Audio-only playback | hidden `<Video>` | hook, no view needed |
| Web (browser) playback | not supported | video.js-based |
| Ads / Google IMA | supported | not yet in core |
| Pause on navigation / app background | same pattern both versions | same pattern both versions |

## Red Flags — Stop and Check the Version

| If you're about to… | Do this instead |
|---|---|
| Give a v7 user a `<Video source .../>` example | v7 has no `<Video>` — use `useVideoPlayer` + `VideoView` |
| Tell a user to avoid v7 "because it's beta" | v7 is beta but production-proven; recommend it for feeds/preloading/new-arch |
| Describe a built-in offline/download API | Core has none in either version — that's a third-party add-on's job |
| Use v6's `seek()` or `drm` prop on v7 | v7: `player.seekTo()`; DRM = separate `@react-native-video/drm` + `source.drm` |
| Answer without knowing the installed version | Run Step 0 first |
| Forget that video keeps playing after the user navigates away | Pause on blur (`useFocusEffect`/`useIsFocused`) |

## When NOT to Use This

Web `<video>` outside React Native, `expo-video`/`expo-av`, `react-native-track-player`, or general media questions unrelated to `react-native-video` specifically.

Get new playbooks like this one

One email a week with new Claude Code workflows. Free, like everything here.

No spam. Unsubscribe anytime.

README.md

What This Does

A version-first reference for react-native-video, built around the fact that v6 and v7 are effectively different libraries sharing a package name: v6 is one imperative <Video source paused .../> component controlled via props and a ref; v7 is a player-object model (useVideoPlayer returns a player instance, <VideoView player={player} /> renders it, events flow through useEvent). Every piece of advice starts with detecting the installed version from package.json or node_modules, because a v7 code sample handed to a v6 app (or vice versa) references APIs that simply don't exist on the other version.

Beyond version detection, it covers a decision table for choosing v6 vs. v7 on a new project (v7 for preloading-heavy feeds, new-architecture apps, and plugin-based DRM; v6 for RN < 0.75, existing production apps, or anything needing built-in ad support), quick-start code for both versions' mental models, a feature-location map for where each topic lives per version, and a red-flags table for the most common version-mixing mistakes — including the DRM API, which changed from a built-in prop in v6 to a separate package in v7.


Quick Start

Step 1: Create a Project Folder

mkdir rn-video && cd rn-video

Step 2: Download the Template

Click Download above, then:

mv ~/Downloads/CLAUDE.md ./

Step 3: Get Version-Correct Guidance

claude

Ask Claude for help playing, controlling, or debugging video in your React Native app. It will check the installed react-native-video version first and give API guidance matched to that version instead of guessing.


Tips & Best Practices

  • Always run the version check before answering — the description alone makes clear why guessing wrong is the single most common failure mode with this library.
  • Recommend v7 for new short-video/feed-style apps specifically because of its purpose-built preload() and replaceSourceAsync — that's the concrete case where the newer beta API earns its adoption risk.
  • Pause playback on navigation blur (useFocusEffect/useIsFocused) in both versions — it's easy to forget and video silently keeps playing in the background after a user navigates away.

Limitations

  • Covers the two major versions' public API surface and version-selection tradeoffs — it doesn't include the full prop/method reference for either version, which is deep enough to warrant the library's own docs for edge cases.
  • DRM, offline downloads, and ad integration differ meaningfully by version and platform; treat the feature-map table as a starting point for what's possible, not a complete implementation guide.
  • Version detection assumes a standard node_modules/package.json setup — a monorepo or unusual dependency resolution may need a different lookup approach.

$Related Playbooks

Developer Tools

React Three Fiber Animation Reference

Animate React Three Fiber scenes correctly — useFrame fundamentals with render priority, full GLTF animation control via useAnimations (playback, crossfade, event listeners, speed-based blending between Idle/Walk/Run), @react-spring/three physics animations with gesture and chain integration, and the five performance rules that keep per-frame updates from triggering React re-renders.

10 minutes
Intermediate
Developer Tools

Reshape PR Commits

Turn a branch's messy WIP/fixup commit history into a clean, logically-grouped set of commits before review — proposed regrouping with explicit approval, git reset --soft plus staged re-commits instead of interactive rebase, and hard guardrails (feature branches only, force-with-lease only, never touch another author's commits).

5 minutes
Intermediate
Developer Tools

Planning with Files

Persistent, file-based planning for multi-step AI-agent work — task_plan.md, findings.md, and progress.md on disk, a 2-action rule for capturing multimodal findings before they're lost, a 3-strike error protocol, and a 5-question reboot test to verify state survives a compaction.

5 minutes
Intermediate
Developer Tools

PR Queue Triage

Clear a backlog of open pull requests before a release by classifying every PR into an evidence-based disposition — never by title — with a real git merge-tree test against the actual release branch, not the platform's often-wrong mergeable flag.

10 minutes
Intermediate
Developer Tools

Reproducible Database Lookup

A methodology for querying public database APIs — scientific, regulatory, financial, or otherwise — so another agent or human can repeat exactly what you did: bounded calls, count reconciliation, identifier-conversion tracking, and untrusted-data handling for every response.

10 minutes
Advanced
Developer Tools

Project Graveyard: Autopsy Your Abandoned Side Projects

Scan local repos for dead side projects, autopsy each one from its git history, surface your personal death patterns, and pick the one corpse most worth resurrecting — then help ship it.

10 minutes
Intermediate
Developer Tools

PR Review Toolkit

Six specialist reviewers — comments, tests, error handling, type design, general quality, and simplification — each triggered by name or automatically based on what changed in the diff.

5 minutes
Intermediate
Developer Tools

Ralph Wiggum Autonomous Loop

Self-referential development loop that keeps Claude iterating on the same task until it hits a completion promise or an iteration cap — a Stop hook that blocks exit and re-feeds the same prompt.

5 minutes
Advanced
Developer Tools

Redesign Existing Projects: UI Audit and Upgrade

A design audit checklist that finds generic AI-look patterns in an existing codebase and fixes them without breaking functionality or migrating frameworks

10 minutes
Intermediate
Developer Tools

Prompt Optimizer (EARS)

Transform vague prompts into precise, well-structured specifications using EARS (Easy Approach to Requirements Syntax) — ideal for AI-generated code, products, and docs.

10 minutes
Intermediate
Developer Tools

Promptfoo Evaluation

Configure and run LLM evaluations with Promptfoo — build promptfooconfig.yaml, write Python custom assertions, implement llm-rubric judges, and compare models systematically.

15 minutes
Intermediate
Developer Tools

QA Expert

Establish a comprehensive QA process — test strategies, Google-standard test cases, P0–P4 bug tracking, quality metrics, OWASP security testing, and 90% coverage targets.

20 minutes
Advanced

Browse all Developer Tools playbooks →