FRAMEWORKS
React Router video
Complete video infrastructure for a React Router or Remix app. Install the packages and you get uploads, adaptive playback, live streams, DRM, analytics and AI features, without building your own encoding, storage and delivery.
Free plan: 10 videos, 100K streaming minutes, 300 minutes of subtitles and moderation. No credit card.
TRUSTED BY PRODUCT TEAMS SHIPPING VIDEO AT SCALE






What you get
What you get from FastPix for React Router video
Four things you don't have to build or run yourself.
One video API
Upload, storage, delivery, the player, analytics and AI all come from the same API. No Vite plugin, nothing added to your build.
Built-in encoding
FastPix turns each upload into several quality levels and packages them for streaming. No FFmpeg, no queue workers.
Analytics already on
The player sends view data on its own. Add a title and a viewer ID and you can see who watched what.
Secure video streaming and DRM
Sign a token on your server and pass it to the player. Widevine, PlayReady and FairPlay are all supported.
Functionality
Every React Router video capability, from upload to AI
Pick a group, then a capability. Each one tells you whether the code goes in a resource route, a loader, or the route component itself.
Video upload API
A resource route, a route module with no default export, creates the signed URL from its action. The browser then uploads straight to FastPix in chunks, which is also the answer to the large-file question that has sat unanswered in the Remix repo since 2024.
React Router video player
The player is a web component. It registers against customElements, a browser-only API, and React Router server-renders your routes, so import it inside useEffect. There is no "use client" directive here to reach for.
Video engagement analytics
The player sends view data on its own. There is no second SDK and no loader to write. Every other capability here needs either a route or an attribute; this one needs neither.
Server-side AI processing
Every AI feature runs on the video after it is uploaded. You ask for it from a .server module and the result arrives on a webhook. Because none of it is component code, it survived the Remix to React Router migration unchanged, which is not true of most of your routing.
Setup
Install and configure the React Router video packages
Install the React Router video packages
The uploader and the player run in the browser. The Node SDK runs in your resource routes, where it creates upload URLs, signs playback tokens and asks for AI features.
Configure the React Router video packages
There's no API key. You get two values, an Access Token ID and a Secret Key, and they work as a username and password. The .server suffix is what keeps them out of the browser build.
Get your access tokenA React Router project with all of it wired
The resource route, its registration in routes.ts, the upload page, the webhook and the player route, in one project you can clone and run. Everything in one place instead of four doc pages.
Behind the scenes
What happens after your React Router app uploads a file
Here's what happens between the file leaving the browser and the video reaching a viewer. None of it is code you write, and none of it runs in your app.
Your React Router app only touches the two ends. A server call hands over a signed URL and the player takes the playback ID. In between, a video.media.ready webhook tells your server the video is ready.
FAQ
React Router video questions, answered
How do I upload a large video file in React Router v7?
Create a signed upload URL in a resource route action and let the browser upload to it directly. The file never passes through your app, so request size limits and timeouts do not apply at any file size.
Is this for Remix or React Router?
Both. Remix v2 was upstreamed into React Router and is in maintenance mode, so create-remix now points at create-react-router. On an existing Remix codebase the code is identical apart from importing from @remix-run/* and registering routes by filename.
Why does my new upload route 404?
Framework Mode registers routes explicitly rather than discovering them by filename, so creating app/routes/api.upload-url.ts puts a file on disk and nothing else. Add it to app/routes.ts and restart the dev server, since the config is read at startup.
How do I render the video player from a React Router route?
Fetch the playback ID in a loader and pass it to a player component. Import the player inside useEffect, because React Router server-renders your routes and the player registers against customElements. Safari plays HLS natively and other browsers do not, which a player component handles for you.
Go deeper
More on React Router video uploads and playback
Uploading large video files efficiently using chunking
The protocol detail behind chunk sizing and retry behaviour.
Read moreHow to allow users to upload large videos with pause and resume
The behaviour the uploader gives you, explained.
Read moreGuide to video playback in JavaScript
What the browser is doing underneath any player you pick.
Read moreABR vs MBR: adaptive and multi-bitrate streaming
Why one upload becomes several quality levels.
Read moreGuide to lazy loading HTML videos for your website
Stops a page of video elements blocking your first paint.
Read moreCreating a fully customizable video player interface
Restyling controls without rebuilding the player.
Read moreHow to protect video content with signed URLs
The access model behind private playback.
Read moreWebhooks for video: live events and UGC pipelines
The events that matter, and verifying a signature properly.
Read moreHow to set up monitoring for video player errors
Catching playback failures before support tickets do.
Read more