skills/napi-rs/SKILL.md
Practical guidance for working on napi-rs bindings across Rust and TypeScript/JavaScript projects. Use this skill when creating, changing, or reviewing a project that exposes Rust functionality to Node.js, TypeScript, or JavaScript through `napi-rs`.
npx skillsauth add liangmiQwQ/skills napi-rsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
#[napi]; JavaScript files often wrap, patch, or select native/WASI/browser entrypoints..d.ts, JS wrappers, package tests, and docs together.crates/core-* for Rust logic, napi/<package> or packages/<package> for NAPI crates/npm packages, and optional crates/*_napi or crates/node_bridge for shared bridge helpers.src/lib.rs for NAPI exports, package.json for npm metadata and napi config, index.js for wrappers, index.d.ts or generated definitions for TypeScript, and test/ for JS-level tests.Avoid editing generated files unless the task is specifically to update generated artifacts.
#[napi] for exported functions, classes, Task impls, and string enums.#[napi(object)] for plain JS option/result objects.#[napi(object, use_nullable = true)] when TypeScript should see nullable fields for Option<T> rather than only optional-like fields.#[napi(string_enum)] for JavaScript string enums.#[napi(ts_type = "...")] for fields whose generated type should be narrower or clearer than the Rust type.#[napi(ts_return_type = "...")] for getters/functions that return serialized data but should appear as richer TypeScript types, such as ESTree Program.#[napi(js_name = "...")] when the JS API name differs from Rust naming.#[napi(skip_typescript)] for low-level or internally wrapped exports that should not appear in public .d.ts.Option<T> for optional JS inputs, then apply Rust defaults at the boundary before calling core crates.From/TryFrom conversions from NAPI option structs into internal Rust option structs.napi::Either<A, B> for JS union inputs like boolean | object, string | string[], or string | Options.Record<string, string>.Example boundary shape:
#[napi(object)]
#[derive(Default)]
pub struct BindingOptions {
#[napi(ts_type = "'compact' | 'pretty'")]
pub format: Option<String>,
pub include_metadata: Option<bool>,
}
let include_metadata = options.include_metadata.unwrap_or(false);
mem::take to avoid cloning.Strings in the task and use mem::take or Option::take when moving them into compute work.#[napi(object)] return values for small and medium results where clarity matters more than transfer overhead.Buffer, Uint8Array, JSON strings, or custom binary formats when result construction dominates runtime.skip_typescript when they are implementation details behind JS wrappers.cfg checks. Do not assume pointer width, endianness, allocator behavior, or WASM compatibility.napi::Task plus AsyncTask when Rust compute can run off-thread.compute must not touch JS values. It should consume owned Rust data and return owned Rust output.resolve converts the Rust output into the JS-visible value.AsyncTask.package.json napi section for binaryName, packageName, targets, and WASI/browser settings.napi build or napi build --esm --platform; release builds may add --release and feature flags.postbuild-dev often runs node scripts/patch.js; inspect it before changing generated import paths, wrapper exports, or .d.ts assumptions.browser.js, wasm.js, wasi-worker*.mjs, *.wasi.cjs, and webcontainer-fallback.cjs.Use the narrowest command that covers the changed package:
cargo test -p <rust-crate>
pnpm --filter <npm-package> build
pnpm --filter <npm-package> test
npm run build
npm test
For shared bridge or broad package changes:
cargo test
cargo clippy --all-targets
cargo fmt --all --check
pnpm test
pnpm typecheck
If public TypeScript shapes change, inspect generated .d.ts files and update JS/TS tests under the affected package's test/ directory. If the project has browser/WASI support, run those tests separately because native Node tests do not cover wrapper selection.
compute..d.ts entrypoints still agree.development
High-fidelity HTML design and prototype creation. Use this skill whenever the user asks to design, prototype, mock up, or build visual artifacts in HTML — including slide decks, interactive prototypes, landing pages, UI mockups, animations, or any visual design work. Also use when the user mentions Figma, design systems, UI kits, wireframes, presentations, or wants to explore visual design directions. Even if they just say "make it look good" or "design a screen for X", this skill applies.
development
High-fidelity HTML design and prototype creation. Use this skill whenever the user asks to design, prototype, mock up, or build visual artifacts in HTML — including slide decks, interactive prototypes, landing pages, UI mockups, animations, or any visual design work. Also use when the user mentions Figma, design systems, UI kits, wireframes, presentations, or wants to explore visual design directions. Even if they just say "make it look good" or "design a screen for X", this skill applies.
development
Load this skill when Codex needs to locate, enter, clone, open, or coordinate work across the user's local projects. Use it when the current directory is not the target project, when another local project is needed, or when multiple projects are involved. The user's standard is rootPath/github-owner/repo, managed by mo.
tools
Load this skill before creating, drafting, modifying, or submitting PR on GitHub