ワンクリックで
rust-wasm
Master WebAssembly with Rust - wasm-pack, wasm-bindgen, and browser integration
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Master WebAssembly with Rust - wasm-pack, wasm-bindgen, and browser integration
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
Run tiered computational quality sensors and self-correct. Use after code changes, before commits/PRs, when asked to "verify", "run gates", "quality check", or when AGENTS.md requires verification. Prefer gate:fast during iteration and gate:full before handoff.
Inferential code review sensor for this repo. Use before asking a human to review, after verify gates are green, or when asked to "review", "review changes", or "pre-review". Checks harness compliance, architecture layers, test adequacy, and agent failure modes — not a substitute for cargo/clippy/CI.
Behaviour harness for the 8 ASCII Canvas drawing tools. Use when changing tools, canvas interaction, border styles, or when AGENTS.md tool checklist applies.
Browser automation CLI for AI agents. Use when the user needs to interact with websites, including navigating pages, filling forms, clicking buttons, taking screenshots, extracting data, testing web apps, or automating any browser task. Triggers include requests to "open a website", "fill out a form", "click a button", "take a screenshot", "scrape data from a page", "test this web app", "login to a site", "automate browser actions", or any task requiring programmatic web interaction.
Guide for creating effective skills. This skill should be used when users want to create a new skill (or update an existing skill) that extends Claude's capabilities with specialized knowledge, workflows, or tool integrations.
Write clear, comprehensive technical documentation. Use when creating specs, architecture docs, runbooks, or API documentation. Handles technical specifications, system design docs, operational guides, and developer documentation with industry best practices.
| name | rust-wasm |
| description | Master WebAssembly with Rust - wasm-pack, wasm-bindgen, and browser integration |
Master WebAssembly with Rust: wasm-pack, wasm-bindgen, JavaScript interop, and browser integration.
# Install wasm-pack
cargo install wasm-pack
# Add target
rustup target add wasm32-unknown-unknown
# Create project
cargo new --lib my-wasm
cd my-wasm
# Cargo.toml
[package]
name = "my-wasm"
version = "0.1.0"
edition = "2021"
[lib]
crate-type = ["cdylib", "rlib"]
[dependencies]
wasm-bindgen = "0.2"
js-sys = "0.3"
web-sys = { version = "0.3", features = ["console", "Window", "Document"] }
[dev-dependencies]
wasm-bindgen-test = "0.3"
[profile.release]
lto = true
opt-level = "z"
// src/lib.rs
use wasm_bindgen::prelude::*;
// Import JavaScript function
#[wasm_bindgen]
extern "C" {
#[wasm_bindgen(js_namespace = console)]
fn log(s: &str);
}
// Export Rust function to JavaScript
#[wasm_bindgen]
pub fn greet(name: &str) -> String {
format!("Hello, {}!", name)
}
#[wasm_bindgen]
pub fn add(a: i32, b: i32) -> i32 {
a + b
}
// Initialize (called on load)
#[wasm_bindgen(start)]
fn main() {
log("WASM module loaded!");
}
# Build for bundlers (webpack, etc.)
wasm-pack build
# Build for web (no bundler)
wasm-pack build --target web
# Build for Node.js
wasm-pack build --target nodejs
# Build optimized
wasm-pack build --release
<!DOCTYPE html>
<html>
<head>
<script type="module">
import init, { greet, add } from './pkg/my_wasm.js';
async function run() {
await init();
const message = greet("World");
console.log(message); // "Hello, World!"
const sum = add(2, 3);
console.log(sum); // 5
}
run();
</script>
</head>
<body></body>
</html>
// index.js
import * as wasm from "my-wasm";
console.log(wasm.greet("Webpack"));
# Build and pack
wasm-pack build
cd pkg
npm link
# In JavaScript project
npm link my-wasm
use wasm_bindgen::prelude::*;
use web_sys::{Document, Element, HtmlElement, Window};
#[wasm_bindgen]
pub fn manipulate_dom() -> Result<(), JsValue> {
// Get window and document
let window = web_sys::window().unwrap();
let document = window.document().unwrap();
// Create element
let div = document.create_element("div")?;
div.set_id("my-div");
div.set_inner_html("<h1>Hello from Rust!</h1>");
// Add to body
document.body().unwrap().append_child(&div)?;
// Query selector
let element = document.query_selector("#my-div")?.unwrap();
// Add event listener
let closure = Closure::wrap(Box::new(move |_event: web_sys::MouseEvent| {
web_sys::console::log_1(&"Clicked!".into());
}) as Box<dyn FnMut(_)>);
element.add_event_listener_with_callback(
"click",
closure.as_ref().unchecked_ref()
)?;
closure.forget(); // Keep closure alive
Ok(())
}
use wasm_bindgen::prelude::*;
use wasm_bindgen_futures::JsFuture;
use web_sys::{Request, RequestInit, Response};
#[wasm_bindgen]
pub async fn fetch_data(url: &str) -> Result<JsValue, JsValue> {
let opts = RequestInit::new();
opts.set_method("GET");
let request = Request::new_with_str_and_init(url, &opts)?;
let window = web_sys::window().unwrap();
let resp_value = JsFuture::from(window.fetch_with_request(&request)).await?;
let resp: Response = resp_value.dyn_into()?;
let json = JsFuture::from(resp.json()?).await?;
Ok(json)
}
use wasm_bindgen::prelude::*;
use serde::{Deserialize, Serialize};
#[wasm_bindgen]
pub struct Point {
x: f64,
y: f64,
}
#[wasm_bindgen]
impl Point {
#[wasm_bindgen(constructor)]
pub fn new(x: f64, y: f64) -> Point {
Point { x, y }
}
#[wasm_bindgen(getter)]
pub fn x(&self) -> f64 {
self.x
}
#[wasm_bindgen(getter)]
pub fn y(&self) -> f64 {
self.y
}
pub fn distance(&self, other: &Point) -> f64 {
((self.x - other.x).powi(2) + (self.y - other.y).powi(2)).sqrt()
}
}
// For complex types, use serde
#[derive(Serialize, Deserialize)]
pub struct Config {
name: String,
values: Vec<i32>,
}
#[wasm_bindgen]
pub fn parse_config(json: &str) -> Result<JsValue, JsValue> {
let config: Config = serde_json::from_str(json)
.map_err(|e| JsValue::from_str(&e.to_string()))?;
Ok(serde_wasm_bindgen::to_value(&config)?)
}
use wasm_bindgen::prelude::*;
// Typed arrays for efficient data transfer
#[wasm_bindgen]
pub fn process_array(data: &[u8]) -> Vec<u8> {
data.iter().map(|x| x.wrapping_add(1)).collect()
}
// Zero-copy view into WASM memory
#[wasm_bindgen]
pub fn get_memory_view() -> js_sys::Uint8Array {
let buffer = vec![1u8, 2, 3, 4, 5];
// Create view into WASM memory
let array = js_sys::Uint8Array::new_with_length(buffer.len() as u32);
array.copy_from(&buffer);
array
}
// tests/web.rs
#![cfg(target_arch = "wasm32")]
use wasm_bindgen_test::*;
wasm_bindgen_test_configure!(run_in_browser);
#[wasm_bindgen_test]
fn test_add() {
assert_eq!(my_wasm::add(2, 2), 4);
}
#[wasm_bindgen_test]
fn test_greet() {
assert_eq!(my_wasm::greet("Test"), "Hello, Test!");
}
#[wasm_bindgen_test]
async fn test_async() {
// Test async functions
}
# Run tests in browser
wasm-pack test --chrome
# Run tests in Node
wasm-pack test --node
# Cargo.toml
[profile.release]
lto = true
opt-level = "z"
codegen-units = 1
panic = "abort"
# Build optimized
wasm-pack build --release
# Further optimization with wasm-opt
wasm-opt -Oz -o optimized.wasm pkg/my_wasm_bg.wasm
# Check size
ls -lh pkg/*.wasm
#[wasm_bindgen]
extern "C" {
#[wasm_bindgen(js_namespace = console)]
fn log(s: &str);
#[wasm_bindgen(js_namespace = console, js_name = log)]
fn log_many(a: &str, b: &str);
}
macro_rules! console_log {
($($t:tt)*) => (log(&format_args!($($t)*).to_string()))
}
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub fn may_fail(input: &str) -> Result<String, JsValue> {
if input.is_empty() {
return Err(JsValue::from_str("Input cannot be empty"));
}
Ok(format!("Processed: {}", input))
}
| Problem | Cause | Solution |
|---|---|---|
| Large .wasm | Debug build | Use --release |
| Import error | Wrong target | Match --target to usage |
| Memory leak | Closure not freed | Use .forget() or cleanup |
| Type mismatch | Complex types | Use serde_wasm_bindgen |
# 1. Check wasm size
wasm-pack build --release
ls -lh pkg/*.wasm
# 2. Inspect exports
wasm2wat pkg/my_wasm_bg.wasm | head -50
# 3. Browser console
# Open DevTools > Console for JS errors
# 4. Test in Node first
wasm-pack build --target nodejs
node -e "const m = require('./pkg'); console.log(m.greet('test'))"
opt-level = "z"Result<_, JsValue>