https://github.com/ykmnkmi/native_toolchain_zig.dart
Zig support for Dart's build hooks. Automatically builds and bundles your Zig code with your Dart/Flutter application.
https://github.com/ykmnkmi/native_toolchain_zig.dart
dart ffi interop native-assets native-toolchain zig
Last synced: 3 months ago
JSON representation
Zig support for Dart's build hooks. Automatically builds and bundles your Zig code with your Dart/Flutter application.
- Host: GitHub
- URL: https://github.com/ykmnkmi/native_toolchain_zig.dart
- Owner: ykmnkmi
- License: mit
- Created: 2026-01-16T13:00:26.000Z (5 months ago)
- Default Branch: main
- Last Pushed: 2026-03-30T03:25:24.000Z (3 months ago)
- Last Synced: 2026-03-30T05:55:44.425Z (3 months ago)
- Topics: dart, ffi, interop, native-assets, native-toolchain, zig
- Language: C
- Homepage: https://pub.dev/packages/native_toolchain_zig
- Size: 562 KB
- Stars: 1
- Watchers: 0
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# 🔧 native_toolchain_zig
[![Pub Version][pub_badge]][pub_link]
[![Dart CI][dart_ci]][dart_ci_link]
[![License: MIT][license_badge]][license_link]
Zig support for Dart's [build hooks][dart_hooks].
Automatically builds and bundles your Zig code with your Dart/Flutter application.
> [!NOTE]
> If you want to use `ffigen` to auto-generate Dart bindings, you'll need to
> manually write a C header file. Automatic header generation from Zig is
> currently blocked by ziglang/zig#9698.
### Prerequisites
Install [Zig 0.15.0+][zig_download] on your development machine.
### Installation
```bash
dart pub add hooks native_toolchain_zig
```
### Project Setup
1. Create your Zig project in `my_project/zig/`:
```
my_package/
├── hook/
│ └── build.dart
├── lib/
│ └── my_package.dart
├── zig/
│ ├── src/
│ │ └── lib.zig
│ ├── build.zig
│ └── build.zig.zon
└── pubspec.yaml
```
2. Create `hook/build.dart`:
```dart
import 'package:hooks/hooks.dart';
import 'package:native_toolchain_zig/native_toolchain_zig.dart';
Future main(List arguments) async {
await build(arguments, (input, output) async {
await ZigBuilder(
assetName: 'my_package.dart',
zigDir: 'zig/',
).run(input: input, output: output);
});
}
```
3. Create `zig/build.zig`:
```zig
const std = @import("std");
pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
const lib = b.addLibrary(.{
.name = "my_package",
.linkage = .dynamic,
.root_module = b.createModule(.{
.root_source_file = b.path("src/lib.zig"),
.target = target,
.optimize = optimize,
}),
});
b.installArtifact(lib);
}
```
Build both static and dynamic libraries
To produce both library types in a single build:
```zig
const std = @import("std");
pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
const root_module = b.createModule(.{
.root_source_file = b.path("src/lib.zig"),
.target = target,
.optimize = optimize,
});
// Dynamic library (.so, .dylib, .dll)
const dynamic_lib = b.addLibrary(.{
.name = "my_package",
.linkage = .dynamic,
.root_module = root_module,
});
b.installArtifact(dynamic_lib);
// Static library (.a, .lib)
const static_lib = b.addLibrary(.{
.name = "my_package",
.linkage = .static,
.root_module = root_module,
});
b.installArtifact(static_lib);
}
```
Select linkage via command line
To control linkage type via a custom `-Dlinkage` option, first accept it in
your `build.zig`:
```zig
const std = @import("std");
pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
const linkage = b.option(
std.builtin.LinkMode,
"linkage",
"Library linkage type",
) orelse .dynamic;
const lib = b.addLibrary(.{
.name = "my_package",
.linkage = linkage,
.root_module = b.createModule(.{
.root_source_file = b.path("src/lib.zig"),
.target = target,
.optimize = optimize,
}),
});
b.installArtifact(lib);
}
```
Then pass the flag from Dart via `extraArguments` in `hook/build.dart`:
```dart
import 'package:hooks/hooks.dart';
import 'package:native_toolchain_zig/native_toolchain_zig.dart';
Future main(List arguments) async {
await build(arguments, (input, output) async {
await ZigBuilder(
assetName: 'my_package.dart',
zigDir: 'zig/',
// Forward the linkage option to zig build
extraArguments: ['-Dlinkage=static'],
).run(input: input, output: output);
});
}
```
4. Create `zig/build.zig.zon`:
```zig
.{
.name = .my_package,
.version = "0.1.0",
.minimum_zig_version = "0.15.0",
.fingerprint = 0x..........,
.paths = .{
"src",
"build.zig",
"build.zig.zon",
},
}
```
> [!IMPORTANT]
> The `paths` field drives **incremental build tracking**. `ZigBuilder` parses
> `build.zig.zon` and registers every file and directory listed in `paths` as a
> build dependency. When any of those files change, Dart's build system
> automatically re-triggers the Zig build. Make sure `paths` includes all source
> directories and files your build depends on (e.g. `"src"`, C headers,
> embedded data files).
>
> The `name` field (`.my_package`) is a comptime enum literal and is ignored.
5. Create `zig/src/lib.zig`:
```zig
export fn add(a: i32, b: i32) i32 {
return a + b;
}
```
6. Create Dart bindings in `lib/my_package.dart`:
```dart
import 'dart:ffi';
@Native()
external int add(int a, int b);
```
7. Run your app:
```bash
dart run
```
## Example
An example can be found in [/example/][example].
## License
MIT License - see [LICENSE](LICENSE) for details.
[pub_badge]: https://img.shields.io/pub/v/native_toolchain_zig
[pub_link]: https://pub.dev/packages/native_toolchain_zig
[dart_ci]: https://github.com/ykmnkmi/native_toolchain_zig.dart/actions/workflows/ci.yaml/badge.svg
[dart_ci_link]: https://github.com/ykmnkmi/native_toolchain_zig.dart/actions
[example]: https://github.com/ykmnkmi/native_toolchain_zig.dart/tree/main/example
[license_badge]: https://img.shields.io/badge/license-MIT-purple.svg
[license_link]: https://opensource.org/licenses/MIT
[dart_hooks]: https://dart.dev/tools/hooks
[zig_download]: https://ziglang.org/download/