Have you tried to do npm install? I should add this recommendation as part of that command error message, normally it happens when @meteorjs/rspack within node_modules is not present, and npm install should fix it.
I hit this when migrating a large app. My fix was to externalize a native-style dependency so Rspack doesn’t process it, and let Meteor/Node handle it directly. You can do this with the externals field, or by using the new Meteor.compileWithMeteor helper. This usually helps when you have native deps and Rspack tries to resolve them. In general, externalizing native deps is recommended.
In my case the issue was the thread-stream lib, with this config:
module.exports = defineConfig((Meteor) => {
return {
// ..
...Meteor.compileWithMeteor([
// ..
"thread-stream"
]),
};
});
To find which dependency needs to be externalized, open the server intermediate bundle (_build/main-dev/server-rspack.js). Search for worker.js (or join(__dirname, 'lib', 'worker.js')) and check the context around it to see which npm package it’s coming from. In my case it was thread-stream. It might be the same for you, but I’m describing the process in case others hit this with a different package.
I’ll update the docs to mention this case.
That worked. Thanks!
@nachocodoner I just can’t make this work with JSX in a npm package.
Whatever I tried, I always end up with this:
[client-rspack] compiled with 4 warnings in 690 ms
=> Errors prevented startup:
While building for web.browser:
node_modules/@act/toastr-component/index.js:17:14: This experimental syntax requires enabling one of the following parser plugin(s): "jsx", "flow", "typescript".
(17:14)
What is on my line 17:
const getIcon = icon => {
switch (icon) {
case 'success':
return (<ThumbUpTwoToneIcon color='success' fontSize='large' />) // line 17
// case 'warning':
// return (<WarningTwoToneIcon color='warning' fontSize='large' />)
// case 'info':
// return (<InfoTwoToneIcon color='info' fontSize='large' />)
// case 'error':
// return (<ReportTwoToneIcon color='error' fontSize='large' />)
// case 'link':
// return (<ShareTwoToneIcon color='primary' fontSize='large' />)
}
}
I have no problem outside rspack adoption.
I tried to use babel-loader, swc, include folders, exclude folders, what-not-plugins etc.
Simple reproduction: meteor create app with beta 12, add a local package with an index.js such as
const component = () => (<div>Test</div>)
export { component }
import it anywhere on the client.
I need to figure out if I can somehow migrate to this (or fix my Vite config*) because I realised somehow my (meteor-vite-compiled) client side app code is not being minified properly, and it is not a pretty bundle size ![]()
(but it never was, so… I’m not really suffering so much as feeling FOMO)
*I suspect it’s because I added the swc plugin to Vite, to phase out my use of Babel, so now esbuild isn’t doing the minimisation for some reason, but I can’t quite jump to rspack because I’m using a few plugins where I’m not sure how they’ll fare with Webpack style APIs (thanks to unjs & unplugin things are a bit less fragmented these days but…)
Reporting on the positive side: I have been using Beta 11 and now Beta 12 for about a week, and everything is working well, enjoying the speed. With my M4 powered Mac and these improvements, everything is flying.
Are we close to making a full release version yet?
Could you share the plugins you use in the Vite setup? It would help in case someone here has ideas for Rspack equivalents.
About SWC and Vite: did you make sure you’re including @swc/helpers and enabling the externalHelpers option in the swcrc config (Compilation)?
When we integrated SWC in Meteor, either directly in core or through Rspack, we had to add that dependency or recommend adding it. We also auto-enabled externalHelpers when possible for client code, so helper functions are not inlined in every file. That avoids unnecessary repeated SWC helper code and keeps it in a single shared place, reducing back the client bundle size.
Oh, great to know this. It’s nice that not everything turns out to be an issue, and I really appreciate users sharing feedback like this, as it helps us move faster toward the official release.
Regarding that, we’re currently in the extension/contribution phase. This means we’re still covering reports to achieve full Rspack support, while also adding community contributions and starting to test them. I still have a list of setups to verify. I expect that list to grow as more people experiment with the betas, so we want to keep this period open for both positive experiences and issue reports.
The main factor for the official release will be fixing critical issues. Our top priority right now is the “Total Bundle Size”. While Rspack has significantly reduced the client and server app bundle sizes, the final build artifacts (meteor build) have grown noticeably. The reason is how Meteor packages production artifacts, it includes NPM dependencies from Atmosphere packages, even dev-only ones. We also recently added SWC and a few others that increased the total size, that are not needed for production at all. On top of that, some dev dependencies like Rspack are still being included from the app’s package.json, likely due to native dependency handling. Check this attachment. It shows how Meteor 3.3 compared to Meteor 3.4-beta.12 ended up including rspack, along with several other modules, in the final app bundle artifacts where is not needed (production).
For the first issue, we already have a fix pending testing with the new Meteor dev-only packages. For the second, I’ll be working on a fix soon. With these changes, we expect to clean up long-standing problems in Meteor builds and remove unnecessary dependencies from production, reducing drastically the bundle size.
While I keep focus on the main priorities, I also keep reviewing reports, fixes, and extension possibilities in parallel. Hopefully, once the critical parts are done, we can move toward the official release and leave further feedback for the Meteor 3.4.x series.
I had a similar problem you need to tell RSPack to treat .js as jsx
This package is doing something non-standard
I solved my similar problem like this:
module: {
rules: [
{
test: /react-native-reanimated|react-native-gesture-handler/,
use: {
loader: "builtin:swc-loader",
options: {
jsc: {
parser: { syntax: "typescript", tsx: true, jsx: true },
},
},
},
},
],
},
You can also just use patch-package to rename this file to a .jsx
I believe I tried something similar already. First I tried to pass it to babel.
import { defineConfig } from '@meteorjs/rspack'
// eslint-disable-next-line no-unused-vars
export default defineConfig(Meteor => ({
builtins: {
// enable React/JSX handling in rspack (SWC-backed)
react: {
runtime: "automatic", // or "classic"
development: Meteor.isDevelopment,
importSource: "react"
}
},
module: {
rules: [
// 1) Preprocess Flow: run babel-loader first to strip Flow types
{
enforce: "pre", // run before other loaders / built-in parsing
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
babelrc: false,
presets: [
"@babel/preset-flow",
"@babel/preset-react" // keeps JSX-compatible for any files handled by babel
]
}
}
},
// 2) TypeScript (+ JSX in .tsx)
{
test: /\.(ts|tsx)$/,
type: "tsx" // tells rspack to parse TS + JSX (SWC)
},
// 3) JS / JSX - let rspack's built-in JS parser (SWC) handle remaining .js/.jsx
{
test: /\.(js|jsx)$/,
// 'type: "jsx"' enables JSX parsing/transforms via SWC
type: "jsx",
exclude: /node_modules/ // I also treid with excluding everything but my NPM of interest.
}
]
},
resolve: {
extensions: [".ts", ".tsx", ".js", ".jsx", ".json"]
}
}))
I also tried something like this:
import { defineConfig } from '@meteorjs/rspack'
// eslint-disable-next-line no-unused-vars
// (Same imports as earlier)
export default defineConfig(Meteor => {
return {
// Exclude native modules from the bundle (use Meteor runtime)
...Meteor.compileWithMeteor(['node_modules/@act/toastr-component/index.js']),
}
})
but then I tried this:
import { defineConfig } from '@meteorjs/rspack'
// eslint-disable-next-line no-unused-vars
// (Same imports as earlier)
export default defineConfig(Meteor => {
return {
module: {
rules: [
{
test: /\.jsx?$/, // Target both .js and .jsx files
use: {
loader: 'builtin:swc-loader',
options: {
jsc: {
parser: {
syntax: 'ecmascript',
jsx: true, // Enable JSX parsing
},
},
},
},
type: 'javascript/auto',
},
// ... other rules (e.g., for .tsx files)
],
}
}
})
They all yield the same error.
Then I used your configuration @schlaegerz and I am getting a different error which was reported by @wreiske here: GitHub · Where software is built
I tried transpiler options in package.json of the project
"modern": {
"transpiler": {
"exclude": "/node_modules/@act/toastr-component",
"excludeNodeModules": true
}
},
I finally killed the package and moved it in the main project as a regular React component. It compiled nicely but … now, with no errors, the page is not loading.
I spent more than 12 hours cumulated in multiple weeks trying to debug this, but I think I need to park this indefinitely. I am not sure this is going to work for me, the Meteor build now is a Frankenstein of babel, swc, webpack, rspack and I just don’t understand it and I don’t know which docs to use, when, in what context, which part comes from which tech, which settings to use where and where to take them from … etc.
@paulishca: I’ve added your issue to my work queue. As soon as it’s as easy to reproduce as you described above, it should be easier to track down the fix. Sometimes these problems come from package incompatibilities when certain packages don’t follow specific standards. We’ll see.
By the way, Meteor.compileWithMeteor accepts an array of package names, not paths. Not sure if that helps with the issue.
I don’t get the error you get. I get this instead:


To solve it, I added:
module.exports = defineConfig((Meteor) => {
return {
...Meteor.compileWithRspack(['@act/component']),
// ..
};
}
Btw, this is a similar config as making a module.rules entry similar as suggested above. But we created this abstraction to help keep it easy.
Why? When you use local packages that still have rich syntax, like JSX, you need to tell the compiler to transpile them to plain JS CommonJS (the format Meteor expects).
Most npm packages are already published in that plain format, so you don’t need to treat node_modules often. But some are not, including your own internal packages if you keep modern JS/JSX syntaxes in them. In that case, call compileWithRspack and pass the package name/s so it gets recompiled to plain JS before Meteor runs it.
Docs: compileWithRspack
If you still see the issue, please share an exact reproduction repo so we can iterate on it with your specific case. I shared docs about this in previous updates, and I’ll try to make them clearer and more guided so it’s easier to understand how to recompile modern syntax in local packages.
I see your previous message and I did try with only the package name too. Ok what I didn’t do is to pass it to Rspack instead of Meteor (as I used Meteor.compileWithMeteor). My logic was that if it worked with Meteor in the past, will try to compile it with Meteor further. Ok, these are the type of challenges which discouraged me to spend any more time on it. Maybe I am less patient too but I really read through these documentations and it is not like they are clear on what you can do. The info is a bit thin in online too.
Anyway, this is good to know for future reference. I was past it in 2 ways, I manually recompiled with babel and generated a dist folder with the compiled code and it worked but the page would not load. At this point I moved everything out of NPM into the code and completely moved around the initial problem but the page would not load.
"modern": {
"transpiler": {
"verbose": true
}
},
This in package.json shows details of the SWC, all looks ok but I don’t get info about rspack/webpack. The HTML loads, but React doesn’t seem to mount into the div.
What I should see in dev:
What I see (no html under the div with id=“app” where React should render.) :
I try to add as much information as possible and keep the docs clear, giving full explanations and details. I know it can still be difficult for those just starting with bundler configuration, so I always try to keep that in mind and keep improving the docs. I also work on creating helpers like Meteor.compileWithRspack or Meteor.compileWithMeteor. Maybe there’s a better name given the current explanations, and I’m open to improving that. We’re also in a beta, so it’s the time for do it.
The issues mentioned above could have been fixed through direct Rspack configuration, but that would make it more verbose and harder for newcomers. These helpers I added aim to simplify that. Meteor already provides a default Rspack configuration internally, so users can have a solid starting point with minimal setup, tweak only what’s necessary also via config helpers, and still have the flexibility to go advanced if they want.
Anyway, in the end there’s no other path: if you want to get the most out of Rspack or any other tool, you need to learn the tool and how a bundler config works. AI can also help a lot with some of the config. You get many benefits that can easily pay off the effort. But it’s also totally fine for some apps to skip it. The good part is that Rspack is opt-in, and you can always go back to how Meteor handles things.
If you want me to look at other approaches you tried to solve the problem, or understand the blank page / other issues, I prefer that you share a reproducible repository.
I can’t guess the exact state of your code, what is breaking in your process, or any specific situation in your app without that. Feel free to DM me, I’m happy to help. Anyway, I wouldn’t complicate things. I’d use Rspack’s built-in mechanism to recompile any npm package or piece of modern code instead of doing it manually with Babel or SWC.
Is there a way to separate out server and client unit tests?
How so? Do you mean that any file inside the client or server folders, at any level in the file system, should automatically run only on the client or server? I haven’t used this pattern much and I’m not sure if it ever worked, but please share more details.
Figured out the memory problem was at least partially because unit tests were including the .spec. files which is not what they used to do, which was causing it to include my app test, which then includes way too much and causes it to crash
I don’t get this, what do you mean?
How so? Do you mean that any file inside the client or server folders, at any level in the file system, should automatically run only on the client or server? I haven’t used this pattern much and I’m not sure if it ever worked, but please share more details.
So in existing meteor if I run
meteor test --driver-package meteortesting:mocha --port 3050
Then it segregates the tests into client and server. Client being ones that require the browser to be able to run.
I believe it does this just by deciding that if a test is under any /client/ folder it is a client unit test, and if it is not it is a server unit test.
I don’t get this, what do you mean?
For our existing app we have two ways to run test, the above for unit tests and
meteor test --full-app --port 3005 --settings test.settings.json --driver-package meteortesting:mocha --exclude-archs web.browser.legacy
for functional tests.
In existing meteor the .spec files are only loaded for the functional tests, not the unit tests. Loading the specs for my unit tests was causing my meteor to crash with a memory error. Not exactly sure why, but there was too much being loaded in any case.
The other thing that is broken in my repo in my last message is that if you run the functional tests. It should run a mostly normal server instance along with a client instance. In old meteor on the server Meteor.isAppTest would be set to true, in the RSPack Meteor.isAppTest is being set to false, which breaks tests.
The dummy app in this package does the same thing
I followed the docs here:
What I understand is that for unit tests, meteor test eagerly loads both .spec[s] and .test[s] files, and that’s what I implemented.
Then for full app / functional tests, the pattern is *.app-test[s].* and *.app-spec[s].*. Isn’t this what you’re getting? Or is your result different from what the official docs describe? You stated that “In existing meteor .spec files are only loaded for the functional tests” but that seems only be achieved via unit testing according to docs.
About client/server specifics, you’re right, I didn’t cover all those edge cases when using eager loaded tests (testModule at package.json achieve it). I’ll look into solutions for that using the repositories you shared for eager tests.
Also, do you know if server/client tests only apply to the conventional server/client folders, or if they also affect files within imports or any other root folders with client or server folders within? Do you have tests described outside client/server folders?
Ah you are right about the spec, the problem was more about not loading anything that was outside of client/server folders.
For my unit tests it does seem that if it is not inside of a client or server folder it won’t load the test at all.
I tried today to find where this is specified anywhere in the meteor docs and I believe it is based on this behavior Application Structure | Meteor Guide
Now I agree this kind weird and probably not what we want the expected behavior to be, but I bet there are going to be a lot of apps that are structured like my mine and this should be either the default behavior or very easy to switch to.
The Meteor.isAppTest not being true is definitely a bug and should be resolved.
I’m trying to turn off rspack hot reloading for testing purposes. Here is my relevant rspack.config.js. I have temporarily removed Meteor package hot-module-replacement as well. But, the client console logs show HMR is still being loaded. What am I missing?
rspack.config.js
devServer: {
allowedHosts: 'all',
hot: false,
liveReload: false,
webSocketServer: false,
client: {
overlay: false,
},
},
devtool: Meteor.isDevelopment ? 'eval-source-map' : false,
};
My client console logs show HMR is still being loaded:
Client Console log
[webpack-dev-server] Server started: Hot Module Replacement enabled, Live Reloading enabled, Progress disabled, Overlay disabled.
log.js:39 [HMR] Waiting for update signal from WDS...
@nachocodoner , please ignore my post about disabling HMR. It’s accurate but the only reason I was trying it was to rule out a variable involved in connecting rspack HMR to Cloudflare. I’m pretty sure now that HMR is part of an anomaly I’m encountering, and I do want it, so I’m turning it back on.


