mmycin/zigport
A CLI tool that automatically generates TypeScript FFI bindings for Zig libraries, making it easy to call Zig functions from JavaScript/TypeScript in ...
zigport
is an NPM package as well as a command-line tool that automates the generation of TypeScript Foreign Function Interface (FFI) bindings for Zig libraries created by Tahcin Ul Karim (Mycin). It simplifies the process of calling Zig functions from JavaScript/TypeScript, making it an excellent choice for Bun-based projects that require high-performance Zig functions. Yes, you can now summon Zig speed into your Bun app without breaking a sweat!
zigport
does the heavy lifting for you.You can install zigport
globally using npm
, yarn
, or bun
:
# Using npm
npm install -g zigport
# Using yarn
yarn global add zigport
# Using bun
bun add -g zigport
Create a lib/
directory in your project root. This is where the magic happens.
mkdir -p lib/zig
Inside lib/zig/
, create a Zig source file (e.g., hello.zig
) with the following content:
const std = @import("std");
export fn say_hello() void {
std.debug.print("Hello, {s}!\n", .{"World"});
}
Now, let zigport
do its thing:
zigport generate lib/
This will:
.so
, .dll
, .dylib
depending on your platform).index.ts
file inside lib/
.Once the bindings are generated, import and use them in your TypeScript code:
import { sayHello } from "./lib";
sayHello();
Note that for now it only supports Bun, but we’re working on supporting Deno and Node.js. For this, you'll need Bun installed on your machine.
Install Bun using npm
, yarn
, or bun
:
npm install -g bun
Now run the file.
bun run fileName.ts
Boom. Zig-powered performance, Bun simplicity. Life’s good.
zigport generate <path>
Generates Zig FFI bindings and compiles Zig files into dynamic libraries.
zigport generate lib/
zigport clean
Removes generated files, including compiled Zig libraries and TypeScript bindings.
zigport clean
zigport help
Displays the help menu with available commands.
zigport help
Zig can return numbers, making complex calculations lightning-fast.
math.zig
):export fn add_numbers(a: i32, b: i32) i32 {
return a + b;
}
Generate bindings:
zigport generate lib/
import { addNumbers } from "./lib";
console.log("5 + 3 =", addNumbers(5, 3));
Zig can return strings too! But memory management is your responsibility.
string_utils.zig
):const std = @import("std");
export fn greet(name: [*]const u8) [*]const u8 {
const message = "Hello, " ++ name ++ "!";
return message;
}
Generate bindings:
zigport generate lib/
import { greet } from "./lib";
console.log(greet("Alice"));
Zig just greeted Alice from TypeScript. Mind-blowing, right?
zigport
fails to generate bindingslib/zig/
directory contains valid Zig files.zig build
inside lib/zig/
to diagnose compilation issues.export
..dll
files are in the correct directory.install_name_tool
to set the correct library paths.LD_LIBRARY_PATH
.Here’s a simple Bun project using zigport
:
my-project/
├── lib/
│ ├── zig/
│ │ ├── hello.zig
│ │ ├── math.zig
│ │ ├── string_utils.zig
│ │ ├── build.zig
├── src/
│ ├── main.ts
├── package.json
main.ts
import { sayHello, addNumbers, greet } from "../lib";
sayHello("zigport User");
console.log(addNumbers(10, 20));
console.log(greet("Bob"));
Love zigport
? Want to make it even better? Feel free to open issues or submit pull requests on GitHub. If zigport
saved you hours of headache, consider buying us a virtual coffee ☕️!
This project is licensed under the MIT License. See the LICENSE file for details.
Note: Also, check out RustPort – a similar tool that generates TypeScript FFI bindings for Rust libraries. Because Rust needs love too!