Rspack Bundler Integration
Rspack integration updates Meteor apps to modern bundling standards, offering faster builds, quicker reloads, smaller bundles, and a smoother development experience with built-in features and configurations.
In this setup, Rspack bundles your app code, while Meteor Bundler produces the final output, maintaining support for Meteor features like Atmosphere packages.
Quick start
INFO
Starting with Meteor 3.4
Add this Atmosphere package to your app:
meteor add rspack-beta340.9
On first run, the package installs the required Rspack setup at the project level. It compiles your app code with Rspack to get the full benefit of this integration.
Requirements
Define the app’s entry points
Your app must define entry points for the Rspack integration to work. Entry points tell Rspack which files start execution on the client and server.
In Meteor, set this in package.json
:
{
"meteor": {
"mainModule": {
"client": "client/main.js",
"server": "server/main.js"
}
}
}
Check out the Meteor migration guide on describing entry points in your app.
Remove nested imports
Your app code cannot use Meteor's specific nested imports (not to be confused with dynamic imports, which are supported). These are ES import statements placed inside conditions or functions.
if (condition) {
import { a as b } from "./c"; // This is a nested import
console.log(b);
}
Refer to the Meteor migration guide to ensure your app code has no nested imports.
Reserve a new build context
A Meteor-Rspack project reserves the folders _build
, {public,private}/build-assets
, and {public,private}/build-chunks
to store intermediate and production bundles.
_build/*
. Contains the Rspack entry point, the intermediate Rspack app, and the overridden Meteor entry point that imports the Rspack app. It creates contexts for different environments, such as main or test modules, development and production, client and server. You can explore the contents to understand more.build-assets/*
. Placed insidepublic
(client) andprivate
(server) folders. Stores assets built by Rspack that are packed into the final Meteor app.build-chunks/*
. Placed insidepublic
(client) folder. Stores chunks built by Rspack from code splitting (dynamic imports), CSS generation, and other chunk processing, to be packed into the final Meteor app.
The folders are prepared and cleared automatically and should not be modified directly, as they are autogenerated. They are added to .gitignore
when using Git, and it’s recommended to exclude them from IDE analysis.
You don’t need to migrate your project for this, just ensure these folders are reserved for Meteor-Rspack. If you already use them for something else, move that content elsewhere.
If you want to customize the folder names, set these options in package.json
:
{
"meteor": {
"buildContext": "build",
"assetsContext": "assets",
"chunksContext": "chunks"
}
}
WARNING
Attempts were made to reuse the existing .meteor/local
cache context instead of creating new build contexts, but this was not possible.
Use .meteor/local
or folders that suggest internals or hidden content (e.g., starting with a dot). These affect debug visibility, file watching, final compilation, and inclusion in the Cordova bundle.
Replace build plugins
Meteor build plugins extend the Meteor bundler by letting you handle new file types and process them for the final app bundle. They’ve commonly handled HTML templating, style files for Less or SCSS, CoffeeScript, and more, since the system allows third-party customization.
However, Meteor’s build system solves the same problems as other bundlers, including Rspack. Build plugins are largely deprecated in favor of Rspack alternatives. Some plugins may still be useful if they don’t act directly on app files and do something Meteor-specific that can be preserved.
Among the compatible plugins:
zodern:types
. Still compatible, automatically providing Meteor types for core and community packages.
For others, please refer to the migration topics.
- CSS, Less, and SCSS (when using
less
,fourseven:scss
) - Coffeescript (when using
coffeescript
) - Svelte (when using
zodern:melte
)
You can still use these plugins to handle files inside Meteor atmosphere packages. You only need consider Rspack alternative when it’s required for your app code, which will usually be the case. An exception applies to HTML and CSS files: you can still use Meteor plugins touching these files if they are in the entry folder (e.g. client/*.[html|css]
in most apps), or when using modules
config as explained in the Entry Points migration guide.
Please report your plugin usage as GitHub issues or forum posts, so we can suggest an Rspack alternative or assess compatibility.
Custom rspack.config.js
Meteor-Rspack projects can be customized using the rspack.config.js
file, which is automatically available when installing the rspack
package. You can also use rspack.config.mjs
or rspack.config.cjs
if you prefer strict ESM or CommonJS formats.
This file defines dynamic configurations, so you return the config from a resolved function.
const { defineConfig } = require('@meteorjs/rspack');
const { rspack } = require('@rspack/core');
const HtmlRspackPlugin = require('html-rspack-plugin');
const NodePolyfillPlugin = require('node-polyfill-webpack-plugin');
/**
* Example: Using different plugins for client and server builds
*
* - For client: Load Lodash automatically with ProvidePlugin
* - For server: Add Node.js polyfills with NodePolyfillPlugin
* - For both: Add progress plugin
*/
module.exports = defineConfig(Meteor => {
return {
plugins: [
Meteor.isClient && new rspack.ProvidePlugin({ _: 'lodash' }),
Meteor.isServer && new NodePolyfillPlugin(),
new rspack.ProgressPlugin()
].filter(Boolean)
};
});
You can use flags to control the final configuration based on the environment. The available flags are passed in the Meteor
parameter.
Flag | Type | Description |
---|---|---|
isDevelopment | boolean | True when running in development mode |
isProduction | boolean | True when running in production mode |
isClient | boolean | True when building or running client code |
isServer | boolean | True when building or running server code |
isTest | boolean | True when running in test mode |
isDebug | boolean | True when debug mode is enabled |
isRun | boolean | True when running the project with meteor run |
isBuild | boolean | True when building the project with meteor build |
swcConfigOptions | object | Project-level SWC config available for reusing |
HtmlRspackPlugin | function | Custom HtmlRspackPlugin function for extending the config |
Some configurations in the Rspack config are reserved for the Meteor-Rspack setup to work, such as Rspack options inside the entry
and output
objects. These will trigger warnings if modified. All other settings can be overridden, giving you the flexibility to make any setup compatible with the modern bundler.
If you want to see the final Rspack config applying your overrides, you can enable verbose mode in the modern build stack.
"meteor": {
"modern": {
"verbose": true
}
}
Migration Topics
Entry Points
Meteor entry points allow a modular, modern, bundler-compliant structure for your Meteor app. Modern bundlers define entry points where the evaluation and bootstrap of your app begin. In Meteor, you can set these for both the client and server, and optionally for tests.
{
"meteor": {
"mainModule": {
"client": "client/main.js",
"server": "server/main.js"
},
"testModule": "tests.js"
}
}
Learn more in “Modular application structure” in Meteor.
Ensure your app defines these entry files with the correct paths where each module is expected to load. Organize your app so the loading order of modules is clear.
Defining entry points improves performance even with the Meteor bundler, as Meteor stops scanning and eagerly loading unnecessary files. For Meteor-Rspack integration, this is required, since it does not support automatic code discovery for efficiency.
In Meteor-Rspack integration, all app code is ignored by Meteor and handled by Rspack. By default, Meteor still processes eagerly CSS and HTML files in the entry folder (e.g. client/*.[html|css]
in most apps).
If you need Meteor to handle CSS or HTML files outside the main entry folder, add them to the modules
field. This field accepts an array of strings, each pointing to a file or folder.
{
"meteor": {
"modules": ["styles/main.css"]
}
}
With this, Meteor will process these files, merge stylesheets, generate the final HTML, and support files a Meteor plugin may use, except for JS or script code now handled by Rspack. You can also process CSS and HTML files directly with Rspack using loaders from imports in your app code, as mentioned in "CSS, Less and SCSS" or "HtmlRspackPlugin". If you prefer Meteor's loading approach, you can still rely on it.
Keep in mind: compiling styles with the Meteor compilers triggers Meteor HMR, which is slower than Rspack HMR. Migrating to compile styles with Rspack as part of the app code ensures the fastest HMR for style changes in development.
Nested Imports
Nested imports are a feature of Meteor’s bundler, not supported in standard bundlers. Meteor introduced them during a time when bundling standards were still evolving and experimented with its own approach. This feature comes from the reify
module and works with Babel transpilation. SWC doesn't support them since they were never standardized.
WARNING
Don't confuse nested imports with standardized dynamic imports using import()
in module blocks, these are supported.
Example with a nested import:
// import { a as b } from "./c"; // root import
if (condition) {
import { a as b } from "./c"; // nested import
console.log(b);
}
For background, see: Why nested import.
To use Rspack, migrate your nested imports to a standard form. To identify and fix nested imports in your project, use verbose mode in Meteor 3.3’s modern transpiler. Enable it with:
"meteor": {
"modern": {
"verbose": true
}
}
When you run your app, [Transpiler]
logs will show each file. Focus on (app)
files that fail with messages like:
Error: 'import' and 'export' cannot be used outside of module code
Fix nested imports by moving them to the top of the file, or by replacing them with require or dynamic import.
You can skip migrating (package)
code with nested imports. Meteor packages are still handled by the Meteor bundler in Rspack integration, but your app code is fully delegated to Rspack and must use standard syntax.
Nested imports isn’t standard, most modern projects use other deferred loading methods. Let Rspack handle files to speed builds and enable modern features. The choice is up to the devs. Some Meteor devs use nested imports for valid reasons. You can opt out of Rspack and still get build speed gains from Meteor bundler optimizations.
INFO
With Meteor–Rspack integration, you can still use nested imports if they are defined in Meteor Atmosphere packages. These will be accepted without any breaking changes.
Import Aliasses
An import alias is a shortcut that maps a custom name to a specific file path or directory, making imports shorter and easier to manage.
With Meteor-Rspack integration you can define aliases using the resolve.alias
configuration in your rspack.config.js
. For example:
export default defineConfig(Meteor => {
return {
resolve: {
alias: {
'@ui': '/imports/ui',
'@api': '/imports/api',
},
};
}
Learn more in the Rspack alias docs.
If you use TypeScript, also update your tsconfig.json
to support IDE autocompletion and ESLint resolution:
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@ui/*": ["imports/ui/*"],
"@api/*": ["imports/api/*"]
}
}
}
You can also configure aliases at the transpiler level. For SWC, enable it through the .swcrc
file (note that SWC aliases have some limitations when resolving files or node_modules
). If you use Babel, you can rely on the module-resolver plugin.
CSS, Less and SCSS
Meteor-Rspack comes with built-in CSS support. You can import any CSS file into your code, and it will be processed and included in your HTML skeleton automatically. In addition, any CSS file placed in the same folder as your Meteor entry point will be processed and added as global styles without the need for explicit imports.
Less support in Meteor-Rspack is limited. The Meteor less
package compiles .less
files automatically and merges them into the CSS bundle. With Rspack, you should configure Less directly and consider as replacement of the Meteor package. For details, check the Rspack and Less guide.
SCSS support is available in Meteor-Rspack. You may need to replace the existing Meteor fourseven:scss
package or similar with the Rspack configuration. For details, check the official Rspack and SCSS guide.
React
Meteor-Rspack supports React projects out of the box. Just install the rspack
package and run your app. Meteor will detect it and automatically add the needed Rspack dependencies, including react-refresh
for a full development experience.
Learn more in the official Rspack and React integration guide.
Use
meteor create --react
to start with a preconfigured Rspack React app.
React Compiler
Meteor-Rspack supports React Compiler. To enable it, install the required dependencies and add the new configuration to Meteor’s rspack.config.js
file.
Learn more in the official Rspack and React Compiler integration guide.
Vue
Meteor-Rspack supports Vue projects out of the box. To enable it, install the required dependencies and add the new configuration to Meteor’s rspack.config.js
file.
Learn more in the official Rspack and Vue integration guide.
Use
meteor create --vue
to start with a preconfigured Rspack Vue app.
WARNING
Previous official support in the Meteor bundler was through jorgenvatle:vite.
With Meteor-Rspack integration, you no longer need vite-related packages, so you should remove them from your project.
Solid
Meteor-Rspack supports Solid projects out of the box. To enable it, install the required dependencies and add the new configuration to Meteor’s rspack.config.js
file.
Learn more in the official Rspack and Solid integration guide.
Use
meteor create --solid
to start with a preconfigured Rspack Solid app.
WARNING
Previous official support in the Meteor bundler was through jorgenvatle:vite.
With Meteor-Rspack integration, you no longer need vite-related packages, so you should remove them from your project.
Coffeescript
Meteor-Rspack supports CoffeeScript projects out of the box. To enable it, install the needed dependencies and add the configuration to Meteor’s rspack.config.js.
See the official Webpack and CoffeeScript integration guide. Since Rspack is based on Webpack, the same setup applies.
If you want to use SWC with CoffeeScript, combine swc-loader
with coffee-loader
.
npm install --save-dev coffeescript swc-loader coffee-loader
In your rspack.config.js
you would add something like:
export default defineConfig(Meteor => {
return {
module: {
rules: [
{
test: /\.coffee$/i,
use: [
{
loader: 'swc-loader',
// perserve SWC config in the Meteor project level
options: Meteor.swcConfigOptions,
},
{
loader: 'coffee-loader',
},
],
},
],
},
resolve: {
extensions: ['.coffee'],
},
};
});
Use
meteor create --coffeescript
to start with a preconfigured Rspack Coffeescript app.
Svelte
Meteor-Rspack supports Svelte projects out of the box. To enable it, install the required dependencies and add the new configuration to Meteor’s rspack.config.js
file.
Learn more in the official Rspack and Svelte integration guide.
Use
meteor create --svelte
to start with a preconfigured Rspack Svelte app.
WARNING
Official Svelte support in the Meteor bundler was via zodern:melte.
With the Meteor–Rspack integration, zodern:melte
no longer works. Use the official Rspack Svelte integration instead. If you relied on melte-specific features like $
or $m
, you may need to update parts of your code. Create your own abstractions or migrate them to standard npm package.
Tailwind
Meteor-Rspack supports Tailwind projects out of the box. For details, check the official Rspack and Tailwind guide.
Use
meteor create --tailwind
to start with a preconfigured Rspack Tailwind app.
Babel
Meteor-Rspack supports Babel projects as an alternative to default SWC.
Use
meteor create --babel
to start with a preconfigured Rspack Babel app.
Using Babel will increase build times. Prefer SWC. If you need Babel for specific files, limit Babel to those files, or use a hybrid with SWC and Babel. For example, enabling React Compiler is available only via Babel using module rules.
HtmlRspackPlugin
Meteor-Rspack includes its own HtmlRspackPlugin, enabled by default to attach chunks and assets to the HTML skeleton. Meteor then uses this HTML to generate the final index file.
If you want to customize HtmlRspackPlugin, add it to your rspack.config.js
file:
export default defineConfig(Meteor => {
return {
plugins: [
Meteor.HtmlRspackPlugin({
meta: {
// Will generate: <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
viewport: 'width=device-width, initial-scale=1, shrink-to-fit=no',
// Will generate: <meta name="theme-color" content="#4285f4">
'theme-color': '#4285f4',
// Will generate: <meta http-equiv="Content-Security-Policy" content="default-src https:">
'Content-Security-Policy': {
'http-equiv': 'Content-Security-Policy',
content: 'default-src https:',
},
},
}),
],
};
});
This example adds meta tags to the HTML. For more options, see the official Rspack and HTML integration guide.
WARNING
You can still use HTML files near your Meteor client entry point to define customizations (for example, ./client/main.html
will generate correctly and apply the contents you add).
Benefits
Meteor–Rspack integration sends your app code to Rspack to use modern bundler features. Meteor then uses Rspack’s output to handle Meteor-specific tasks (like Atmosphere package compilation) and create the final bundle.
This implementation preserves Rspack HMR for faster reloads.
With Rspack
compiling your app you get:
- Standard code splitting via HTTP
- Tree shaking to significantly reduce bundle size
- Support for ESM packages, including npm packages with export fields
- Bundler plugins for build hooks, alternative compilers, file resolvers, image optimizations, PWAs with service workers, and more
- Advanced analysis tools to track code impact and guide later optimizations
- More features coming soon
With Meteor
you get:
- Core API with reactive and non-reactive endpoints (DDP, Express)
- Built-in Mongo/Minimongo API for isomorphic business logic
- Third-party packages for faster development
- Multiplatform development support
- All other Meteor strengths
Limitations
No Blaze HMR support
Blaze templates build correctly with Rspack, but Meteor’s Hot Module Replacement (HMR) for Blaze is not available. Normally, Blaze HMR updates the UI instantly without reloading the whole page, keeping the current state (like form inputs or scroll position).
With Rspack, Blaze changes will instead trigger a full live reload. This reload is still very fast thanks to Rspack’s reduced rebuild time (about 97% reduction), but the page state will reset after each change. The limitation exists because Blaze’s HMR relies on Meteor’s internal mechanism, which is not yet compatible with Rspack.
This limitation only applies to Blaze. Any other modern project will work with HMR as soon as Rspack natively supports it, which is likely if it’s a modern library.
Troubleshotting
If you run into issues, try meteor reset
or delete the .meteor/local
and _build
folders in the project root.
For help or to report issues, post on GitHub or the Meteor forums. We’re focused on making Meteor faster and your feedback helps.
You can compare performance before and after enabling modern
by running meteor profile
. Share your results to show progress to others.