HTML Generation for Zig

Zigomponent is a Zig library inspired by gomponents that allows you to create HTML elements using native Zig syntax. Build type-safe, composable HTML components with the power of Zig.

Simple and Intuitive

Create HTML elements with native Zig syntax

const std = @import("std");
const z = @import("zigomponent");
const el = z.el;
const attr = z.attr;

pub fn main() !void {
    const allocator = std.heap.page_allocator;
    var arr: std.ArrayList(u8) = .{};
    defer arr.deinit(allocator);
    const writer = arr.writer(allocator);
    const docType = "\<\!DOCTYPE html\>"; // remove all '\' on this line

    const html = el.ToNode(&.{
        el.Raw(docType),
        el.Html(&.{
            attr.Lang("en"),
            el.Head(&.{
                el.Meta(&.{attr.Charset("UTF-8")}),
                el.Meta(&.{ attr.Name("viewport"), attr.Content("width=device-width, initial-scale=1") }),
                el.Title(&.{el.Text("Document")}),
            }),
            el.Body(&.{el.Div(&.{
                el.H1(&.{
                    attr.Style("color: blue; margin-top: 20px; margin-bottom: 20px;"),
                    el.Text("Welcome to Zigomponent!"),
                }),
                el.P(&.{
                    el.Text("Build HTML with the power of Zig."),
                }),
                el.Button(&.{
                    attr.OnClick("alert('Hello from Zig!')"),
                    el.Text("Click me!"),
                }),
            })}),
        }),
    });

    try html.render(writer);

    const res = arr.items;
    std.debug.print("{s}", .{res});
}

Why Zigomponent?

Powerful features for modern web development

Type Safety
Leverage Zig's compile-time type checking to catch HTML errors before runtime.
Performance
Zero-cost abstractions and compile-time optimizations for blazing fast HTML generation.
Composable
Build reusable components and compose them together for complex layouts.

More Examples

See zigomponent in action

Creating a Form

const form = el.Form(&.{
    attr.Action("/submit"),
    attr.Method("POST"),
    el.Input(&.{
        attr.Type("text"),
        attr.Name("username"),
        attr.Placeholder("Enter username"),
        attr.Required(),
    }),
    el.Input(&.{
        attr.Type("password"),
        attr.Name("password"),
        attr.Placeholder("Enter password"),
        attr.Required(),
    }),
    el.Button(&.{
        attr.Type("submit"),
        attr.Class("btn btn-primary"),
        el.Text("Login"),
    }),
});

Custom Components

fn Card(title: []const u8, content: []const u8) type {
    return struct {
        const card = el.Div(&.{
            attr.Class("card shadow-lg"),
            el.Div(&.{
                attr.Class("card-header"),
                el.H3(&.{
                    el.Text(title),
                }),
            }),
            el.Div(&.{
                attr.Class("card-body"),
                el.P(&.{
                    el.Text(content),
                }),
            }),
        });

        fn New() z.Node {
            return card;
        }
    };
}

Getting Started

Add zigomponent to your Zig project in minutes

1. Add zigomponent to your project

$ zig fetch --save git+https://github.com/eltNEG/zigomponent;

2. Update your build.zig

b.installArtifact(exe); // This line should already be in your build.zig file

const zigomponent = b.dependency("zigomponent", .{
    .target = target,
    .optimize = optimize,
});

exe.root_module.addImport("zigomponent", zigomponent.module("zigomponent"));

3. Import in your code

const z = @import("zigomponent");
const el = z.el;
const attr = z.attr;

4. Use in your code

const page = el.Html(&.{
    attr.Lang("en"),
    el.Body(&.{
        el.H1(&.{
            el.Text("Hello, Zigomponent!"),
        }),
    }),
});