Under The Hood
frontend bun Bun 1.x (`bun:ffi`)

bun:ffi: Direct dlopen C Memory Pointers Without Compilation Bindings

Last updated
Prerequisites:
C ABI (Application Binary Interface) basics
Pointers and data types (`uint8`, `ptr`)
  • bun
  • ffi
  • c-interop
  • dlopen
  • pointers
  • native
  • performance

Read at your depth

The practical view

`bun:ffi` allows Bun to call compiled native C/Rust/Zig shared libraries (`.so`, `.dylib`, `.dll`) directly from JavaScript without writing C++ addons or compiling with `node-gyp`. `import { dlopen, FFIType } from 'bun:ffi'`. You define the symbol signature, and Bun returns a directly callable JavaScript function.

The same idea in other frameworks

node equivalent
Node.js N-API / `node-addon-api` (requires C++ compilation) or `node:ffi-napi`.

Legacy vs modern

Node.js N-API C++ Wrapper vs Bun Zero-Code FFI

Node requires C++ wrapper files and build tools; `bun:ffi` dynamically calls C shared libraries directly from TS.

before → after
Node.js N-API C++ Wrapper
Napi::Value Add(const Napi::CallbackInfo& info); // ❌ Requires C++ wrapper file + binding.gyp
Bun Native bun:ffi
const { symbols: { add } } = dlopen('libmath.so', { add: { args: ['i32', 'i32'], returns: 'i32' } }); // ✅ NEW

Interview gotchas

Context

Interviewers test your knowledge of cross-platform native library loading.

The mechanical answer

`suffix` is a string exported by `bun:ffi` that resolves to the platform-specific shared library file extension: `'dylib'` on macOS, `'so'` on Linux, and `'dll'` on Windows. Using `const path = `./libmycode.${suffix}`` ensures your FFI loading code runs cross-platform without manual OS checks.

Trap

Hardcoding `./lib.so` will crash on macOS where dynamic libraries use `.dylib`.

Under The Hood — a multi-depth technical interview hub.

Third-party licenses Press ⌘ K to search.