wasm-pack is the official tool in the Rust ecosystem for building, testing, and publishing WebAssembly packages. It simplifies the process of compiling Rust code to WebAssembly and provides convenient integration with the JavaScript ecosystem.
Introduction to wasm-pack
Main Features
- Build WebAssembly Packages: Compiles Rust code into WebAssembly and generates appropriate package formats
- JavaScript Integration: Automatically generates TypeScript type definitions and JavaScript glue code
- Publish to npm: Directly publishes WebAssembly packages as npm modules
- Development Mode: Supports hot reloading and rapid iterative development
Applicable Scenarios
- Building high-performance web application components
- Porting Rust code to the web platform
- Creating WebAssembly modules that run in browsers and Node.js
Installing wasm-pack
Prerequisites
- Rust toolchain installed (via rustup)
- Node.js and npm/yarn installed
Installation Commands
curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | shAlternatively, install using cargo:
cargo install wasm-packVerify Installation
wasm-pack --versionUsing wasm-pack
Initializing a Project
Creating a New Project
wasm-pack new my-wasm-project
cd my-wasm-projectThis creates a Rust project with a basic structure configured for building WebAssembly.
Initializing an Existing Project
For an existing Rust project, initialize wasm-pack:
wasm-pack initBuilding a Project
Development Build
wasm-pack build --dev- Generates unoptimized debug builds
- Faster compilation speed
- Includes debug information
Production Build
wasm-pack build --release- Generates optimized production builds
- Smaller file sizes
- Faster execution speed
Build Targets
Specify the target environment for the build:
# Browser environment (default)
wasm-pack build --target web
# Node.js environment
wasm-pack build --target nodejs
# For bundlers (e.g., webpack)
wasm-pack build --target bundler
# For no-pack toolchains
wasm-pack build --target no-modulesDevelopment Mode
Watch Mode
wasm-pack watch- Monitors file changes and automatically rebuilds
- Ideal for rapid iteration during development
Development Server
Use in combination with webpack-dev-server or other tools:
wasm-pack build --dev --target web
# Then run webpack-dev-server in another terminalProject Structure
Typical wasm-pack project structure:
my-wasm-project/
├── Cargo.toml # Rust project configuration
├── src/
│ ├── lib.rs # Main library file
│ └── ... # Other Rust source files
├── pkg/ # Generated WebAssembly package
│ ├── my_wasm_project_bg.wasm # WebAssembly binary
│ ├── my_wasm_project.js # JavaScript glue code
│ ├── my_wasm_project.d.ts # TypeScript type definitions
│ └── ... # Other generated files
└── ... # Other project filesConfiguration Options
Cargo.toml Configuration
Basic Configuration
[package]
name = "my-wasm-project"
version = "0.1.0"
authors = ["Your Name <your@email.com>"]
edition = "2021"
[lib]
crate-type = ["cdylib", "rlib"] # cdylib for dynamic library generationwasm-pack Specific Configuration
[package.metadata.wasm-pack.profile.release]
wasm-opt = ["-O4", "--enable-mutable-globals"] # wasm-opt optimization optionswasm-pack Configuration File
Create a wasm-pack.toml file for more detailed configuration:
[build]
target = "web" # Default build target
mode = "release" # Default build mode
[package]
# Package metadata configurationIntegration with JavaScript
Importing WebAssembly Modules
In Browsers (ES Modules)
import init, { add } from './pkg/my_wasm_project.js';
async function run() {
await init(); // Initialize WebAssembly module
console.log(add(2, 3)); // Call Rust function
}
run();In Node.js
const { add } = require('./pkg/my_wasm_project.js');
(async () => {
await init(); // Initialize WebAssembly module
console.log(add(2, 3));
})();Type Support
wasm-pack automatically generates TypeScript type definition files (*.d.ts), providing full type-checking support.
Publishing to npm
Preparing for Publication
wasm-pack publishOr specify a registry:
wasm-pack publish --registry npmjsConfiguring package.json
Ensure package.json includes correct metadata:
{
"name": "my-wasm-project",
"version": "0.1.0",
"description": "A WebAssembly project",
"main": "pkg/my_wasm_project.js",
"module": "pkg/my_wasm_project.js",
"types": "pkg/my_wasm_project.d.ts",
"files": [
"pkg/**/*"
],
"scripts": {
"build": "wasm-pack build",
"test": "wasm-pack test"
},
"devDependencies": {
"wasm-pack": "^0.10.3"
}
}Advanced Features
Testing
Unit Tests
wasm-pack test --node # Run tests in Node.js
wasm-pack test --headless --firefox # Run tests in browserWriting Tests
Create test files in the tests/ directory:
// tests/web.rs
use wasm_bindgen_test::*;
wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
#[wasm_bindgen_test]
fn test_add() {
assert_eq!(add(2, 3), 5);
}Optimization
wasm-opt Optimization
wasm-pack build --release -- --features wasm-optCustom Optimization Options
Configure in Cargo.toml:
[package.metadata.wasm-pack.profile.release]
wasm-opt = ["-O4", "--enable-mutable-globals"]Custom Glue Code
Control generated JavaScript glue code by implementing custom behavior with wasm_bindgen.
Troubleshooting Common Issues
Build Issues
Out of Memory
Increase available memory:
# Linux/macOS
export RUSTFLAGS="-C link-arg=-zstack-size=4194304"
# Windows
set RUSTFLAGS="-C link-arg=-zstack-size=4194304"Linking Errors
Ensure correct crate-type configuration:
[lib]
crate-type = ["cdylib", "rlib"]Runtime Issues
Initialization Errors
Ensure init() is called before any WebAssembly functions:
import init, { add } from './pkg/my_wasm_project.js';
async function run() {
await init(); // Must await initialization
add(2, 3); // Then call functions
}
run();Performance Issues
- Use
--releasebuild mode - Enable
wasm-optoptimization - Reduce frequent calls between Rust and JavaScript
Best Practices
- Minimize Cross-Language Calls: Reduce the number of function calls between Rust and JavaScript
- Batch Process Data: Avoid frequent WebAssembly function calls in loops
- Use Appropriate Data Types: Choose efficient data transfer methods
- Enable Optimization: Always use
--releasefor production builds - Version Control: Follow Semantic Versioning (SemVer)
- Documentation: Provide clear documentation comments for exported functions
wasm-pack is a core tool in the Rust WebAssembly development ecosystem, greatly simplifying the development process from Rust to WebAssembly, allowing developers to focus on business logic rather than the complexities of the build toolchain.



