crossbind
GitHub

Import C++ and Rust
like JavaScript modules.

No bindings, no glue, no second build system. One import runs in the browser, on iOS and Android, in Node, on Workers, and as a WASI command.

Get started

Free and open source under the MIT license.

src/main.js
import { initNative, Matrix } from './native/Matrix.h';
import { GDALVersionInfo } from '@crossbind/package-gdal/gdal.h';
 
await initNative();
 
const a = new Matrix(1210000, 1);
const b = new Matrix(1210000, 2);
const result = a.multiple(b);
 
console.log(result.get(0), GDALVersionInfo('RELEASE_NAME'));
src/main.js
import { initNative, Uuid } from 'cargo:uuid';
import { Version, VersionReq } from 'cargo:semver';
 
await initNative();
 
const id = Uuid.newV4().toString();
const ok = new VersionReq('^1.2').matches(new Version('1.4.0'));
 
console.log(id, ok);
SAME CALL · FIVE RUNTIMES
Browser
Chrome · Firefox · Safari
Node.js
CJS or ESM
React Native
iOS + Android · JSI
CF Workers
Edge · same wasm
WASI
wasmtime 47+ · wasip3
Setup promptPaste into Claude Code, Cursor, Copilot…
Add crossbind to this project so I can call C++ (or Rust) from JavaScript.

First inspect the repo and tell me what you found: package manager, bundler (Vite, Webpack, Rspack, Rollup, Metro), whether it targets the browser, Node, Cloudflare Workers or React Native, and any existing C++/Rust sources or CMake project.

Then:

1. Install `crossbind` and the plugin matching my bundler (`@crossbind/plugin-vite`, `@crossbind/plugin-webpack`, `@crossbind/plugin-rspack`, `@crossbind/plugin-rollup`, `@crossbind/plugin-metro`).
2. Create `cppjs.config.js` at the repo root and register the plugin in my bundler config. Keep the change idempotent - do not duplicate an existing entry.
3. If I already have C++ or Rust sources, wire those up. Otherwise add one small example: a header under `src/native/`, imported directly from JavaScript.
4. Call `await initNative()` once at my app's entry point, before the first native call - import it from the header or crate the app already imports, not from a separate runtime package.
5. Run my build and report what changed, including the size of the generated WebAssembly.

Rules: do not hand-write binding or glue code - crossbind generates it from the header. Do not add a second build system. If I need a prebuilt library (GDAL, OpenSSL, SQLite, GEOS, PROJ and more), install the matching `@crossbind/package-*` instead of compiling it from source.

Reference: https://cpp.js.org/docs/guide/getting-started/introduction
$npm create crossbind

Start fresh in under a minute.

The scaffolder asks five questions and prints a working repo — framework, bundler, target, and a sample C++ binding already wired. npm run dev works on the spot.

FRAMEWORKS
ReactVueSvelteVanilla
BUNDLERS
ViteRspackWebpackRollupMetro
TARGETS
Web (WASM)React NativeNode.jsCloudflare Workers
Already have a project? The AI Agent migrates an existing repo — same five questions, no boilerplate.
AGENT →
terminal · ~/projects
> npm create crossbind

FULL CAPABILITY MATRIX

26 capabilities · 9 platform details

Build it

How source turns into every required target

06
10One command, the full build matrixcppjs build spans every valid target by default, with wasm64 kept opt-in. Platform, architecture, runtime, release/debug and runtime-environment filters compose — each accepts comma-separated values when a release needs only part of the matrix.5 COMPOSABLE FILTERS · 30 BUILD TARGETS11CMake, Autotools or your own runnerA package recipe can fetch or generate source, run CMake or configure + make, inject flags and environment variables, patch upstream files, copy assets or replace the build step entirely.CMAKE · AUTOTOOLS · CUSTOM HOOKS12No toolchain to installemscripten, the Android NDK and wasi-sdk arrive together in one digest-pinned Docker image — nothing to set up, identical builds on any machine. iOS still goes through local Xcode, and Rust through your own cargo.JUST DOCKER FOR WASM · ANDROID · WASI13Nothing rebuilds twiceHeaders, bridges and libraries are content-hashed, so an unchanged one comes back as (cached) in the build log instead of recompiling. Cargo keeps its own incremental cache, and the Docker image is pulled once.CONTENT-HASHED · PER-TARGET CACHE14Only what you useDead-code elimination on top of -O3, plus platform-split downloads: you ship what you call and nothing else. Android is the exception — it links the whole library.DCE + -O3 · PLATFORM-SPLIT DOWNLOADS15Override anythingTwenty documented override points: swap flags per target, patch sources, drop a dependency from the graph, or rebuild any prebuilt from source.20 OVERRIDE POINTS · REBUILD FROM SOURCE

Platform & tooling details

  • Expo config plugin
  • memory64 targets
  • JSPI async (experimental)
  • SWIG escape hatch
  • Android arm64 + x86_64
  • monorepo paths
  • write your own bundler plugin
  • CommonJS + ESM modules
  • clean dependency cache command
NEW

Drop crossbind in,
without reading the docs.

The crossbind Agent reads your project, writes cppjs.config.js and cppjs.build.js, wires initNative() into the right entrypoint, then verifies the build.

Detects your stack (Vite, Webpack, RN, Next…)
Writes cppjs.config.js + cppjs.build.js
Patches your bundler config — idempotent
Runs your build and reports the diff
Try the agent →
agent · integrating into vite app
> cppjs-agent integrate
┌─ Detecting project
│ ✓ Vite + React + TypeScript
│ ✓ vendored C++ at ./vendor/matrix.cpp
┌─ Writing config
│ ✓ cppjs.config.js
│ ✓ cppjs.build.js
│ ✓ vite.config.ts   + plugin-crossbind
│ ✓ src/main.tsx    await initNative()
⚠ React Native target requested but no RN setup
  Skipped — add later via `--rn` flag
✓ npm run dev compiles · WASM 184 kB
>  
PREBUILT LIBRARIES

Drop in real C++ libraries.

View all 16 →
GDAL
The geospatial stack — 200+ raster and vector formats
geo · 3.13.2install →
OpenSSL
TLS and crypto, real https from a WASI command
crypto · 4.0.1install →
SQLite
The database, in the browser and on device
db · 3.53.4install →
PROJ
Coordinate transforms with the EPSG database
geo · 9.8.1install →
GEOS
Planar geometry — buffers, overlays, predicates
geo · 3.14.1install →
libTIFF
TIFF read/write with JPEG, ZSTD and LERC codecs
image · 4.7.2install →
libwebp
WebP encode and decode anywhere
image · 1.6.0install →
SpatiaLite
Spatial SQL on top of SQLite
geo · 5.1.0install →
COMMUNITY

Build it together

Type to search every guide page and section.
↑↓ navigate↵ openesc close