New 3.4-beta.6 Release, Faster Builds, Smaller Bundles and Modern Setups with the Rspack integration ⚡

Hello everyone!

I’m excited to announce that the first beta of the Meteor-Rspack integration is now live.

This release marks the first step toward stabilizing and consolidating a modern bundler approach with Meteor, combining the strengths of both. With it, your app can benefit from features like tree shaking, full ESM support, secure code, modern plugins, and more.

I encourage everyone to check the new docs on the modern build stack. It’s now split into two steps: first, enabling Meteor Bundler optimizations from Meteor 3.3 with SWC, and second, adding Rspack integration for extra speed and new bundler features coming in Meteor 3.4. Both are opt-in, so if you prefer the legacy Meteor bundler, you can keep that configuration.

Highlights

Faster Build times

Meteor 3.4 goes further than Meteor 3.3 and the initial SWC adoption. With Rspack now compiling your app code, you get the speed of this modern tool built in Rust. The Meteor bundler still compiles Atmosphere packages and links the final app code, but that part was already optimized in Meteor 3.3, so you get the best of both.

With meteor profile, build times drop 75.4% and are over 4x faster. Client rebuilds now only run Rspack with the new dev server and HMR, cutting refresh time by about 96% (27x faster). Rebuild times for both client and server are now much shorter, making development far quicker.

Smaller Bundle sizes

Meteor 3.4 introduces one of the most awaited features to keep app bundles small: tree shaking. With the Meteor-Rspack integration, bundle size is significantly reduced through this built-in optimization.

After deploying fredmaiaarantes/simpletasks to a private instance on Galaxy Cloud, the client bundle size dropped by about 50% compared to previous 3.3.1 release. Client bundles are now thinner, meaning less code delivered and faster initial load times for your apps.

Extend your app with Modern Setups

Meteor 3.4 introduces Rspack as the modern bundler for your app code. With it, you can configure any modern setup from the community.

With 3.4 we remove past limits like using ESM packages, adopting React Router v7, building Vue or Solid apps, setting up advanced aliasing, full-featured systems like i18n with lingui, integrating bundle visualizers, and using modern Rspack plugins or existing Webpack plugins. Check out Rspack docs and Webpack articles online. Anything compatible with these tools can be integrated into your app.

We encourage you to try it out and share the benefits you discover.

Hands on

To update an existing app:

meteor update --release 3.4-beta.6

To create a new app:

meteor create --release 3.4-beta.6

Add modern to your package.json to enable the Meteor Bundler optimizations:

"meteor": {
  "modern": true
}

This setting is on by default for new apps.

Check out the requirements for Meteor Bundler optimizations on existing apps.

Add rspack package to enable the Rspack Bundler integration:

meteor add rspack@1.0.0-beta340.3

This package is added by default for new apps.

Check out the requirements for Rspack Bundler integration on existing apps.

Migration

New apps will use the skeleton of existing Meteor projects, already set up with the modern build stack with Meteor bundler optimizations and Rspack integration. This provides a base for new projects, testing and understanding the setup. You can create new apps with:

meteor create --release 3.4-beta.6 --[template]

Available templates include react, solid, svelte, vue, tailwind, and others you can check with --help.

For those who want to adapt an existing app, check the docs. They explain in detail the requirements and migration steps depending on your setup and the technologies used in your app.

:page_with_curl: Modern Build Stack docs

:comet: Meteor Bundler optimizations docs

:zap: Rspack Bundler integration docs

Please note the Meteor Rspack integration is still in progress and in beta, so keep app stability in mind.

You can experiment, adapt your app, and deploy to staging. I don’t recommend production yet. If you do, keep it low risk and help us verify it… We need a full phase of testing and migrations across different app setups to ensure proper migrations. We need your help to spot any missing pieces.

Please help us with this and stay positive. We are working hard to bring a new era to Meteor, and these efforts take both determination and patience.

Feedback

Your feedback is crucial in adjusting this beta before the official launch. Community testing is key to ensuring Meteor 3.4 and the Rspack integration is stable and flexible.

You can use this thread to ask questions.

You can also check the existing Meteor-Rspack integration forum post for more details and to share your feedback. The post will also serve as a place to add insights on the integration and explain further options and ways it can be used.

What’s Next?

Mainly to address feedback for the Meteor 3.4 release. We will publish as many betas as needed to ensure stability, extensibility, contributions, and proper testing before the official release.

  • Meteor 3.4 Betas – Coming Soon
    • Work is in progress, with focus on feedback and issue resolution.
    • First beta: 3.4-beta.6 :hourglass: (Focus: Stability)
      Introduces Meteor-Rspack integration across all skeletons. It delivers long-requested features and fixes, but limits changes to Rspack only. This keeps the scope small and avoids shifting focus away from the new bundler.
    • Second beta: 3.4-beta.y :hourglass: (Focus: Extensibility)
      Expands Rspack integration to more project setups and configs, especially for Meteor-specific behaviors without direct Rspack equivalents. Real-world bundler use will be reviewed, with modern or fallback configs provided as needed.
    • Third beta: 3.4-beta.z :hourglass: (Focus: Contributions)
      Adds fixes and improvements to Rspack integration and introduces other 3.4 features, including dev-only packages and community contributions.
    • First release candidate: 3.4-rc.x :hourglass:
      Focuses on stability fixes. If stable, it will become the final 3.4 release.
  • Meteor 3.4 – On the Horizon
  • Meteor 3.5 – Beyond
4 Likes

Awesome. Since v3.3 I started to feel that im working with a modern framework again, this takes it a step further. Just awesome. Great work @nachocodoner and meteor team.

4 Likes

Can’t wait to build something quick and maybe a real reason to update some older apps to Meteor 3.

While this is still in beta you could rename meteor: { modern: true } to something like meteor: { rspack: true }. That way a future build flag wouldn’t have to named moreModern.

1 Like

meteor: { modern: true } relates to Meteor’s bundler optimizations, not Rspack. Rspack integration depends on adding the rspack package, not modern setting. The modern option was created only for the Meteor perspective, to speed up its own bundler when processing apps, packages and other CLI processing.

Let me know how your experiments with Meteor-Rspack go, and if you get any feedback to improve it for the official version.

Some initial observations:

Something wrong with the certificate of this website.

It seems that I can no longer import /from/folder when I want to assume the index.js inside the folder and also I need to add .js extensions for all imports in the project.

The certificate issue is out of my action scope. For betas, we can live with it for now.


@paulishca: Regarding strict extension usage, I tried to reproduce it in a small app and couldn’t. I set "type": "module" in package.json but ran into other errors. I’d like a consistent repoduce it so I can provide a direct fix.

Also, can you try this in your rspack.config.js?

export default defineConfig(Meteor => {
  return {
    module: {
      rules: [
        {
          test: /\.m?js$/,
          resolve: { fullySpecified: false }, // allow extensionless ESM imports
        },
      ],
    },
  };
});

If that turns out to fix your setup, I’ll make it the default. It would help to know how to configure my app to make this error appear. Could you provide a minimal repository?

First try. I have this error. @sw/helpers is installed.

[Transpiler] Used SWC for socket-stream-client/node.js                      (package)                          🟢 Cache hit (os.linux.x86_64)
[Transpiler] Used SWC for socket-stream-client/common.js                    (package)                          🟢 Cache hit (os.linux.x86_64)
[Transpiler] Used SWC for socket-stream-client/urls.js                      (package)                          🟢 Cache hit (os.linux.x86_64)
[Transpiler] Used SWC for ecmascript/ecmascript.js                          (package)                          🟢 Cache hit (os.linux.x86_64)
=> Linted your app. No linting errors.        
W20250909-12:05:38.530(2)? (STDERR) packages/core-runtime.js:189
W20250909-12:05:38.530(2)? (STDERR)             throw error;
W20250909-12:05:38.530(2)? (STDERR)             ^
W20250909-12:05:38.530(2)? (STDERR) 
W20250909-12:05:38.531(2)? (STDERR) Error: Cannot find module '@swc/helpers/_/_async_generator_delegate'
W20250909-12:05:38.531(2)? (STDERR)     at makeMissingError (packages/modules-runtime.js:221:12)
W20250909-12:05:38.531(2)? (STDERR)     at Module.require (packages/modules-runtime.js:240:17)
W20250909-12:05:38.531(2)? (STDERR)     at Module.mod.require (/home/harry/.meteor/packages/modules/.0.20.3.13guc6xon0l++os+web.browser+web.browser.legacy+web.cordova/npm/node_modules/@meteorjs/reify/lib/runtime/index.js:30:33)
W20250909-12:05:38.531(2)? (STDERR)     at Module.moduleLink [as link] (/home/harry/.meteor/packages/modules/.0.20.3.13guc6xon0l++os+web.browser+web.browser.legacy+web.cordova/npm/node_modules/@meteorjs/reify/lib/runtime/index.js:102:22)
W20250909-12:05:38.532(2)? (STDERR)     at module.wrapAsync.self (/home/harry/Dev/VueGPX/.meteor/local/build/programs/server/app/app.js:121:144)
W20250909-12:05:38.532(2)? (STDERR)     at Module.wrapAsync (/home/harry/.meteor/packages/modules/.0.20.3.13guc6xon0l++os+web.browser+web.browser.legacy+web.cordova/npm/node_modules/@meteorjs/reify/lib/runtime/index.js:252:8)
W20250909-12:05:38.532(2)? (STDERR)     at module (/home/harry/Dev/VueGPX/.meteor/local/build/programs/server/app/app.js:121:9)
W20250909-12:05:38.532(2)? (STDERR)     at fileEvaluate (packages/modules-runtime.js:335:7)
W20250909-12:05:38.532(2)? (STDERR)     at Module.require (packages/modules-runtime.js:237:14)
W20250909-12:05:38.532(2)? (STDERR)     at Module.mod.require (/home/harry/.meteor/packages/modules/.0.20.3.13guc6xon0l++os+web.browser+web.browser.legacy+web.cordova/npm/node_modules/@meteorjs/reify/lib/runtime/index.js:30:33)
W20250909-12:05:38.533(2)? (STDERR)     at Module.moduleLink [as link] (/home/harry/.meteor/packages/modules/.0.20.3.13guc6xon0l++os+web.browser+web.browser.legacy+web.cordova/npm/node_modules/@meteorjs/reify/lib/runtime/index.js:102:22)
W20250909-12:05:38.533(2)? (STDERR)     at module.wrapAsync.self (_build/main-dev/server-meteor.js:1:1)
W20250909-12:05:38.533(2)? (STDERR)     at Module.wrapAsync (/home/harry/.meteor/packages/modules/.0.20.3.13guc6xon0l++os+web.browser+web.browser.legacy+web.cordova/npm/node_modules/@meteorjs/reify/lib/runtime/index.js:252:8)
W20250909-12:05:38.533(2)? (STDERR)     at module (_build/main-dev/server-meteor.js:1:1)
W20250909-12:05:38.533(2)? (STDERR)     at fileEvaluate (packages/modules-runtime.js:335:7)
W20250909-12:05:38.533(2)? (STDERR)     at Module.require (packages/modules-runtime.js:237:14)
W20250909-12:05:38.533(2)? (STDERR) 
W20250909-12:05:38.533(2)? (STDERR) Node.js v22.18.0

Could you check if this solves it for you? Adding "externalHelpers": false at .swcrc as showed in the other post.

I am trying to debug this problem, but it’s hard to get the same problem on Meteor checkout, I will need to debug on published versions.

Sorry, I missed this post. Thanks, it fixes it.

my project starts. Now, will look at vue support (Vue - Rspack)

I’ve deployed a few stability betas, the latest is 3.4-beta.6. This release fixes an issue where the published and checkout versions of Meteor 3.4 behaved differently, including how project files were handled for compilation. That mismatch caused problems like the @swc/helpers reports and others, and likely RAM-related instability.

@pmogollon, @harry73, @schlaegerz: the errors with '@swc/helpers/_/_async_generator_delegate' and related should be gone. You no longer need to set "externalHelpers": false in .swcrc. Can you confirm?

I’ll move on to other issues as soon as I have reproductions. As I test existing repos and apps, I’ll ship more fixes as well.

2 Likes

Perfect. I can confirm beta.6 fixes the issue when removing the externalHelpers setting.

Thanks.

2 Likes

:+1: beta.6 fixes it

Thanks.

I have the following error:


[Rspack Client] [client-rspack]:package ...  /
  ERROR in ./node_modules/@firebase/database-compat/dist/index.standalone.js 5:25-32
    × Module not found: Can't resolve 'util' in '/home/Dev/VueGPX/node_modules/@firebase/database-compat/dist'
     ╭─[5:17]
   3 │ Object.defineProperty(exports, '__esModule', { value: true });
   4 │ 
   5 │ var require$$2 = require('util');
     ·                  ───────────────
   6 │ var require$$0 = require('buffer');
   7 │ var require$$1 = require('events');
     ╰────

My original rspack.config.js is:


import { defineConfig } from '@meteorjs/rspack';
import { VueLoaderPlugin } from 'vue-loader';

export default defineConfig(Meteor => {
  return {
    ...(Meteor.isClient && {
      module: {
        rules: [
          {
            test: /\.vue$/,
            loader: 'vue-loader',
            options: {
              // Note, for the majority of features to be available, make sure this option is `true`
              experimentalInlineMatchResource: true,
            },
          },
          {
            test: /\.(sass|scss)$/,
            use: [
              {
                loader: 'sass-loader',
                options: {
                  // using `modern-compiler` and `sass-embedded` together significantly improve build performance,
                  // requires `sass-loader >= 14.2.1`
                  api: 'modern-compiler',
                  implementation: 'sass-embedded',
                },
              },
            ],
            // set to 'css/auto' if you want to support '*.module.(scss|sass)' as CSS Modules, otherwise set type to 'css'
            type: 'css/auto',
          },
          { test: /\.css$/, use: ['postcss-loader'], type: 'css' },
        ],
      },
      plugins: [new VueLoaderPlugin()],
    }),

    resolve: {
      alias: {
        '@ui': '/imports/ui',
        '@api': '/imports/api',
        '@plugins': '/imports/plugins',
        '@server': '/server',
        '@client': '/client',
        '@packages': '/packages',
        '@tests': '/tests',
        '@public': '/public',
        '@private': '/private',
      },
    },
  };
});

and the one built by Meteor:

[Rspack Client] Config: {
  name: '[client-rspack]',
  target: 'web',
  mode: 'development',
  entry: '/home/Dev/VueGPX/_build/main-dev/client-entry.js',
  output: {
    path: '/home/Dev/VueGPX/public',
    filename: [Function: filename],
    libraryTarget: 'commonjs',
    publicPath: '/',
    chunkFilename: 'build-chunks/[id].js',
    assetModuleFilename: 'build-assets/[hash][ext][query]',
    cssFilename: 'build-chunks/[name].css',
    cssChunkFilename: 'build-chunks/[id].css'
  },
  optimization: { usedExports: true, splitChunks: { chunks: 'async' } },
  module: {
    rules: [
      {
        test: /\.(?:[mc]?js|jsx|[mc]?ts|tsx)$/i,
        exclude: /node_modules|\.meteor\/local/,
        loader: 'builtin:swc-loader',
        options: {
          jsc: {
            baseUrl: '/home/Dev/VueGPX',
            paths: {
              '/*': [ '*', '*' ],
              '@api/*': [ 'imports/api/*' ],
              '@ui/*': [ 'imports/ui/*' ],
              '@plugins/*': [ 'imports/plugins/*' ],
              '@server/*': [ 'server/*' ],
              '@client/*': [ 'client/*' ],
              '@packages/*': [ 'packages/*' ],
              '@tests/*': [ 'tests/*' ],
              '@public/*': [ 'public/*' ],
              '@private/*': [ 'private/*' ]
            },
            parser: { syntax: 'ecmascript' },
            target: 'es2015',
            transform: { react: { development: true, refresh: true } },
            externalHelpers: true
          }
        }
      },
      {
        test: /\.vue$/,
        loader: 'vue-loader',
        options: { experimentalInlineMatchResource: true }
      },
      {
        test: /\.(sass|scss)$/,
        use: [
          {
            loader: 'sass-loader',
            options: { api: 'modern-compiler', implementation: 'sass-embedded' }
          }
        ],
        type: 'css/auto'
      },
      { test: /\.css$/, use: [ 'postcss-loader' ], type: 'css' }
    ]
  },
  resolve: {
    extensions: [
      '.ts',   '.tsx',
      '.mts',  '.cts',
      '.js',   '.jsx',
      '.mjs',  '.cjs',
      '.json', '.wasm'
    ],
    alias: {
      '/': '/home/Dev/VueGPX',
      '@ui': '/imports/ui',
      '@api': '/imports/api',
      '@plugins': '/imports/plugins',
      '@server': '/server',
      '@client': '/client',
      '@packages': '/packages',
      '@tests': '/tests',
      '@public': '/public',
      '@private': '/private'
    }
  },
  externals: [ /^meteor.*/ ],
  plugins: [
    RequireExternalsPlugin {
      pluginName: 'RequireExternalsPlugin',
      _externals: null,
      _externalMap: null,
      _enableGlobalPolyfill: true,
      _isEagerImport: null,
      _lastImports: null,
      _defaultExternalPrefix: 'external ',
      filePath: '/home/Dev/VueGPX/_build/main-dev/client-meteor.js',
      backRoot: '../../',
      _funcCount: 1
    },
    DefinePlugin {
      affectedHooks: 'compilation',
      name: 'DefinePlugin',
      _args: [
        {
          'Meteor.isClient': 'true',
          'Meteor.isServer': 'false',
          'Meteor.isTest': 'false',
          'Meteor.isAppTest': 'false',
          'Meteor.isDevelopment': 'true',
          'Meteor.isProduction': 'false'
        }
      ]
    },
    BannerPlugin {
      affectedHooks: undefined,
      name: 'BannerPlugin',
      _args: [
        {
          banner: '/**\n' +
            '* @file client-rspack.js\n' +
            '* @description Bundled output generated by Rspack\n' +
            '* --------------------------------------------------------------------------\n' +
            '* ⚡ Rspack Client App (Development)\n' +
            '* --------------------------------------------------------------------------\n' +
            '* • [   client-entry.js ] ──▶ [■ client-rspack.js ] ──▶ [   client-meteor.js ]\n' +
            '*\n' +
            '* This file is the bundled output generated by Rspack.\n' +
            '* It contains all application code and assets combined into one build.\n' +
            '* It is not used directly, but will be imported by the Meteor main module\n' +
            '* file (`client-meteor.js`) so that Meteor runs the Rspack bundle.\n' +
            '*\n' +
            '* ⚠️ Note: This file is autogenerated. It is not meant to be modified manually.\n' +
            '* These files also act as a cache: they can be safely removed and will be\n' +
            '* regenerated on the next build. They should be ignored in IDE suggestions\n' +
            '* and version control.\n' +
            '*/\n' +
            '\n' +
            '/* No code generated as served by HMR server */\n',
          entryOnly: true
        }
      ]
    },
    HtmlRspackPlugin {
      options: {
        inject: false,
        cache: true,
        filename: '../_build/main-dev/index.html',
        templateContent: '\n' +
          '          <head>\n' +
          '            <% for tag in htmlRspackPlugin.tags.headTags { %>\n' +
          '              <%= toHtml(tag) %>\n' +
          '            <% } %>\n' +
          '          </head>\n' +
          '          <body>\n' +
          '            <% for tag in htmlRspackPlugin.tags.bodyTags { %>\n' +
          '              <%= toHtml(tag) %>\n' +
          '            <% } %>\n' +
          '          </body>\n' +
          '        '
      }
    },
    Plugin {}
  ],
  watchOptions: { ignored: [ '**/.meteor/local/**', '**/dist/**' ] },
  devtool: 'source-map',
  devServer: {
    static: {
      directory: '/home/Dev/VueGPX/public',
      publicPath: '/__rspack__/'
    },
    hot: true,
    liveReload: true,
    port: '8080',
    devMiddleware: { writeToDisk: [Function: writeToDisk] }
  },
  experiments: { css: true }
}

[Rspack Server] [server-rspack]:package ...  -
  [server-rspack] compiled successfully in 686 ms

[Rspack Client] <i> [webpack-dev-server] Project is running at:

[Rspack Client] <i> [webpack-dev-server] Loopback: http://localhost:8080/, http://[::1]:8080/
<i> [webpack-dev-server] On Your Network (IPv4): http://192.168.1.45:8080/
<i> [webpack-dev-server] Content not from webpack is served from '/home/Dev/VueGPX/public' directory