Hello world (Bun) - chung-leong/zigar GitHub Wiki

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.

Creating the app

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!

Configuring the app for deployment

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](/chung-leong/zigar/wiki/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](/chung-leong/zigar/wiki/targets)
platform = "linux"
arch = "x64"

[targets](/chung-leong/zigar/wiki/targets)
platform = "linux"
arch = "arm64"

[targets](/chung-leong/zigar/wiki/targets)
platform = "linux-musl"
arch = "x64"

[targets](/chung-leong/zigar/wiki/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.

Source dode

You can find the complete source code for this example here.

Conclusion

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.


SHA1 digest example