WebAssembly

Bundle and use WebAssembly modules

WebAssembly

Packem can import and bundle .wasm modules. WebAssembly support is provided through the rollup.wasm option, which is backed by @rollup/plugin-wasm and accepts its full option set.

Overview

When enabled, .wasm files imported from your source are inlined or copied as part of the build, letting you instantiate compiled WebAssembly directly from JavaScript/TypeScript.

:::note WebAssembly modules are a supported feature of Packem (see the feature list in the package README). Support is configured via rollup.wasm. :::

Project Structure

wasm-example/
├── src/
│   ├── index.ts
│   └── add.wasm
├── package.json
├── packem.config.ts
└── tsconfig.json

Source Files

src/index.ts

// Import the compiled WebAssembly module
import addModule from './add.wasm'

export async function add(a: number, b: number): Promise<number> {
  const instance = await addModule()
  return (instance.exports.add as (a: number, b: number) => number)(a, b)
}

Configuration

Enable WebAssembly handling through the rollup.wasm option. Passing an empty object turns it on with defaults; you can pass any @rollup/plugin-wasm option (such as sync or maxFileSize).

packem.config.ts

import { defineConfig } from '@visulima/packem/config'
import transformer from '@visulima/packem/transformer/esbuild'

export default defineConfig({
  transformer,
  declaration: true,
  rollup: {
    // Enable .wasm bundling (backed by @rollup/plugin-wasm)
    wasm: {}
  }
})

Inlining Smaller Modules

import { defineConfig } from '@visulima/packem/config'
import transformer from '@visulima/packem/transformer/esbuild'

export default defineConfig({
  transformer,
  rollup: {
    wasm: {
      // Inline modules under this size; emit larger ones as separate files
      maxFileSize: 10_000,
      // Synchronously instantiate (Node-only, no async wrapper)
      sync: ['src/add.wasm']
    }
  }
})

To disable WebAssembly handling explicitly, set rollup.wasm to false.

package.json

{
  "name": "@myorg/wasm-example",
  "version": "1.0.0",
  "type": "module",
  "files": ["dist"],
  "exports": {
    ".": {
      "types": "./dist/index.d.ts",
      "import": "./dist/index.mjs"
    }
  },
  "scripts": {
    "build": "packem build"
  },
  "devDependencies": {
    "@visulima/packem": "^2"
  }
}

Build Output

$ packem build

dist/index.mjs        # JS entry, instantiates the wasm module
dist/index.d.ts       # type declarations

Notes

  • rollup.wasm accepts the full RollupWasmOptions shape from @rollup/plugin-wasm; the most common options are sync, maxFileSize, targetEnv, and publicPath.
  • Small modules can be inlined as base64 (via maxFileSize) to avoid a separate fetch; larger ones are emitted as standalone .wasm files.
  • Combine with Bundle Analysis to see how WebAssembly assets contribute to your output size.
Support

Contribute to our work and keep us going

Community is the heart of open source. The success of our packages wouldn't be possible without the incredible contributions of users, testers, and developers who collaborate with us every day.Want to get involved? Here are some tips on how you can make a meaningful impact on our open source projects.

Ready to help us out?

Be sure to check out the package's contribution guidelines first. They'll walk you through the process on how to properly submit an issue or pull request to our repositories.

Submit a pull request

Found something to improve? Fork the repo, make your changes, and open a PR. We review every contribution and provide feedback to help you get merged.

Good first issues

Simple issues suited for people new to open source development, and often a good place to start working on a package.
View good first issues