The libtcc API is minimal. For my needs that has been 100% sufficient and a pleasure to work with.
Here's an example that uses raylib (GUI library), without any extra bindings/build step: https://github.com/theoparis/bunray/blob/main/src/example.ts
bun:ffi works by embedding TinyCC - https://github.com/TinyCC/tinycc and then just-in-time compiling C functions that perform type conversions from JavaScript <> C ABI and back. It's faster than node.js' napi (which bun also supports) because it avoids the dynamic library overhead via doing type conversions inline.
For bun, I really wanted something simpler than napi without the performance drawbacks of libffi.
If you want to see the generated C bindings, you can do this:
import { viewSource } from "bun:ffi";
console.log(
viewSource(
{
hello_world: {
returns: "float",
args: ["float"],
},
},
false
)[0]
);
There has been some continued development of tcc; the GitHub repository here has changes through April 2016: https://github.com/TinyCC/tinycc