Webpack and Rspack
Remotion bundles your project before opening the Studio or rendering media. It supports Webpack and Rspack.
Bundler roadmap
Remotion used Webpack exclusively until experimental Rspack support was added in v4.0.426. Webpack remains the default bundler.
Rspack is intended to replace Webpack:
- Rspack will soon become the default for newly created projects.
- In a future major version of Remotion, Webpack support will be removed and Rspack will be the only bundler.
You can enable Rspack now to test your project before this transition.
Enable Rspackv4.0.426
Enable Rspack for CLI commands in remotion.config.ts:
remotion.config.tsimport {Config } from '@remotion/cli/config';Config .setRspack (true);
To enable it for one command, use the --rspack flag:
npx remotion studio --rspackThe flag is also available for other commands that bundle your project, such as render, still, and bundle.
When using the Node.js bundle() API, set rspack to true:
bundle.tsimport {bundle } from '@remotion/bundler'; awaitbundle ({entryPoint :require .resolve ('./src/index.ts'),rspack : true, });
The bundle() API and Cloud Run's deploySite() have the same rspack setting.
Override the bundler configuration
Remotion provides three config file APIs:
| API | When it runs |
|---|---|
Config.overrideBundlerConfig() | With either selected bundler. Runs first. |
Config.overrideWebpackConfig() | Only when Webpack is selected. Runs after the shared override. |
Config.overrideRspackConfig() | Only when Rspack is selected. Runs after the shared override. |
You can call each override API more than once. Overrides of the same type run in registration order.
Only use Config.overrideBundlerConfig() for changes that are compatible with both bundlers. Many loaders implement an API that works with both bundlers, but you should verify each loader individually.
Webpack and Rspack plugins are not interchangeable. Use the plugin implementation from the selected bundler in its bundler-specific override.
Remotion ships with its own Webpack configuration and Rspack configuration. Each override receives the previous configuration and returns the next one.
Webpack overrides in remotion.config.ts
In your remotion.config.ts file, you can call Config.overrideWebpackConfig() from @remotion/cli/config.
remotion.config.tsimport {Config } from '@remotion/cli/config';Config .overrideWebpackConfig ((currentConfiguration ) => { return { ...currentConfiguration ,module : { ...currentConfiguration .module ,rules : [ ...(currentConfiguration .module ?.rules ?? []), // Add more loaders here ], }, }; });
You may also mutate the configuration object. Return the same object after mutating it:
remotion.config.tsimport {Config } from '@remotion/cli/config';Config .overrideWebpackConfig ((config ) => {config .module ??= {};config .module .rules ??= [];config .module .rules .push ({test : /\.txt$/,type : 'asset/source', }); returnconfig ; });
Using the reducer pattern will help with type safety, give you auto-complete, ensure forwards-compatibility and keep it completely flexible - you can override just one property or pass in a completely new Webpack configuration.
Rspack overrides in remotion.config.tsv4.0.498
Use Config.overrideRspackConfig() when Rspack is enabled:
remotion.config.tsimport {Config } from '@remotion/cli/config';Config .overrideRspackConfig ((currentConfiguration ) => { return { ...currentConfiguration , // Rspack-specific configuration }; });
When using bundle()
The bundle() Node.js API does not read remotion.config.ts. Pass the overrides directly to bundle(). Put an override in a separate file to import it from both remotion.config.ts and your Node.js script.
Pass portable changes as bundlerOverride.
src/bundler-override.tsimport {BundlerOverrideFn } from '@remotion/bundler'; export constbundlerOverride :BundlerOverrideFn = (currentConfiguration ) => { return { ...currentConfiguration , // Your override here }; };
remotion.config.tsimport {Config } from '@remotion/cli/config'; import {bundlerOverride } from './src/bundler-override';Config .overrideBundlerConfig (bundlerOverride );
With bundle:
my-script.jsimport {bundle } from '@remotion/bundler'; import {bundlerOverride } from './src/bundler-override'; awaitbundle ({entryPoint :require .resolve ('./src/index.ts'),bundlerOverride , });
For bundler-specific changes, pass webpackOverride or rspackOverride instead.
Multiple overrides
If you have multiple overrides, you should curry them:
import {Config } from '@remotion/cli/config';
import {enableScss } from '@remotion/enable-scss';
import {enableTailwind } from '@remotion/tailwind-v4';
Config .overrideBundlerConfig ((c ) => enableScss (enableTailwind (c )));You can also call Config.overrideBundlerConfig() multiple times in the config file:
import {Config } from '@remotion/cli/config';
import {enableScss } from '@remotion/enable-scss';
import {enableTailwind } from '@remotion/tailwind-v4';
Config .overrideBundlerConfig (enableScss );
Config .overrideBundlerConfig (enableTailwind );Snippets
Add a plugin
Use Webpack plugins with Config.overrideWebpackConfig():
remotion.config.tsimport {webpack } from '@remotion/bundler'; import {Config } from '@remotion/cli/config';Config .overrideWebpackConfig ((config ) => { return { ...config ,plugins : [ ...(config .plugins ?? []), newwebpack .DefinePlugin ({MY_CONSTANT :JSON .stringify ('value'), }), ], }; });
Use the equivalent Rspack plugin with Config.overrideRspackConfig():
- npm
- bun
- pnpm
- yarn
npm i --save-exact @rspack/core
pnpm i @rspack/core
bun i @rspack/core
yarn --exact add @rspack/core
remotion.config.tsimport {Config} from '@remotion/cli/config'; import {DefinePlugin} from '@rspack/core'; Config.overrideRspackConfig((config) => { return { ...config, plugins: [ ...(config.plugins ?? []), new DefinePlugin({ MY_CONSTANT: JSON.stringify('value'), }), ], }; });
Do not pass a plugin created by webpack to Rspack or a plugin created by @rspack/core to Webpack.
Enabling MDX support
- Install the following dependencies:
- npm
- bun
- pnpm
- yarn
npm i --save-exact @mdx-js/loader @mdx-js/react
pnpm i @mdx-js/loader @mdx-js/react
bun i @mdx-js/loader @mdx-js/react
yarn --exact add @mdx-js/loader @mdx-js/react
- Create a file with the bundler override:
enable-mdx.tsexport constenableMdx :BundlerOverrideFn = (currentConfiguration ) => { return { ...currentConfiguration ,module : { ...currentConfiguration .module ,rules : [ ...(currentConfiguration .module ?.rules ?currentConfiguration .module .rules : []), {test : /\.mdx?$/,use : [ {loader : '@mdx-js/loader',options : {}, }, ], }, ], }, }; };
- Add it to the config file:
remotion.config.tsimport {Config } from '@remotion/cli/config'; import {enableMdx } from './src/enable-mdx';Config .overrideBundlerConfig (enableMdx );
-
Add it to your Node.JS API calls as well if necessary.
-
Create a file which contains
declare module '*.mdx';in your project to fix a TypeScript error showing up.
Enable TailwindCSS support
Enable PostCSS support
Use this snippet for generic PostCSS plugins. For TailwindCSS, use the TailwindCSS docs instead.
- Install the following dependencies:
- npm
- bun
- pnpm
- yarn
npm i --save-exact postcss postcss-loader postcss-size
pnpm i postcss postcss-loader postcss-size
bun i postcss postcss-loader postcss-size
yarn --exact add postcss postcss-loader postcss-size
- Create a file with the bundler override:
src/enable-postcss.tsexport constenablePostCSS :BundlerOverrideFn = (currentConfiguration ) => { return { ...currentConfiguration ,module : { ...currentConfiguration .module ,rules : (currentConfiguration .module ?.rules ?? []).map ((rule ) => { if (!rule ||rule === '...') { returnrule ; } if (!rule .test ?.toString ().includes ('.css')) { returnrule ; } constuse =Array .isArray (rule .use ) ?rule .use :rule .use ? [rule .use ] : []; return { ...rule ,use : [ ...use , {loader : 'postcss-loader',options : {postcssOptions : {plugins : ['postcss-size'], }, }, }, ], }; }), }, }; };
- Add it to the config file:
remotion.config.tsimport {Config } from '@remotion/cli/config'; import {enablePostCSS } from './src/enable-postcss';Config .overrideBundlerConfig (enablePostCSS );
-
Add it to your Node.JS API calls as well if necessary.
-
Restart the Remotion Studio.
Enable SASS/SCSS support
The easiest way is to use the @remotion/enable-scss.
Follow these instructions to enable it.
Enable SVGR support
This allows you to enable import SVG files as React components.
- Install the following dependency:
- npm
- bun
- pnpm
- yarn
npm i --save-exact @svgr/webpack
pnpm i @svgr/webpack
bun i @svgr/webpack
yarn --exact add @svgr/webpack
- Declare an override function:
src/enable-svgr.tsimport {WebpackOverrideFn } from '@remotion/bundler'; export constenableSvgr :WebpackOverrideFn = (currentConfiguration ) => { return { ...currentConfiguration ,module : { ...currentConfiguration .module ,rules : [ {test : /\.svg$/i,issuer : /\.[jt]sx?$/,resourceQuery : {not : [/url/]}, // Exclude react component if *.svg?urluse : ['@svgr/webpack'], }, {test : /\.svg$/i,resourceQuery : /url/, // Load *.svg?url as an asset URLtype : 'asset/resource', }, ...(currentConfiguration .module ?.rules ?? []).map ((r ) => { if (!r ) { returnr ; } if (r === '...') { returnr ; } if (!r .test ?.toString ().includes ('svg')) { returnr ; } return { ...r , // Remove Remotion loading SVGs as a URLtest : newRegExp (r .test .toString ().replace (/svg\|/g, '').slice (1, -1)), }; }), ], }, }; };
- Add the override function to your
remotion.config.tsfile:
remotion.config.tsimport {Config } from '@remotion/cli/config'; import {enableSvgr } from './src/enable-svgr';Config .overrideWebpackConfig (enableSvgr );
-
Add it to your Node.JS API calls as well if necessary.
-
Restart the Remotion Studio.
Enable support for GLSL imports
- Install the following dependencies:
- npm
- bun
- pnpm
- yarn
npm i --save-exact glslify glslify-import-loader glslify-loader raw-loader
pnpm i glslify glslify-import-loader glslify-loader raw-loader
bun i glslify glslify-import-loader glslify-loader raw-loader
yarn --exact add glslify glslify-import-loader glslify-loader raw-loader
- Declare a webpack override:
src/enable.glsl.tsimport {WebpackOverrideFn } from '@remotion/bundler'; export constenableGlsl :WebpackOverrideFn = (currentConfiguration ) => { return { ...currentConfiguration ,module : { ...currentConfiguration .module ,rules : [ ...(currentConfiguration .module ?.rules ?currentConfiguration .module .rules : []), {test : /\.(glsl|vs|fs|vert|frag)$/,exclude : /node_modules/,use : [ 'glslify-import-loader', {loader : 'raw-loader',options : {esModule : false}, }, 'glslify-loader', ], }, ], }, }; };
remotion.config.tsimport {Config } from '@remotion/cli/config'; import {enableGlsl } from './src/enable-glsl';Config .overrideWebpackConfig (enableGlsl );
- Add the following to your entry point (e.g.
src/index.ts):
declare module '*.glsl' {
const value: string;
export default value;
}-
Add it to your Node.JS API calls as well if necessary.
-
Reset the webpack cache by deleting the
node_modules/.cachefolder. -
Restart the Remotion Studio.
Enable WebAssembly
Rspack and Webpack support asynchronous WebAssembly. Webpack's syncWebAssembly mode is only supported by Webpack.
Asynchronous WebAssembly
Use a shared override to enable asynchronous WebAssembly with either bundler:
remotion.config.tsimport {Config } from '@remotion/cli/config';Config .overrideBundlerConfig ((conf ) => { return { ...conf ,experiments : { ...conf .experiments ,asyncWebAssembly : true, }, }; });
Static and dynamic .wasm imports are supported.
Webpack's synchronous WebAssembly mode
Rspack does not implement Webpack's syncWebAssembly experiment. If a library relies on synchronous named exports from a .wasm import, use a Webpack-specific override:
remotion.config.tsimport {Config } from '@remotion/cli/config';Config .overrideWebpackConfig ((conf ) => { return { ...conf ,experiments : { ...conf .experiments ,syncWebAssembly : true, }, }; });
Since Webpack does not allow synchronous WebAssembly code in the main chunk, you most likely need to declare your composition using lazyComponent instead of component. Check out a demo project for an example.
After changing the configuration, restart the Remotion Studio.
Add the asynchronous override as bundlerOverride to your Node.JS API calls if necessary. Pass the synchronous override as webpackOverride.
Change the @jsxImportSource
Webpack uses Remotion's esbuild loader for TypeScript and JSX. Change its jsxImportSource option in a Webpack-specific override:
remotion.config.tsimport {Config } from '@remotion/cli/config';Config .overrideWebpackConfig ((config ) => { return { ...config ,module : { ...config .module ,rules :config .module ?.rules ?.map ((rule ) => { // @ts-expect-error if (!rule ?.use ) { returnrule ; } return { // @ts-expect-error ...rule , // @ts-expect-erroruse :rule ?.use .map ((use ) => { if (!use ?.loader ?.includes ('esbuild')) { returnuse ; } return { ...use ,options : { ...use .options ,jsxImportSource : 'react', }, }; }), }; }), }, }; });
Rspack uses its built-in SWC loader instead. Change jsc.transform.react.importSource in a Rspack-specific override:
remotion.config.tsimport {Config } from '@remotion/cli/config';Config .overrideRspackConfig ((config ) => { return { ...config ,module : { ...config .module ,rules :config .module ?.rules ?.map ((rule ) => { if (!rule ||rule === '...' || !Array .isArray (rule .use )) { returnrule ; } return { ...rule ,use :rule .use .map ((use ) => { if ( typeofuse === 'string' ||use .loader !== 'builtin:swc-loader' ) { returnuse ; } constoptions =use .options as | {jsc ?: {transform ?: {react ?:Record <string, unknown>}; }; } | undefined; return { ...use ,options : { ...options ,jsc : { ...options ?.jsc ,transform : { ...options ?.jsc ?.transform ,react : { ...options ?.jsc ?.transform ?.react ,importSource : 'react', }, }, }, }, }; }), }; }), }, }; });
Use legacy babel loader
See Using legacy Babel transpilation.
Enable TypeScript aliases
See TypeScript aliases.
Customizing configuration file location
You can pass a --config option to the command line to specify a custom location for your configuration file.
Importing ES Modules in remotion.config.tsv4.0.117
The config file gets executed in a CommonJS environment. If you want to import ES modules, you can pass an async function to Config.overrideWebpackConfig:
remotion.config.tsimport {Config } from '@remotion/cli/config';Config .overrideWebpackConfig (async (currentConfiguration ) => { const {enableSass } = await import('./src/enable-sass'); returnenableSass (currentConfiguration ); });