Skip to main content
bun:ffi has experimental support for compiling and running C from JavaScript with low overhead.

Usage (cc in bun:ffi)

See the introduction blog post for background. JavaScript:
hello.ts
C source:
hello.c
Running hello.ts prints:
terminal
cc uses TinyCC to compile the C code, then links it with the JavaScript runtime, converting types in-place.

Primitive types

cc supports the same FFIType values as dlopen.
FFITypeC TypeAliases
cstringchar*
function(void*)(*)()fn, callback
ptrvoid*pointer, void*, char*
i8int8_tint8_t
i16int16_tint16_t
i32int32_tint32_t, int
i64int64_tint64_t
i64_fastint64_t
u8uint8_tuint8_t
u16uint16_tuint16_t
u32uint32_tuint32_t
u64uint64_tuint64_t
u64_fastuint64_t
f32floatfloat
f64doubledouble
boolbool
charchar
napi_envnapi_env
napi_valuenapi_value

Strings, objects, and non-primitive types

For strings, objects, and other non-primitive types that don’t map 1:1 to C types, cc supports N-API. Use napi_value to pass or receive JavaScript values from a C function without any type conversions. You can also pass a napi_env to receive the N-API environment used to call the JavaScript function.

Returning a C string to JavaScript

For example, to return a string from C to JavaScript:
hello.ts
And in C:
hello.c
The same approach returns other types like objects and arrays:
hello.c

cc Reference

library: string[]

Use the library array to specify the libraries to link with the C code.

symbols

Use the symbols object to specify the functions and variables to expose to JavaScript.

source

source is the path to the C code to compile and link with the JavaScript runtime.

flags: string | string[]

flags is an optional array of strings passed to the TinyCC compiler.
These are flags like -I for include directories and -D for preprocessor definitions.

define: Record<string, string>

define is an optional object of preprocessor definitions passed to the TinyCC compiler.