Start here · ~10 minutes
Your first Glyph program
Install it, scaffold a project, run it, then break it on purpose and read the error the compiler gives you. No prior Glyph knowledge assumed — if you've written a little TypeScript, you'll follow every line.
1 · Install
Glyph ships as a single prebuilt binary. You also need Node with tsx and
typescript, which Glyph uses to run and type-check.
npm install -g @glyphlang/glyph npm install -g tsx typescript # run & type-check toolchain glyph doctor # confirms your toolchain is ready
2 · Scaffold a project
glyph init creates a runnable starter — a src/main.glyph, a package.json, and a .gitignore.
glyph init hello cd hello
Open src/main.glyph — it's a hello-world:
module main
fn main(argv: Array<string>) -> number {
print("hello from glyph")
return 0
}
Two things to notice: a program runs its main(argv), and main
returns a number — the process exit code.
3 · Run it
glyph run src/main.glyph
hello from glyph
glyph run type-checked it, compiled it to TypeScript, and executed it. That's
the whole loop.
4 · Add something real
Now replace the body with a tiny bit of logic — a task status and a function that
labels it. This introduces the two things you'll use constantly: a tagged union
(type Status = ...) and match, which is Glyph's only conditional.
module main
type Status = Todo | Doing | Done
fn label(s: Status) -> string {
return match s {
Todo => "not started",
Doing => "in progress",
Done => "finished",
}
}
fn main(argv: Array<string>) -> number {
print(label(Done))
return 0
}
glyph run src/main.glyph
finished
5 · Break it on purpose
Here's the part that shows you what Glyph is for. Delete the Done arm
from the match — the kind of thing an agent does when it adds a case
somewhere and forgets to handle it — and run again.
fn label(s: Status) -> string {
return match s {
Todo => "not started",
Doing => "in progress",
}
}
[E0200] Error: typecheck: non-exhaustive match on `Status`: missing variants `Done`
╭─[main:6:10]
│
6 │ ╭─▶ return match s {
┆ ┆
9 │ ├─▶ }
│ ╰───────── missing variants `Done`
│
│ Help: Add an arm for each missing variant, or an `else` arm to catch the rest.
───╯
It didn't run. In TypeScript the equivalent switch would compile clean and
return undefined at runtime; here the missing case is a compile error with a
stable code (E0200), the exact spot, and a one-line fix. Run
glyph --explain E0200 any time you want the long version.
6 · Fix it
Put the arm back (or add an else), and it runs again.
glyph run src/main.glyph
finished
That's the core loop: write, run, and when something's wrong the compiler tells you exactly what and how — before your code ships, not after. From here:
- The five-minute tour — the whole language, quickly.
- The answers — straight replies to the questions engineers actually ask (React, typed APIs, why not tooled TS).
- The playground — try Glyph in your browser, no install.