Getting Started
This guide walks you through setting up Zylix and building your first cross-platform application. By the end, you’ll have a working Todo app running on your chosen platform.
Prerequisites
Before you begin, ensure you have the following installed:
Required
Zig 0.13.0 or later
# Verify installation zig version # Expected: 0.13.0 or higherGit for cloning the repository
git --version
Platform-Specific Requirements
Web/WASM requires:
- A modern web browser (Chrome, Firefox, Safari, Edge)
- A local HTTP server (Python, Node.js, or any static file server)
# Quick server options
python3 -m http.server 8080
# or
npx serve .iOS requires:
- macOS 12 (Monterey) or later
- Xcode 14 or later
- XcodeGen for project generation
# Install XcodeGen via Homebrew
brew install xcodegenAndroid requires:
- Android Studio Arctic Fox or later
- Android SDK with API level 26+
- Android NDK 25 or later (for native compilation)
# Set environment variables
export ANDROID_HOME=$HOME/Library/Android/sdk
export ANDROID_NDK_HOME=$ANDROID_HOME/ndk/25.2.9519653macOS requires:
- macOS 12 (Monterey) or later
- Xcode 14 or later
- XcodeGen for project generation
# Install XcodeGen via Homebrew
brew install xcodegenLinux requires:
- GTK4 development libraries
- pkg-config
# Ubuntu/Debian
sudo apt install libgtk-4-dev pkg-config
# Fedora
sudo dnf install gtk4-devel pkg-config
# Arch Linux
sudo pacman -S gtk4 pkgconfWindows requires:
- Windows 10 version 1809 or later
- .NET 8 SDK
- Windows App SDK 1.4 or later
# Verify .NET installation
dotnet --versionInstallation
Step 1: Clone the Repository
git clone https://github.com/kotsutsumi/zylix.git
cd zylixStep 2: Build the Core Library
The core library contains all shared logic: Virtual DOM, state management, diffing algorithm, and component system.
cd core
zig buildThis produces libzylix.a (static library) for your current platform.
Step 3: Verify the Build
Run the test suite to ensure everything is working:
zig build testYou should see all tests passing.
Project Structure
Understanding the project layout helps navigate the codebase:
zylix/
├── core/ # Zig core library (shared across all platforms)
│ ├── src/
│ │ ├── vdom.zig # Virtual DOM engine
│ │ ├── diff.zig # Diffing algorithm
│ │ ├── component.zig # Component system
│ │ ├── state.zig # State management
│ │ ├── store.zig # Generic state store
│ │ ├── events.zig # Event system
│ │ ├── arena.zig # Memory arena allocator
│ │ ├── layout.zig # Layout engine
│ │ ├── css.zig # CSS-in-Zig styling
│ │ ├── scheduler.zig # Task scheduler
│ │ ├── abi.zig # C ABI exports
│ │ ├── wasm.zig # WASM bindings
│ │ ├── dsl.zig # Declarative UI DSL
│ │ └── todo.zig # Todo app implementation
│ └── build.zig # Build configuration
│
├── platforms/
│ ├── web/ # Web/WASM platform
│ │ ├── index.html # HTML shell
│ │ ├── zylix.js # JavaScript bindings
│ │ └── styles.css # Platform styles
│ │
│ ├── ios/ # iOS platform
│ │ ├── Zylix/ # Swift/SwiftUI app
│ │ ├── project.yml # XcodeGen configuration
│ │ └── ZylixBridge.swift # C ABI bridge
│ │
│ ├── android/ # Android platform
│ │ └── zylix-android/ # Kotlin/Compose app
│ │ ├── app/ # Application module
│ │ └── zylix/ # Native library module
│ │
│ ├── macos/ # macOS platform
│ │ ├── Zylix/ # Swift/SwiftUI app
│ │ └── project.yml # XcodeGen configuration
│ │
│ ├── linux/ # Linux platform
│ │ └── zylix-gtk/ # GTK4/C app
│ │ ├── src/ # C source files
│ │ └── Makefile # Build configuration
│ │
│ └── windows/ # Windows platform
│ └── Zylix/ # C#/WinUI 3 app
│ ├── Zylix/ # Application project
│ └── Zylix.sln # Solution file
│
└── site/ # This documentation websiteBuilding for Platforms
Web/WASM
Build the WASM module and serve locally:
# Build WASM (from core directory)
cd core
zig build wasm -Doptimize=ReleaseSmall
# The output is at: zig-out/lib/zylix.wasm
# Copy to web platform
cp zig-out/lib/zylix.wasm ../platforms/web/
# Serve the web app
cd ../platforms/web
python3 -m http.server 8080Open http://localhost:8080 in your browser.
iOS
# Build for iOS (from core directory)
cd core
zig build ios -Doptimize=ReleaseFast
# Generate Xcode project
cd ../platforms/ios
xcodegen generate
# Open in Xcode
open Zylix.xcodeprojSelect a simulator or device and press Run (⌘R).
Android
# Build for Android (from core directory)
cd core
zig build android -Doptimize=ReleaseFast
# Build with Gradle
cd ../platforms/android/zylix-android
./gradlew assembleDebug
# Install on device/emulator
./gradlew installDebugmacOS
# Build for macOS (from core directory)
cd core
zig build -Doptimize=ReleaseFast
# Generate Xcode project
cd ../platforms/macos
xcodegen generate
# Open in Xcode
open Zylix.xcodeprojLinux
# Build for Linux (from core directory)
cd core
zig build linux -Doptimize=ReleaseFast
# Build GTK app
cd ../platforms/linux/zylix-gtk
make
# Run the app
./build/zylix-todoWindows
# Build for Windows (from core directory)
cd core
zig build windows-x64 -Doptimize=ReleaseFast
# Build with .NET
cd ../platforms/windows/Zylix
dotnet build -c Release
# Run the app
dotnet runYour First App: Hello Zylix
Let’s create a simple counter app to understand the basics.
Understanding the Data Flow
sequenceDiagram
participant User
participant Platform as Platform Shell<br/>(Swift/Kotlin/etc.)
participant Core as Zylix Core (Zig)
User->>Platform: 1. Tap/Click
Platform->>Core: 2. zylix_dispatch(event)
Note over Core: 3. Event handler updates state
Note over Core: 4. State change triggers re-render
Note over Core: 5. Virtual DOM diff produces patches
Core->>Platform: 6. Return patches
Platform->>User: 7. UI updates on screen
Core Logic (Zig)
Here’s how a counter works in Zylix:
// state.zig - Define your state
pub const AppState = struct {
counter: i64 = 0,
};
// events.zig - Define events
pub const Event = union(enum) {
counter_increment,
counter_decrement,
counter_reset,
};
// Handle events
pub fn dispatch(event: Event) void {
switch (event) {
.counter_increment => state.counter += 1,
.counter_decrement => state.counter -= 1,
.counter_reset => state.counter = 0,
}
// Trigger re-render
reconciler.scheduleRender();
}Platform Shell (Swift Example)
import SwiftUI
struct CounterView: View {
@State private var counter: Int64 = 0
var body: some View {
VStack(spacing: 20) {
Text("Count: \(counter)")
.font(.largeTitle)
HStack(spacing: 16) {
Button("-") {
ZylixBridge.dispatch(.counterDecrement)
updateState()
}
Button("Reset") {
ZylixBridge.dispatch(.counterReset)
updateState()
}
Button("+") {
ZylixBridge.dispatch(.counterIncrement)
updateState()
}
}
}
}
func updateState() {
counter = ZylixBridge.getState().counter
}
}Next Steps
Now that you have Zylix running, explore these topics:
Troubleshooting
Common Issues
Zig version mismatch
# Check your version
zig version
# Zylix requires 0.13.0+
# Download from https://ziglang.org/download/WASM not loading in browser
- Ensure you’re serving via HTTP (not file://)
- Check browser console for CORS errors
- Verify the WASM file path is correct
iOS build fails
- Run
xcodegen generateafter any changes to project.yml - Ensure XcodeGen is up to date:
brew upgrade xcodegen
Android NDK not found
- Set
ANDROID_NDK_HOMEenvironment variable - Verify NDK is installed via Android Studio SDK Manager
GTK4 not found on Linux
- Install development packages:
libgtk-4-dev(Ubuntu) orgtk4-devel(Fedora) - Run
pkg-config --cflags gtk4to verify
Windows build fails
- Ensure .NET 8 SDK is installed
- Install Windows App SDK via NuGet or Visual Studio