Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
506e5c0
`@remotion/bundler`: Add `--rspack` flag for optional Rspack bundling
JonnyBurger Feb 19, 2026
cda35d1
fix a couple of issues
JonnyBurger Feb 19, 2026
c54fa3b
make options mandatory
JonnyBurger Feb 19, 2026
5cebbf5
ignore warnings
JonnyBurger Feb 19, 2026
d3a0341
Rename `--rspack` to `--experimental-rspack` and add `Config.setExper…
JonnyBurger Feb 19, 2026
40cc637
abstract
JonnyBurger Feb 19, 2026
5e89654
simplify
JonnyBurger Feb 19, 2026
376c3d3
Add `rspack` option to CLI bundle/render pipeline, Lambda/CloudRun `d…
JonnyBurger Feb 19, 2026
33dbaaa
Merge branch 'main' into rspack-bundler-option
JonnyBurger Feb 19, 2026
1ee8634
Extract shared config between rspack and webpack, replace 4.0.TBD wit…
JonnyBurger Feb 19, 2026
bf9f8d3
fix
JonnyBurger Feb 19, 2026
600c05f
Remove process-update.ts HMR client, add disk fallback for rspack hot…
JonnyBurger Feb 19, 2026
f812af8
Add `pullfrog.yml` workflow
JonnyBurger Feb 20, 2026
69652cb
Migrate --port, --props, --config, --browser to options system
JonnyBurger Feb 20, 2026
29913c9
Update proxy.mdx
JonnyBurger Feb 20, 2026
a81dea4
Update packages/docs/docs/cli/studio.mdx
JonnyBurger Feb 20, 2026
cc69cbe
style: Fix formatting
pullfrog[bot] Feb 20, 2026
f77c25c
Merge pull request #6604 from remotion-dev/migrate-cli-options-port-p…
JonnyBurger Feb 20, 2026
a999134
Update remotion.config.ts
JonnyBurger Feb 20, 2026
9ebb04b
Merge branch 'main' into rspack-bundler-option
JonnyBurger Feb 20, 2026
c1e7209
`@remotion/web-renderer`: Add support for text shadows
JonnyBurger Feb 20, 2026
2f0f422
Allow changelog workflow to post for a specific release tag
JonnyBurger Feb 20, 2026
e2f0d3a
docs: Use <Options> component for shared option descriptions
JonnyBurger Feb 20, 2026
fcd578e
Merge pull request #6609 from remotion-dev/docs/use-options-component
JonnyBurger Feb 20, 2026
78c8da6
Revert debugging changes to HMR middleware files
JonnyBurger Feb 20, 2026
b53f3fd
Extract shared shadow parser and update docs
JonnyBurger Feb 20, 2026
7a1e95c
Merge branch 'main' into rspack-bundler-option
JonnyBurger Feb 20, 2026
c11c738
use options
JonnyBurger Feb 20, 2026
9e8e74d
Merge pull request #6596 from remotion-dev/rspack-bundler-option
JonnyBurger Feb 20, 2026
1a190b8
Merge pull request #6607 from remotion-dev/web-renderer-text-shadow
JonnyBurger Feb 20, 2026
f788a5e
`docs`: Add CompatibilityTable and fix backticks in renderer docs
JonnyBurger Feb 20, 2026
0f7352a
`@remotion/renderer`: Add mimeType field to renderMedia() and renderS…
JonnyBurger Feb 20, 2026
68ce4cd
Fix mimeLookup for bare extensions
JonnyBurger Feb 20, 2026
4a495d4
Add mimeType assertions to existing tests and AvailableFrom to docs
JonnyBurger Feb 20, 2026
ed7c3b0
Use AvailableFrom component for buffer in render-still docs
JonnyBurger Feb 20, 2026
6334a94
Fix renderStill() links pointing to stitch-frames-to-video instead of…
pullfrog[bot] Feb 20, 2026
545f661
Update make-cancel-signal.mdx
JonnyBurger Feb 20, 2026
531b4ab
docs cleanup
JonnyBurger Feb 20, 2026
09492ec
Merge pull request #6611 from remotion-dev/add-mimetype-to-render-res…
JonnyBurger Feb 20, 2026
7eacbb4
`@remotion/serverless`: Await final progress upload and improve uploa…
JonnyBurger Feb 20, 2026
6d6a733
Merge pull request #6610 from remotion-dev/docs/renderer-compatibilit…
JonnyBurger Feb 20, 2026
ef9b40b
`@remotion/renderer`: Rename mimeType to contentType
JonnyBurger Feb 20, 2026
91a66df
Merge pull request #6612 from remotion-dev/fix/serverless-progress-up…
JonnyBurger Feb 20, 2026
1d346a7
Merge pull request #6614 from remotion-dev/rename-mimetype-to-content…
JonnyBurger Feb 20, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .claude/skills/web-renderer-test/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,4 @@ test('should render background-color', async () => {
2. **Important**: Add the fixture to `packages/web-renderer/src/test/Root.tsx` to add a way to preview it.
3. Add a new test in `packages/web-renderer/src/test`.
4. Run `bunx vitest src/test/video.test.tsx` to execute the test.
5. **Important**: Update `packages/docs/docs/client-side-rendering/limitations.mdx` to reflect the newly supported property.
6 changes: 5 additions & 1 deletion .github/workflows/changelog.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ on:
release:
types: [published]
workflow_dispatch:
inputs:
tag:
description: 'Release tag to post (e.g. v4.0.422). Leave empty for latest.'
required: false
name: Publish latest release

jobs:
Expand All @@ -18,4 +22,4 @@ jobs:
DISCORD_TOKEN: ${{ secrets.DISCORD_TOKEN }}
run: |
cd packages/discord-poster
bun post.ts
bun post.ts ${{ github.event.inputs.tag }}
46 changes: 46 additions & 0 deletions .github/workflows/pullfrog.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# PULLFROG ACTION — DO NOT EDIT EXCEPT WHERE INDICATED
name: Pullfrog
run-name: ${{ inputs.name || github.workflow }}
on:
workflow_dispatch:
inputs:
prompt:
type: string
description: Agent prompt
name:
type: string
description: Run name

permissions:
id-token: write
contents: write
pull-requests: write
issues: write
actions: read
checks: read

jobs:
pullfrog:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
fetch-depth: 1
- name: Run agent
uses: pullfrog/pullfrog@v0
with:
prompt: ${{ inputs.prompt }}
env:
# add any additional keys your agent(s) need
# optionally, comment out any you won't use
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
GOOGLE_API_KEY: ${{ secrets.GOOGLE_API_KEY }}
GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
CURSOR_API_KEY: ${{ secrets.CURSOR_API_KEY }}
MISTRAL_API_KEY: ${{ secrets.MISTRAL_API_KEY }}
GROQ_API_KEY: ${{ secrets.GROQ_API_KEY }}
DEEPSEEK_API_KEY: ${{ secrets.DEEPSEEK_API_KEY }}
OPENROUTER_API_KEY: ${{ secrets.OPENROUTER_API_KEY }}

16 changes: 15 additions & 1 deletion bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions packages/bundler/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
"author": "Jonny Burger <jonny@remotion.dev>",
"license": "SEE LICENSE IN LICENSE.md",
"dependencies": {
"@rspack/core": "1.7.6",
"@rspack/plugin-react-refresh": "1.6.1",
"css-loader": "5.2.7",
"esbuild": "0.25.0",
"react-refresh": "0.9.0",
Expand Down
84 changes: 66 additions & 18 deletions packages/bundler/src/bundle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import webpack from 'webpack';
import {copyDir} from './copy-dir';
import {indexHtml} from './index-html';
import {readRecursively} from './read-recursively';
import {rspackConfig} from './rspack-config';
import type {WebpackOverrideFn} from './webpack-config';
import {webpackConfig} from './webpack-config';

Expand Down Expand Up @@ -52,6 +53,7 @@ export type MandatoryLegacyBundleOptions = {
onSymlinkDetected: (path: string) => void;
keyboardShortcutsEnabled: boolean;
askAIEnabled: boolean;
rspack: boolean;
};

export type LegacyBundleOptions = Partial<MandatoryLegacyBundleOptions>;
Expand All @@ -72,10 +74,10 @@ export const getConfig = ({
bufferStateDelayInMilliseconds: number | null;
experimentalClientSideRenderingEnabled: boolean;
maxTimelineTracks: number | null;
onProgress?: (progress: number) => void;
options?: LegacyBundleOptions;
onProgress: (progress: number) => void;
options: MandatoryLegacyBundleOptions;
}) => {
return webpackConfig({
const configArgs = {
entry: path.join(
require.resolve('@remotion/studio/renderEntry'),
'..',
Expand All @@ -84,9 +86,9 @@ export const getConfig = ({
),
userDefinedComponent: entryPoint,
outDir,
environment: 'production',
environment: 'production' as const,
webpackOverride: options?.webpackOverride ?? ((f) => f),
onProgress: (p) => {
onProgress: (p: number) => {
onProgress?.(p);
},
enableCaching: options?.enableCaching ?? true,
Expand All @@ -97,7 +99,13 @@ export const getConfig = ({
poll: null,
experimentalClientSideRenderingEnabled,
askAIEnabled: options?.askAIEnabled ?? true,
});
};

if (options.rspack) {
return rspackConfig(configArgs);
}

return webpackConfig(configArgs);
};

type NewBundleOptions = {
Expand Down Expand Up @@ -229,20 +237,59 @@ export const internalBundle = async (
actualArgs.experimentalClientSideRenderingEnabled,
});

const output = (await promisified([config])) as
| webpack.MultiStats
| undefined;
if (isMainThread) {
process.chdir(currentCwd);
}
if (actualArgs.rspack) {
const {rspack: rspackFn} = require('@rspack/core');
const rspackCompiler = rspackFn(config);
const rspackOutput = await new Promise<{
toJson: (opts: unknown) => {
errors?: Array<{message: string; details: string}>;
};
}>((resolve, reject) => {
rspackCompiler.run(
(
err: Error | null,
stats: {
toJson: (opts: unknown) => {
errors?: Array<{message: string; details: string}>;
};
},
) => {
if (err) {
reject(err);
return;
}

rspackCompiler.close(() => {
resolve(stats);
});
},
);
});

if (!output) {
throw new Error('Expected webpack output');
}
if (isMainThread) {
process.chdir(currentCwd);
}

const {errors} = output.toJson();
if (errors !== undefined && errors.length > 0) {
throw new Error(errors[0].message + '\n' + errors[0].details);
const {errors} = rspackOutput.toJson({});
if (errors !== undefined && errors.length > 0) {
throw new Error(errors[0].message + '\n' + errors[0].details);
}
} else {
const output = (await promisified([config as webpack.Configuration])) as
| webpack.MultiStats
| undefined;
if (isMainThread) {
process.chdir(currentCwd);
}

if (!output) {
throw new Error('Expected webpack output');
}

const {errors} = output.toJson();
if (errors !== undefined && errors.length > 0) {
throw new Error(errors[0].message + '\n' + errors[0].details);
}
}

const publicPath = actualArgs?.publicPath ?? '/';
Expand Down Expand Up @@ -368,6 +415,7 @@ export async function bundle(...args: Arguments): Promise<string> {
renderDefaults: actualArgs.renderDefaults ?? null,
askAIEnabled: actualArgs.askAIEnabled ?? true,
keyboardShortcutsEnabled: actualArgs.keyboardShortcutsEnabled ?? true,
rspack: actualArgs.rspack ?? false,
});
return result;
}
21 changes: 21 additions & 0 deletions packages/bundler/src/define-plugin-definitions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
export const getDefinePluginDefinitions = ({
maxTimelineTracks,
askAIEnabled,
keyboardShortcutsEnabled,
bufferStateDelayInMilliseconds,
experimentalClientSideRenderingEnabled,
}: {
maxTimelineTracks: number | null;
askAIEnabled: boolean;
keyboardShortcutsEnabled: boolean;
bufferStateDelayInMilliseconds: number | null;
experimentalClientSideRenderingEnabled: boolean;
}) => ({
'process.env.MAX_TIMELINE_TRACKS': maxTimelineTracks,
'process.env.ASK_AI_ENABLED': askAIEnabled,
'process.env.KEYBOARD_SHORTCUTS_ENABLED': keyboardShortcutsEnabled,
'process.env.BUFFER_STATE_DELAY_IN_MILLISECONDS':
bufferStateDelayInMilliseconds,
'process.env.EXPERIMENTAL_CLIENT_SIDE_RENDERING_ENABLED':
experimentalClientSideRenderingEnabled,
});
3 changes: 3 additions & 0 deletions packages/bundler/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {findClosestFolderWithItem, getConfig, internalBundle} from './bundle';
import {indexHtml} from './index-html';
import {readRecursively} from './read-recursively';
import {createRspackCompiler, rspackConfig} from './rspack-config';
import {cacheExists, clearCache} from './webpack-cache';
import {webpackConfig} from './webpack-config';
import esbuild = require('esbuild');
Expand All @@ -9,6 +10,8 @@ import webpack = require('webpack');
export const BundlerInternals = {
esbuild,
webpackConfig,
rspackConfig,
createRspackCompiler,
indexHtml,
cacheExists,
clearCache,
Expand Down
Loading
Loading