node-ffi-rust
Build high-performance native modules for Node.js using Rust and N-API via napi-rs. Use when optimizing compute-intensive operations, integrating system libraries, or requiring native performance without blocking the event loop.
Best use case
node-ffi-rust is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
Build high-performance native modules for Node.js using Rust and N-API via napi-rs. Use when optimizing compute-intensive operations, integrating system libraries, or requiring native performance without blocking the event loop.
Teams using node-ffi-rust should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/node-ffi-rust/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How node-ffi-rust Compares
| Feature / Agent | node-ffi-rust | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
Build high-performance native modules for Node.js using Rust and N-API via napi-rs. Use when optimizing compute-intensive operations, integrating system libraries, or requiring native performance without blocking the event loop.
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# Node.js FFI Rust Skill
Build native extensions for Node.js using Rust with N-API bindings via napi-rs.
## When to Use
- **CPU-intensive operations**: Crypto, compression, math, image processing
- **System integration**: OS-level operations, hardware access
- **Large data processing**: Batch operations on buffers/arrays
- **Legacy libraries**: Wrap existing Rust/C libraries
- **Event loop safety**: Offload blocking work without freezing the server
## Quick Start
### 1. Create Project
```bash
cargo new --lib my-native-module
cd my-native-module
```
### 2. Add napi-rs
```toml
[package]
name = "my_native_module"
version = "0.1.0"
edition = "2021"
[dependencies]
napi = { version = "2", features = ["napi8"] }
napi-derive = "2"
[lib]
crate-type = ["cdylib"]
```
### 3. Write Rust Function
```rust
use napi_derive::napi;
#[napi]
pub fn add(a: i32, b: i32) -> i32 {
a + b
}
#[napi]
pub fn process_buffer(data: Vec<u8>) -> Vec<u8> {
data.iter().map(|b| b.wrapping_add(1)).collect()
}
```
### 4. Build
```bash
npm install -g @napi-rs/cli
napi build --release
```
### 5. Use in Node.js
```js
const { add, processBuffer } = require('./index.node');
console.log(add(2, 3)); // 5
console.log(processBuffer([1,2,3])); // [2,3,4]
```
## Architecture
```
JS → V8 → N-API → Rust → N-API → V8 → JS
```
Rust runs at native speed. N-API handles type conversion and memory safety.
## Performance Considerations
### Boundary Overhead
- **Cost**: 100-300 nanoseconds per call
- **Dominates**: Tiny functions called repeatedly
- **Solution**: Batch operations
### Serialization Cost
- **JSON**: Very expensive (parse/stringify)
- **TypedArray**: Zero-copy (direct memory mapping)
- **Buffers**: Efficient (single allocation)
### Rule of Thumb
**If work per call > boundary cost → native wins**
## Critical Edge Cases
See [references/EDGE_CASES.md](references/EDGE_CASES.md) for:
- Panic safety (catch_unwind required)
- Event loop blocking (use napi::Task)
- Buffer ownership (references vs copies)
- Async callbacks (thread safety)
- Cross-platform builds (prebuilt binaries)
- Struct layout (repr(C) for ABI stability)
## Best Practices
1. **Use napi-rs** — Safer than raw N-API, better DX
2. **Design around buffers** — TypedArray/Buffer, not JS objects
3. **Batch operations** — Process entire datasets, not row-by-row
4. **Avoid event loop blocking** — Use `napi::Task` for CPU work
5. **Wrap panics** — `std::panic::catch_unwind()` always
6. **Reuse buffers** — Minimize allocations
7. **Version APIs** — Struct layouts are ABI contracts
## Optimization Checklist
- [ ] Minimize JS ↔ Rust calls
- [ ] Avoid JSON serialization
- [ ] Use TypedArray/Buffer
- [ ] Batch operations
- [ ] No event loop blocking
- [ ] Panics wrapped safely
- [ ] Boundary overhead benchmarked
- [ ] Prebuilt binaries available
- [ ] No JS references held across threads
- [ ] Buffers reused where possible
## Example: Batch Array Processing
**Rust** (`src/lib.rs`):
```rust
use napi_derive::napi;
#[napi]
pub fn sum_array(data: Vec<u32>) -> u32 {
data.iter().sum()
}
#[napi]
pub fn process_batch(data: Vec<u8>, key: u8) -> Vec<u8> {
data.iter().map(|b| b ^ key).collect()
}
```
**Node.js** (`index.js`):
```js
const { sumArray, processBatch } = require('./index.node');
const data = new Uint32Array([1, 2, 3, 4, 5]);
console.log(sumArray(Array.from(data))); // 15
const buffer = Buffer.from([72, 101, 108, 108, 111]);
console.log(processBatch(buffer, 42)); // XOR encrypted
```
This avoids 5 separate JS→Rust calls and processes data once.
## Mental Model
Think of FFI as a **toll booth between two countries**.
- **Many tiny cars** (frequent small calls) → toll booth dominates
- **One giant truck** (batch operation) → efficient trip
This predicts nearly every FFI performance problem.
## See Also
- [Complete SDK Reference](references/COMPLETE_SDK_REFERENCE.md)
- [Rust Documentation](https://doc.rust-lang.org/)
- [napi-rs Docs](https://napi.rs/)
- [Node.js N-API](https://nodejs.org/api/n_api.html)Related Skills
rust-best-practices
Guide for writing idiomatic Rust code based on Apollo GraphQL's best practices handbook. Use this skill when: (1) writing new Rust code or functions, (2) reviewing or refactoring existing Rust code, (3) deciding between borrowing vs cloning or ownership patterns, (4) implementing error handling with Result types, (5) optimizing Rust code for performance, (6) writing tests or documentation for Rust projects.
rust-async-patterns
Master Rust async programming with Tokio, async traits, error handling, and concurrent patterns. Use when building async Rust applications, implementing concurrent systems, or debugging async code.
nodejs-core
Debugs native module crashes, optimizes V8 performance, configures node-gyp builds, writes N-API/node-addon-api bindings, and diagnoses libuv event loop issues in Node.js. Use when working with C++ addons, native modules, binding.gyp, node-gyp errors, segfaults, memory leaks in native code, V8 optimization/deoptimization, libuv thread pool tuning, N-API or NAN bindings, build system failures, or any Node.js internals below the JavaScript layer.
node
Provides domain-specific best practices for Node.js development with TypeScript, covering type stripping, async patterns, error handling, streams, modules, testing, performance, caching, logging, and more. Use when setting up Node.js projects with native TypeScript support, configuring type stripping (--experimental-strip-types), writing Node 22+ TypeScript without a build step, or when the user mentions 'native TypeScript in Node', 'strip types', 'Node 22 TypeScript', '.ts files without compilation', 'ts-node alternative', or needs guidance on error handling, graceful shutdown, flaky tests, profiling, or environment configuration in Node.js. Helps configure tsconfig.json for type stripping, set up package.json scripts, handle module resolution and import extensions, and apply robust patterns across the full Node.js stack.
Goal: Build an LLM-based RAG App
Here is the MVP Implementation Plan.
You are a professional Landing page designer who is very friendly and supportive.
Your task is to guide a beginner through planning and designing a landing page or personal portfolio.
You are a professional Chief Marketing Officer. Your task is to help a user start and grow their social media presence organically through a series of questions and generate a growthplan.md blueprint.
Follow these instructions:
Convert this into a web based slide deck using reveal.js.
Use the following brand colour and logo.
technical-article-writer
Write compelling technical articles and blog posts for developer audiences. Use this skill whenever the user asks to write a blog post, technical article, or any long-form technical content. Also trigger when the user says 'write about [technical topic]', 'help me draft an article', 'turn this into a blog post', 'write a post about', 'I want to publish something about', or mentions writing for a developer audience. Covers the full pipeline: idea sharpening, hook/title generation, article structure, body drafting, and editing. Even if the user just says 'I want to write about X' without specifying format, use this skill. Do NOT use for platform-specific optimization, newsletter strategy, or ghostwriting voice matching.
substack-ghostwriting
Write, optimize, and grow Substack content — both newsletter issues (email-first) and web posts (web-first articles/essays). Covers ghostwriting with voice matching, Substack algorithm optimization, Notes strategy, email formatting, SEO, growth tactics, and monetization planning. Use when the user mentions Substack, newsletters, write a newsletter issue, Substack post, Substack article, web post on Substack, evergreen content, SEO for Substack, newsletter growth, Notes strategy, ghostwrite for, match someone's voice, write in the style of, newsletter monetization, paid subscribers, or any task involving Substack as a platform. Also trigger for general article/newsletter writing even if Substack isn't named explicitly, or when the user wants to adapt existing content (blog post, talk, thread) into newsletter or web post format. Do NOT use for generic blog post writing without a newsletter/Substack context (-> See samber/cc-skills@technical-article-writer skill).
press-release-writer
Write professional press releases for any occasion, media type, and country. Use when the user wants to write, draft, or improve a press release, communiqué de presse, media announcement, news release, or PR statement — including product launches, funding rounds, partnerships, crisis communications, earnings, executive hires, events, M&A, open source milestones, and media advisories. Covers all release types, media targets (print, digital/wire, broadcast, social/SMPR, trade press), and region-specific conventions (Western/Eastern Europe, Americas, Middle East, Africa, Asia, Oceania). Also trigger when the user says 'I need to announce something' or 'how do I tell the press about X.'
Use this skill whenever the user wants to do anything with PDF files. This includes reading or extracting text/tables from PDFs, combining or merging multiple PDFs into one, splitting PDFs apart, rotating pages, adding watermarks, creating new PDFs, filling PDF forms, encrypting/decrypting PDFs, extracting images, and OCR on scanned PDFs to make them searchable. If the user mentions a .pdf file or asks to produce one, use this skill.