Skip to content

Your first Dazzle program

A Dazzle project is a folder with a dazzle.toml manifest. One manifest is one module. dz new makes one:

Terminal window
dz new hello
hello/
dazzle.toml
src/
main.dz
.gitignore
[module]
name = "hello"
sources = ["src/**/*.dz"]
[dependencies]
std = { open = true }
[build]
output = "executable"

sources lists the module’s files. Folders under src/ are organisation only: every file sees every other file’s declarations without an import, and declaration order never matters. std = { open = true } makes the standard library’s names, like String and List, usable without a std:: prefix. Modules has the rest.

src/main.dz has a function, a call of it, and a test beside it:

fn main() {
println!("{}", greeting("world"))
}
fn greeting(name: &str) -> String {
return format!("Hello, {}!", name)
}
// `dz test` runs every `#[test]`; `dz run` and `dz build` leave them out.
#[test]
fn greets_by_name() {
if greeting("Dazzle").as_str() != "Hello, Dazzle!" {
panic!("the greeting should name who it greets")
}
}

Run it from the project folder:

Terminal window
cd hello
dz run

dz checks the program, writes C++17, compiles it with your C++ compiler, and runs it, which prints Hello, world!. dz test runs the test. To see the C++ it wrote, run dz cpp and look in build/cpp/.

Command Does
dz new <dir> create a project there: a manifest and a hello world
dz run [dir] build and run
dz build [dir] build an executable into build/bin/
dz check [dir] analyse only: every diagnostic, no C++ compiler needed (--format=json for JSON)
dz fix [dir] apply the fixes the compiler is certain of (--dry-run to list them)
dz explain <code> what a diagnostic means, with a wrong and a right program
dz test [dir] [filter] run the #[test] functions, each in its own process
dz bench [dir] time the #[bench] functions (release mode by default)
dz fmt <file> format in place (--stdout to print instead, --check to only report)
dz expand <file> the file with every macro invocation expanded
dz cpp [dir] write the generated C++ to build/cpp/
dz placements [dir] where each allocation goes, a region or the heap, and why (--format=json for JSON)
dz lsp the language server, on stdio

dir defaults to the current directory. run, build, cpp, test and bench take a build mode: --debug (the default, -O0 -g), --release (-O2 with link-time optimisation) or --shipping (-O3). --track-memory records every allocation and reports leaks and bad frees when the program exits.

Tests are part of the language. Put a #[test] function next to what it covers:

fn clamp01(x: f32) -> f32 {
if x < 0 {
return 0
}
if x > 1 {
return 1
}
return x
}
#[test]
fn clamp_keeps_values_in_range() {
assert(clamp01(2) == 1)
assert(clamp01(-3) == 0, "negative values clamp to zero")
}

dz test runs each test in its own process, so one crash does not hide the others. A normal build leaves every test out.

ownership a growable array from scratch: own, the three special members, copies and moves; no C++ needed
raylib a raylib window, with raylib compiled from source by dz
rgfw a window from RGFW, a single-header C library
breakout a small game: the rules are plain Dazzle, drawn with raylib
stb a ray tracer that saves its image as a PNG with stb_image_write; no window
sokol a particle fountain on sokol_app, sokol_gfx and sokol_gl
box2d rigid-body physics with Box2D, drawn with sokol: two C libraries in one project
miniaudio a synthesizer, generated sample by sample and played with miniaudio
sdl3 a real-time 3D scene in GLSL, on SDL3 built by its own CMake

Take the tour, starting with errors.