ZX
Build fast full-stack web apps with Zig.
JSX like syntax or just like HTML with having access to Zig's control flow. No JavaScript runtime, no garbage collection.
Features
Performance-focused web apps built with Zig.
It's Fast
~100x faster SSR than Next.js. Compiles to native code instead of running JavaScript.
Familiar Syntax
Familiar JSX like syntax or just like HTML with having access to Zig's control flow.
Server-Side Rendering
Server-side rendering by default. Pages render on the server with zero configuration.
Static Site Generation
Static site generation by default. Pages render on the server with zero configuration.
File System Routing
Folder structure defines routes. No configs, no magic strings, just files in folders.
Control Flow in Zig's Syntax
if/else, loops, switch—standard control flow works as expected. It's just Zig.
Familiar Syntax
Familiar JSX like syntax or just like HTML with having access to Zig's control flow.
pub fn QuickExample(allocator: zx.Allocator) zx.Component {
const is_loading = true;
const chars = "Hello, ZX Dev!";
var i: usize = 0;
return (
<main @allocator={allocator}>
<section>
{if (is_loading) (<h1>Loading...</h1>) else (<h1>Loaded</h1>)}
</section>
<section>
{for (chars) |char| (<span>{char}</span>)}
</section>
<section>
{for (users) |user| (
<Profile name={user.name} age={user.age} role={user.role} />
)}
</section>
<section>
{while (i < 10) : (i += 1) (<p>{i}</p>)}
</section>
</main>
);
}
fn Profile(allocator: zx.Allocator, user: User) zx.Component {
return (
<div @allocator={allocator}>
<h1>{user.name}</h1>
<p>{user.age}</p>
{switch (user.role) {
.admin => (<p>Admin</p>),
.member => (<p>Member</p>),
}}
</div>
);
}
const UserRole = enum { admin, member };
const User = struct { name: []const u8, age: u32, role: UserRole };
const users = [_]User{
.{ .name = "John", .age = 20, .role = .admin },
.{ .name = "Jane", .age = 21, .role = .member },
};
const zx = @import("zx");
The Numbers
Real numbers based on some initial benchmarks.