Skip to Content
Course content

213: wasm-pack Build Workflow

Click on the "Edit" button in the top corner of the screen to edit your slide content.

Think of wasm-pack like a professional catering service. You've spent hours in your kitchen (your IDE) preparing a complex, gourmet meal (your Rust logic). But there's a problem: your guest (the Web Browser) doesn't have a kitchen. They can't handle raw ingredients or heavy pots and pans; they can only eat food that's been plated, garnished, and delivered in a convenient container.

If you just used cargo build, you'd be handing the browser a raw slab of meat and some unpeeled carrots. The browser wouldn't know what to do with it. wasm-pack is the service that takes your Rust code, cooks it into WebAssembly, plates it with the necessary JavaScript "glue" so the browser knows how to call your functions, and puts it all in a neat package (an npm module) that's ready for delivery.

The Glue That Makes Rust Play Nice With JS

When you run wasm-pack build, a lot happens under the hood that would be a nightmare to do manually. First, it compiles your code to the wasm32-unknown-unknown target. But a .wasm file by itself is just a binary blob; it doesn't have a way to tell JavaScript, "Hey, I have a function called calculate_palette that takes an integer."

This is where wasm-bindgen comes in, and wasm-pack orchestrates it for you. It generates a JavaScript wrapper. This wrapper acts as the translator. When your JS code calls a function, it's actually calling the wrapper, which then handles the memory management—moving strings or arrays from JS memory into the Wasm linear memory—and then triggers the Rust logic.

Choosing Your Delivery Method

Depending on how you're building your frontend, you'll need a different "packaging" style. I usually see people get tripped up here because they try to use the default build in a project where it doesn't fit. You'll mostly deal with two targets:

  • --target web: This is for when you're just using a plain HTML file and a <script type="module">. It generates a JS file that you can import directly, and it includes an initialization function you have to call before the Wasm is ready.
  • --target bundler: This is the default. Use this if you're using Webpack, Vite, or Parcel. It assumes the bundler will handle the loading and initialization for you, making the import feel like any other npm package.

I personally prefer --target web when I'm just prototyping because it removes the need for a complex build pipeline, but for production, the bundler target is where the real power is.

What Actually Lands in the /pkg Folder

Once the build finishes, you'll see a new /pkg directory. This is the "delivery box" I mentioned earlier. Inside, you'll find:

/pkg
  ├── your_project.wasm   // The compiled binary logic
  ├── your_project.js     // The JS glue code (the translator)
  ├── your_project.d.ts   // TypeScript definitions (huge for DX!)
  └── package.json        // Makes this a valid npm package

The .d.ts file is a lifesaver. Even if you aren't writing your frontend in TypeScript, most modern editors use these files to give you autocomplete for your Rust functions inside your JavaScript files. It's a fantastic feeling to type myWasmModule. and see your Rust function signatures pop up in the dropdown.




📋 Practical Task

Building a High-Performance Color Palette Generator for NPM

Your goal is to create a Rust library that calculates a set of complementary colors based on a single hex input, then package it using wasm-pack so it could be installed via npm.

Requirements:

  • Create a new Rust library project.
  • Implement a function generate_palette(hex_color: String) -> Vec<String> that takes a hex string (e.g., "#FF5733") and returns a vector of four related colors (the original, a lighter version, a darker version, and a complementary color).
  • Ensure you use #[wasm_bindgen] on your function and the wasm-bindgen dependency in your Cargo.toml.
  • Run wasm-pack build --target web.
  • Verify that the /pkg directory contains the .wasm, .js, and .d.ts files.
  • Bonus: Create a simple index.html that imports the generated JS glue code, initializes the module, and logs the resulting palette to the console when a button is clicked.
Rating
0 0

There are no comments for now.

to be the first to leave a comment.