Bun provides a high-performance Foreign Function Interface (FFI) via the bun:ffi module. It allows JavaScript to call native C functions directly by just-in-time (JIT) compiling C wrappers that handle type conversion between JavaScriptCore (JSC) types and the C Application Binary Interface (ABI) packages/bun-types/ffi.d.ts1-15
The FFI system is built on a multi-layered architecture involving Zig, C++, and an integrated C compiler (TinyCC).
| Component | Role | File Reference |
|---|---|---|
FFI (Zig/Rust) | The primary orchestrator for loading dynamic libraries (dlopen) and managing function symbols. | src/runtime/ffi/ffi_body.rs194-200 |
TCC (TinyCC) | Integrated C compiler used to generate machine code thunks that bridge JSC and the C ABI. | packages/bun-types/ffi.d.ts12-15 |
JSCallback | Manages native-to-JS calls, providing a context for the JS function and supporting thread-safe execution. | src/js/bun/ffi.ts82-116 |
CString | A specialized String subclass wrapping a native pointer for zero-copy access to C strings. | src/js/bun/ffi.ts118-152 |
JSFFIFunction | A C++ class representing a native function exposed to JavaScript, inheriting from JSC::JSFunction. | src/jsc/bindings/JSFFIFunction.cpp135-141 |
When a native function is called from JavaScript, Bun utilizes a specialized pipeline to minimize transition overhead:
symbols object.int32_t values are forced to Int32Tag using the |0 bitwise operator to ensure JSValue::asInt32() can deserialize them src/js/bun/ffi.ts166-184Diagram: FFI System Architecture
Sources: src/js/bun/ffi.ts75-80 src/runtime/ffi/ffi_body.rs118-128 src/jsc/bindings/JSFFIFunction.cpp81-87
Bun maps JavaScript types to C types using the FFIType enum. Performance is optimized by using "fast" versions of types (e.g., i64_fast) that attempt to avoid BigInt overhead when values fit within safe integer limits packages/bun-types/ffi.d.ts324-330
| FFIType | C Equivalent | JavaScript Type | Implementation Detail |
|---|---|---|---|
i32 / int | int32_t | number | Uses ` |
ptr | void* | TypedArray / number | Resolved via ffi.ptr() src/js/bun/ffi.ts69 |
cstring | char* | string / CString | Automatically converts null-terminated strings packages/bun-types/ffi.d.ts309-313 |
napi_env | napi_env | null / opaque | Bridges to Bun's Node-API implementation src/js/bun/ffi.ts58 |
bool | bool | boolean | Forced via !!val in the JS wrapper src/js/bun/ffi.ts275-277 |
Diagram: Type Coercion Logic
Sources: src/js/bun/ffi.ts159-280 packages/bun-types/ffi.d.ts20-330
cc)Bun supports compiling C code at runtime using the cc API. This integrates TinyCC directly into the runtime, allowing developers to define native logic without external build steps test/js/bun/ffi/cc.test.ts26-31
#define constants from JavaScript via the define property test/js/bun/ffi/cc-fixture.js10-12<node/node_api.h> to interact with the JS environment via napi_env test/js/bun/ffi/cc-fixture.c15-23Bun supports passing JavaScript functions as callbacks to native code via JSCallback src/js/bun/ffi.ts82
.close() or the Symbol.dispose pattern to prevent memory leaks src/js/bun/ffi.ts103-116threadsafe option allows callbacks to be invoked from non-JS threads. Bun handles this by using a FFICallbackFunctionWrapper which is ThreadSafeRefCounted and schedules the task on the main JS thread's event loop src/jsc/bindings/JSFFIFunction.cpp42-60 src/js/bun/ffi.ts87-96Bun's Bun.cron API leverages native OS capabilities and internal timers.
crontab (Linux), launchd (macOS), or Windows Task Scheduler docs/runtime/cron.mdx150-157Bun.cron.parse uses a native implementation to calculate future execution dates from 5-field cron expressions docs/runtime/cron.mdx33-51Sources:
Refresh this wiki
This wiki was recently refreshed. Please wait 7 days to refresh again.