• Jarred a day ago

    This was an unplanned feature I worked on mostly a month ago on a Saturday for fun. Happy to answer any questions

    To get it out the door, ended up adding some patches to TinyCC to support .framework on macOS and fix a few things with dlopen and include paths. Also added support for parsing the deprecated attribute used in lots of Darwin headers. C parsers seem a lot simpler than JavaScript which is nice

    • candleknight a day ago

      Awesome work on this, it looks like a game changer!

      From my (admittedly limited) knowledge on this space, it seems like this is a straight upgrade over WASM, with the only limiting factor being that your stack is limited to Bun + C. Are there any downsides of this feature when compared with the alternatives mentioned at the start of the article? There are some tradeoffs listed at the bottom but I'm not sure how napi/WASM perform in those aspects either.

      • NoahKAndrews 17 hours ago

        NAPI and WASM let you use optimizing compilers, so they're suitable for use with larger C and C++ codebases

      • hiccuphippo 19 hours ago

        This is very cool. Is the code compiled on every run or does it get cached?

        • jll29 a day ago

          Cool - if this was an unplanned "accident" then I want to see how your planned projects look like.

        • seveibar a day ago

          I ran some benchmarks and got about a 10% improvement by porting a simple function used in autorouting to C. With the subfunction ported to C, Bun was still ~15% slower than node (v8). As the article hints at, you probably need to port fairly large subfunctions to see major performance gains. Results:

          Bun: 6.7410ms Bun FFI w/ C: 6.0413ms Node: 5.1307ms C only: 4.3ms (+- 1ms)

          I'm generally very bullish on Bun and was very happy with the DX for this C api. Great work to Jarred and the team!!!

          benchmark code: https://github.com/tscircuit/bun-ffi-benchmarking

          • spacedcowboy 8 hours ago

            The Objj compiler is pretty similar to this in Cappuccino and you get (pretty much) Cocoa bundled with…

            https://www.cappuccino.dev/

            • randomdata 4 hours ago

              What is similar about a language that compiles to Javascript and a more efficient Javascript FFI?

              • pjmlp 7 hours ago

                Uau is that still around?!

              • maidh91 10 hours ago
                • russfink a day ago

                  I wonder about the security of this. Are programs executed in some kind of jail? Is there a limit to certain features, e.g., opening a socket to somewhere?

                  • potsandpans 20 hours ago

                    Fta

                    > However, for system libraries, WebAssembly's isolated memory model comes with serious tradeoffs.

                    > Isolation means no system calls WebAssembly can only access functions the runtime exposes to it. Usually, that's JavaScript.

                    Without digging into the code I'm going to assume (guess) that this feature did not take the main value-prop of the WASM model.

                    Afaik, this is explicitly against the isolation that WASM imposes [1]

                    > Modules must declare all accessible functions and their associated types at load time, even when dynamic linking is used. This allows implicit enforcement of control-flow integrity (CFI) through structured control-flow.

                    I seem to remember a WASI developer talk that discussed syscalls here, but I can't remember the specifics. The gist was basically along the lines of, "syscalls are a level of privilege that should not be cart-blanche accessible to all programs at all times"

                  • pjmlp 14 hours ago

                    For me this looks like a solution for a problem that really isn't there.

                    Anyone that cares about compiling C code should be skilled enough to actually use the right tools in first place.

                    • tjelen 7 hours ago

                      I would say that the problem really is there. Dealing with native dependencies and addons was almost always a pain as the article describes (and not just from developer perspective), so anything that helps there is really appreciated.

                      Not sure what you mean by the right tools in this context.

                      • pjmlp 6 hours ago

                        First of all, this is for C, and most extensions are written in C++ or Rust nowadays.

                        Secondly, the right tools are having Python, the C and C++ compiler, node-gyp and cmake.js installed, and actually understand how they work.

                        But what do I know, nowadays folks use C and C++ as scripting languages putting a full library into a single header file to avoid learning how to use the compiler and linker.

                        • paperplatter 3 hours ago

                          I know how to compile and link C. I've never done C<->JS FFI but could probably figure it out. But if I have relatively small C code in single files, why bother? I'll take the easy route unless there's a clear reason not to.

                          The thing is, I'm not already using the Bun runtime and wouldn't switch just for this.

                          • solarkraft 5 hours ago

                            I definitely want to avoid learning how to set up and use the compiler and linker when I just want to use some package.

                            • pjmlp 5 hours ago

                              Knowledge is empowering.

                      • mati365 a day ago
                        • knighthack 4 hours ago

                          ...So is this a transpiler of some sort?

                          If it is, consider looking in Nim. It compiles to C, and even compiles to Javascript. And is extremely performant while at it.

                          • randomdata 3 hours ago

                            Of some sort. The C is transpiled to machine code so that the processor can execute it. Turns out CPUs don't understand C natively.

                            In addition, it automatically generates wrappers to transparently convert between Javascript's memory model and C's memory model to seamlessly allow Javascript to call upon the C functions imported using it.

                            Just your usual FFI, really, but with less call overhead than the FFI specification defined by Node (N-API). Albeit with some different tradeoffs made in order to accomplish that.

                          • gyutff a day ago

                            Is this local js only or can you compile the c code and serve it to a client to execute in the browser?

                            • hiccuphippo 19 hours ago

                              It seems to be local only, but I would imagine they could add compilation to wasm in the future.