How to Use Static Files in Remotion Compositions: The Complete Guide
Place assets in a public/ folder and resolve them using the staticFile() function, which validates paths, encodes unsafe characters, and returns a runtime URL that works in both the Remotion Studio and deployed players.
Managing static assets is essential when building programmatic video with React. In the remotion-dev/remotion repository, the framework provides a dedicated API to handle images, fonts, audio, and other files through a public/ directory workflow. This guide explains how to use static files in Remotion compositions using the staticFile(), getStaticFiles(), and watchStaticFile() utilities.
Setting Up the Public Directory
Remotion expects static assets to live in a folder named public/ located at the same level as your package.json that contains the Remotion dependency. You can create subdirectories inside public/ to organize images, fonts, videos, or JSON data.
Place any static asset in this folder, then reference it by its path relative to the public/ directory without including the public/ prefix in your code.
Resolving Asset Paths with staticFile()
The staticFile() function is the primary API for converting a file path into a URL that the Remotion Player and Studio can serve at runtime. According to the source code in [packages/core/src/static-file.ts](https://github.com/remotion-dev/remotion/blob/main/packages/core/src/static-file.ts), this utility performs three critical tasks:
- Validation: It throws descriptive errors if you pass remote URLs (starting with
http://orhttps://), relative paths (starting with./or../), absolute system paths, or paths that already include thepublic/prefix. - Encoding: Since version 4.0, it automatically applies
encodeURIComponentto each path segment, ensuring that filenames with spaces or special characters work without manual encoding. - Base URL Prefixing: It prepends the correct static base URL that the Studio or Player serves at runtime, abstracting away deployment-specific paths like
/static-abc123/.
Basic Usage Example
import {Img, staticFile} from 'remotion';
export const MyComposition = () => {
// Resolves to "/static-<hash>/logo.png" at runtime
const logoUrl = staticFile('logo.png');
return (
<div style={{flexDirection: 'row', alignItems: 'center'}}>
<Img src={logoUrl} width={200} height={200} />
<p>My brand logo</p>
</div>
);
};
Loading Custom Fonts
You can also use staticFile() with the browser's FontFace API to load custom typefaces:
import {staticFile} from 'remotion';
const myFont = new FontFace(
'MyFont',
`url(${staticFile('fonts/MyFont.woff2')}) format('woff2')`,
);
await myFont.load();
document.fonts.add(myFont);
Enumerating Assets with getStaticFiles()
When you need to build dynamic galleries or iterate over available resources, the getStaticFiles() function returns metadata for every file in the public/ directory. As implemented in [packages/core/src/get-static-files.ts](https://github.com/remotion-dev/remotion/blob/main/packages/core/src/get-static-files.ts), it returns an array of objects containing:
src: The resolved URL pathname: The filenamesizeInBytes: File sizelastModified: Timestamp
This API only works in the browser or Studio environment, not during server-side rendering.
import {getStaticFiles, Img, staticFile} from 'remotion';
export const Gallery = () => {
const files = getStaticFiles().filter((f) => f.name.endsWith('.png'));
return (
<div style={{display: 'flex', flexWrap: 'wrap'}}>
{files.map((file) => (
<Img key={file.name} src={file.src} width={150} height={150} />
))}
</div>
);
};
Live Reloading with watchStaticFile()
During development in the Remotion Studio, you can monitor static files for changes using watchStaticFile(). This utility, found in [packages/core/src/watch-static-file.ts](https://github.com/remotion-dev/remotion/blob/main/packages/core/src/watch-static-file.ts), sets up a listener that triggers when a file is added, modified, or removed.
The function returns a cancel method to clean up the listener. Note that in Remotion v5, this functionality moved to the @remotion/studio package.
import {staticFile, watchStaticFile, Img} from 'remotion';
import {useEffect, useState} from 'react';
export const LiveImage = () => {
const [src, setSrc] = useState(() => staticFile('dynamic.png'));
useEffect(() => {
const {cancel} = watchStaticFile('dynamic.png', (newData) => {
if (newData) {
// Force reload by appending timestamp
setSrc(`${newData.src}?t=${Date.now()}`);
}
});
return cancel;
}, []);
return <Img src={src} width={400} height={300} />;
};
Summary
- Place all static assets in a
public/folder at the project root to make them available to Remotion compositions. - Use
staticFile()to resolve paths into runtime URLs, letting the function handle validation, encoding, and base-path prefixing automatically. - Enumerate available assets with
getStaticFiles()when building dynamic galleries or processing multiple files. - Enable live reloading during development with
watchStaticFile()to react to asset changes in real time. - Reference the source implementations in
packages/core/src/static-file.ts,get-static-files.ts, andwatch-static-file.tsfor advanced customization.
Frequently Asked Questions
What is the difference between staticFile() and a regular import?
A regular ES Module import bundles the asset into your JavaScript build, increasing bundle size and requiring rebuilds when the file changes. The staticFile() function keeps assets separate in the public/ folder, references them by URL at runtime, and allows instant updates without recompiling your Remotion code.
Can I use staticFile() with remote URLs or absolute paths?
No. The implementation in packages/core/src/static-file.ts explicitly throws errors for remote URLs (starting with http:// or https://), absolute system paths (starting with / on Unix or C:\ on Windows), and relative paths (starting with ./ or ../). You must pass a plain filename or path relative to the public/ folder without the public/ prefix.
How do I handle filenames with spaces or special characters?
Since Remotion v4.0, staticFile() automatically applies encodeURIComponent to each path segment. You should pass the filename exactly as it appears in your public/ folder (e.g., staticFile('my file.png')) without pre-encoding spaces or special characters. The function handles the encoding to ensure valid URLs.
Why does watchStaticFile() not work in my production render?
The watchStaticFile() utility relies on the Remotion Studio's development server to monitor file system changes. It is designed for the browser/Studio environment only and does not function during server-side rendering or production video renders. For production, ensure all assets exist in public/ before starting the render, or use getStaticFiles() to validate availability at runtime.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →