wasm-pack is a Rust CLI tool that's supposed to make compiling Rust to WebAssembly easy. The good news: it usually works. The bad news: when it doesn't work, you'll spend hours figuring out why your perfectly fine Rust code won't compile to WASM.
Originally built by the Rust and WebAssembly Working Group, which got archived in August 2025 with zero warning, leaving maintainers scrambling to figure out what the hell happened. Now it's maintained by @drager, who took over when rustwasm went dark.
The tool handles the tedious parts: generating JavaScript bindings, optimizing WASM binaries, and creating npm packages. Without it, you'd be manually configuring wasm-bindgen, fighting with wasm-opt, and probably giving up.
How It Actually Works (When It Works)
wasm-pack wraps a bunch of other tools and prays they all work together. It runs cargo build
to compile your Rust, uses wasm-bindgen to generate JavaScript glue code, optimizes everything with wasm-opt, and spits out an npm package.
The wasm-pack build
command is what you'll use 99% of the time. It creates a pkg/
directory with:
- A
.wasm
file (hopefully smaller than 10MB) - JavaScript bindings that somehow work
- TypeScript definitions (wrong about half the time)
- A
package.json
you can actually publish
When everything lines up, it's beautiful. When it goes wrong, you get cryptic bullshit like "could not compile wasm-bindgen-cli" that sends you down a 3-hour rabbit hole checking versions and clearing cache dirs.
Current Status: Barely Maintained
As of August 2025, we're on version 0.13.1 from October 2024. That's right - no releases for almost a year. The tool requires Rust 1.30.0+ (which is ancient by Rust standards).
The docs are mostly broken since the rustwasm shutdown. The official book returns 404s, so good luck finding help. You're basically on your own with Stack Overflow and GitHub issues.
Performance Reality Check
Let's be honest about performance:
- "Optimization" usually means your 100-line Rust function becomes a 2MB WASM file
- Bundle sizes are massive compared to equivalent JavaScript
- Startup time includes loading and instantiating WASM, which isn't free
- The generated bindings add overhead for every function call
wasm-opt helps, but don't expect miracles. Your "optimized" hello world will still be larger than most JavaScript libraries. Use wee_alloc if you want to shave off a few KB.
Integration Hell
Getting wasm-pack output to work with modern JavaScript tooling is... interesting.
Webpack: Requires specific configuration and experimental features. Hot reloading? Forget about it.
Vite: Works better with vite-plugin-wasm-pack, but you'll still fight with import paths.
Node.js: Use --target nodejs
and pray your dependencies don't break.
The generated TypeScript types are usually wrong, so you'll end up using any
everywhere or writing your own declarations.
When wasm-pack Screws You
Common ways this thing breaks:
Build failures: "could not compile wasm-bindgen-cli" means your versions are mismatched. Delete everything and start over.
Target issues: Forgot to install
wasm32-unknown-unknown
? You're getting cryptic errors.Proxy problems: Corporate networks will break the installer. Download binaries manually.
Version hell: Your local wasm-bindgen version doesn't match the crate version. Welcome to dependency hell.
Platform differences: Works on Linux, breaks on Windows, acts weird on macOS. Classic Rust ecosystem behavior.
The tool assumes everything is configured perfectly. When it's not, you're on your own.