Component-based · Pure Zig · GPLv3

Build games in pure Zig.

No garbage collector SDL3 GPU · Vulkan/Metal/D3D12 Single native binary
spinner.zig — assets/
 const engine = @import("engine"); pub const
Spinner = struct { pub const is_component = true; speed: f32 = 90.0, // editable
in inspector pub fn update(self: *Spinner, time: engine.Time) void { _ =
self.speed * time.delta; } }; 
terminal
$ turian-cli new-project ../my-game "My Game"
$ turian-cli build ../my-game
→ cooked 12 assets · compiled game · 1 standalone binary ✓
0garbage collectors
1language, top to bottom
3GPU backends
1 binaryself-contained ship
GPLv3no seats, no fees
Everything in one window

A real editor, without the runtime tax

Turian pairs a Unity-style visual workflow with the predictability of a systems language. No VM, no scripting bridge, no hidden allocations.

Visual editor

Scene hierarchy, inspector, asset browser and a live 3D viewport — all in a single window powered by SDL3 GPU.

Component system

Declare pub const is_component = true; in any struct and it appears in the Add Component menu with full field inspection.

Live script discovery

Drop a .zig file into assets/, hit Refresh, and your component shows up immediately — fields introspected at edit-time.

Asset pipeline

Loads OBJ, glTF 2.0 / GLB, PNG, JPG and more, with GUID-stable references that survive moves and renames.

Headless CLI

turian-cli build compiles your game without opening the GUI — the same artifact your editor produces, ideal for CI.

Pure Zig

No garbage collector, no hidden allocations, no runtime surprises. Compiles to a single executable on every Zig-supported platform.

Scripting

Components are just Zig structs

One marker turns a struct into an editor component. Public fields become inspector controls; lifecycle hooks are plain methods you implement only when you need them.

  • Code-driven discovery — the editor parses real Zig, not regex, so comments and conditional compilation never break it.
  • Typed inspector fields — f32, i32, bool, Vec3, and object/asset references render automatically.
  • Familiar lifecycle — awake, enable, start, update, disable, destroy.

Read the tutorial →

follower.zig
 const std = @import("std"); const engine = @import("engine"); pub
const Follower = struct { pub const is_component = true; /// Drag a GameObject
from the Hierarchy here. target: engine.GameObjectRef = .{}, speed: f32 = 4.0,
pub fn start(self: *Follower) void { const name = self.target.slice(); if
(name.len > 0) std.debug.print("following '{s}'\n", .{name}); } pub fn
update(self: *Follower, time: engine.Time) void { _ = self.speed * time.delta; }
}; 
From zero to a shipped build

Three commands. One binary.

Scaffold

turian-cli new-project creates a project with an assets folder and a starter scene.

Script & arrange

Open Turian Studio, drop in components, wire up the scene, and tweak fields live in the inspector.

Build & share

turian-cli build cooks assets and emits a self-contained executable you can hand to anyone.

Open source · open doors

Join the community

Ask questions, share your work, and help shape the engine — everyone is welcome.

Keep the lights on

Support Turian's development

Turian is built by volunteers. Your support funds ongoing work and keeps the engine free and open.

Ready to build something?

Download the SDK, install Zig 0.16.0, and ship your first scene in minutes.