-
Notifications
You must be signed in to change notification settings - Fork 3
Hello world (Bun)
In this example we're going to create a very simple server-side app that outputs "Hello world!" to the console through Zig. It demonstrates the basics of working with bun-zigar and the steps for deploying an app in different server environments.
We'll first initialize the project. Open a terminal window and run the following commands:
mkdir hello
cd hello
bun init
bun init helps you get started with a minimal project and tries to guess sensible defaults. Press ^C anytime to quit
package name (hello):
entry point (index.ts): src/index.js
Next, we install bun-zigar:
bun install bun-zigar
bunx bun-zigar preload
Then we create one directory for Zig files:
mkdir zig
In a text editor, we create hello.zig
:
const std = @import("std");
pub fn hello() void {
std.debug.print("Hello world!", .{});
}
Followed by index.js
:
import { hello } from '../zig/hello.zig';
hello();
Then we run it:
bun src/index.js
A message will appear informing you that the Node API addon is being built. This will be followed by the module "hello" itself. After 30 seconds or so, the following should appear in the terminal:
Hello world!
When you use import
on a Zig file, bun-zigar will save the resulting shared library file to a
temporary location. At the root level of the app you will notice a .zigar-cache
sub-directory
with the following structure:
📁 .zigar-cache
📁 zig-6c2c904
📁 Debug
📁 hello.zigar
📑 linux.x64.so
📁 node-zigar-addon
📑 linux.x64.node
hello.zigar
is a bun-zigar module. It's a directory containing dynamic-link libraries for
different platforms. node-zigar-addon
is the Bun.js native addon used to load bun-zigar
modules. It too comes in platform-specific versions.
The files in the cache directory aren't ones we want delivered to end-users. They're compiled at the
Debug
level and are therefore large and slow. Moreover, they only cover the platform we're using
for development (Linux in this case), which probably does not match the eventual server environment.
To prepare our app for deployment, we first change the import
statement so that it references a
.zigar
instead, stored at a more permanent location:
import { hello } from '../lib/hello.zigar';
hello();
We then create a configure file for bun-zigar with the help of its CLI script:
bunx bun-zigar init
bun-zigar.toml
will be populated with some default options:
optimize = "ReleaseSmall"
[sourceFiles]
[[targets]]
platform = "linux"
arch = "x64"
sourceFiles
maps .zigar
modules to source files. Paths are relative to the config file.
optimize
can be Debug
, ReleaseSafe
, ReleaseSmall
, or ReleaseFast
.
targets
is a list of cross-compile targets. platform
and arch
can be one of the possible values
returned by os.platform
and
os.arch
.
We insert the following into our config file:
optimize = "ReleaseSmall"
[sourceFiles]
"lib/hello.zigar" = "zig/hello.zig"
[[targets]]
platform = "linux"
arch = "x64"
[[targets]]
platform = "linux"
arch = "arm64"
[[targets]]
platform = "linux-musl"
arch = "x64"
[[targets]]
platform = "linux-musl"
arch = "arm64"
Then we ask bun-zigar to create the necessary library files:
bunx bun-zigar build
✓ Built module "hello" (linux/x64)
✓ Built module "hello" (linux/arm64)
✓ Built module "hello" (linux-musl/x64)
✓ Built module "hello" (linux-musl/arm64)
✓ Built Bun.js addon (linux/x64)
✓ Built Bun.js addon (linux/arm64)
✓ Built Bun.js addon (linux-musl/x64)
✓ Built Bun.js addon (linux-musl/arm64)
Run bun src/index.js
again to confirm that the configuration is correct.
When you upload the app to a server, omit files in the zig
directory and bun-zigar.toml
so that bun-zigar will never attempt recompilation.
You can find the complete source code for this example here.
You have just learned the basic of using bun-zigar in server-side applications. The app we created doesn't do much. In the next example we're going to create an app that actually does something useful.