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.js N-API / `node-addon-api` (requires C++ compilation) or `node:ffi-napi`.`Deno.dlopen()` foreign function interface.`import { dlopen, FFIType } from 'bun:ffi';`.Project Panama Foreign Function & Memory API (`Linker.nativeLinker()`).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.
Napi::Value Add(const Napi::CallbackInfo& info); // ❌ Requires C++ wrapper file + binding.gypconst { symbols: { add } } = dlopen('libmath.so', { add: { args: ['i32', 'i32'], returns: 'i32' } }); // ✅ NEWInterview 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`.
Context
Checks awareness of native pointer crashes and memory corruption.
The mechanical answer
`bun:ffi` bypasses JavaScript's memory safety guarantees. If a C function is called with incorrect argument types, accesses an out-of-bounds pointer, or attempts to read memory freed by C's `free()`, the **entire Bun process will crash immediately with a Segmentation Fault (`SIGSEGV`)** that cannot be caught by JavaScript `try/catch`.
Trap
Always ensure buffer pointers passed to C libraries remain in memory (not garbage collected) for the duration of the native call.