ZZON: Zig's ZON parser and serializer for JavaScript

zzon Library - ZON seems to be a cleaner version than JSON. This library enables usage of ZON file in JS/TS project.

Demo in Playground using zzon parser/serializer:
playground

There are other reason to use ZON in JS project, for me it was because I was having to maintain a project in multiple language for web and native implementation, and I chose Zig to be the primary language, and maintain data file in Zig side in ZON and just reuse/sync the same ZON file in JS side so I end up building this.

13 Likes

This looks great. I have a use for it on a personal project!

In the Bun example would that allow this style of import?

import config from "config.zon" with { type: "zon" };

What sort of benchmark results are you getting?

2 Likes

Awesome!

There are ways to import ZON file in Bun, and two of them has 0 performance overhead, so they will work as fast as normal like declaring JS Object inline.

Here are steps in case of your use case:

  1. Add a .d.ts file so that you don’t get type error.
# zon.d.ts
declare module '*.zon' {
  const content: Record<string, any>;
  export default content;
}
  1. Add the bun loader so that import is handled automatically by bun at bundle time. I or someone can publish this bun loader as npm package and it would be even simpler.
# zon.loader.ts
import { plugin } from 'bun';

await plugin({
  name: 'ZON',
  async setup(build) {
    const { ZON } = await import('zzon');

    build.onLoad({ filter: /\.(zon)$/ }, async (args) => {
      const text = await Bun.file(args.path).text();
      const zon = ZON.parse(text) as Record<string, any>;
      
      return {
        loader: 'object',
        exports: {
          default: zon,
        },
      };
    });
  },
});
  1. Define the loader in bunfig.toml
preload = ["./zon.loader.ts"]
  1. And you just import ZON file and they will be converted to JS Obj and inclined during bundle time.
import data from './../data.zon'; // see zon.loader.ts which describes how to load the file

console.log(data);

Here are all available methods in case you are interested. An older version of the guide is on the repo as well. zzon/example/bun at main · nurulhudaapon/zzon · GitHub

ZON in Bun

There are three ways to use ZON in Bun:

First cd into the example/bun directory:


cd example/bun

Install the dependencies:


bun install

Using Bun’s loader (Recommended)

:white_check_mark: Parsing happens at bundle time so 0 performance overhead

:white_check_mark: No extra files or code to parse

Files: zon.loader.ts, zon.d.ts, loader/index.ts


bun run loader/index.ts

Using Bun’s Macro

:white_check_mark: Parsing happens at bundle time so 0 performance overhead

:cross_mark: Extra files and code is required

Files: macro/index.ts


bun run macro/index.ts

Using Bun’s default text loader

:cross_mark: Parsing happens at runtime so performance overhead

:cross_mark: Extra code is required to parse the file

Files: import/index.ts


cd import && bun run index.ts

4 Likes

Cool to see that Bun has those options. I wonder if the Bun team could be persuaded to integrate ZON directly into Bun since it’s written in Zig :thinking: Although with the loader plugin I suppose it’s solved.

Anyway, great work on ZZON

1 Like

Welcome to Ziggit @nurulhudaapon!

This is a great first project. In general I’m looking forward to the ZON format becoming ubiquitous in Zig code, and it’s intriguing to see the possibilities for using it across language boundaries as well.

Thanks for sharing!

2 Likes