Skip to main content

Files with absolute paths

Why is it not possible to use absolute paths to require assets?

This does not work
tsx
import { Img } from "remotion";
const MyComp: React.FC = () => {
return <Img src="C://Users/Joe/Documents/image.png" />;
};
This does not work
tsx
import { Img } from "remotion";
const MyComp: React.FC = () => {
return <Img src="C://Users/Joe/Documents/image.png" />;
};

Browsers don't have access to your filesystem

Remotion runs in a browser during preview and in a headless browser during rendering.
By default, browsers don't have access to your filesystem. To read any files, they need to be served via an HTTP server.

Only the public folder is supported by web frameworks

To allow importing assets, frameworks for making web apps such as Next.js, Vite, Remix or Create React App expose the public folder.

We follow this convention in Remotion to allow for seamless code reuse across frameworks - assets that show up in the Remotion Studio also show up in the Remotion Player.

Allowing assets to be imported from any folder would break this convention, and they could not be displayed in the Remotion Player.

The public folder convention

Remotion implements a convention where the public folder in your project is exposed via HTTP server and can be accessed on the same domain as your development server.

In Next.js, Remix, and Vite, if you have a file public/image.png, you can access it via "http://localhost:3000/image.png", or just "/image.png"

In Remotion you need to wrap the path in staticFile(), so it would be staticFile("image.png").
This ensures that assets are loaded correctly if the webpage is not served on the root path /, which is the case on Remotion Lambda and Remotion Cloud Run.

By using staticFile(), you can import assets from the public folder, and it will automatically also work in Remotion Studio as well as Remix, Vite, Next.js and Create React App in case you are using the Remotion Player.

Absolute paths are not portable

Before rendering a video, code is bundled to reduce the size of the assets that need to be sent to the browser. Your project with it's node_modules folder would be hundreds of megabytes large, but by bundling, the size is reduced drastically.

A bundle can also be uploaded and hosted on the internet, which is what Remotion Lambda and Remotion Cloud Run do and what is also possible using regular rendering.

Because the goal is to reduce the size of the bundle, only the public gets copied into the bundle.
Files with an absolute path would not be copied into the bundle, and therefore not be available when rendering on another device.

Serving the filesystem via HTTP is dangerous

While Remotion could theoretically serve the full filesystem via HTTP so it is accessible via browser, this would be a security risk.
Any application or website could then read any file on your computer by making a HTTP request.

What to do instead

Use the public folder

Preferrably, copy files into the public folder and staticFile() to import assets.

Workaround: Use npx serve

Sometimes, it is preferrable to not copy all assets into your Remotion project because they are too large.

In this case, you can use npx serve to serve a folder on your computer via HTTP.

bash
npx serve --cors C://Users/Joe/Documents
bash
npx serve --cors C://Users/Joe/Documents

You will get a URL that you can use to access the folder via HTTP.
Pass URLs of assets to <Img>, <Video>, <OffthreadVideo>, <Audio>, <Gif> tags to use them in Remotion.

If you need to spawn a server programmatically, use serve-handler.

See also