Topaz is a compact language for application intent. It reads like Python or TypeScript, but prefers one consistent way to express each common idea. The same rules apply whether a person writes the code or a tool generates it.
Rust remains the right tool when you need direct control of the machine. Topaz lives one layer higher: command-line tools, data transformation, service logic, configuration, SQL, shell, and path orchestration. You can run the same source directly or build a native program, Python product, or web artifact.
This page explains where the language fits and what its code feels like. It is not lesson one. If you are new to Topaz, follow the Learning path or run the first program in the Playground. Use Syntax at a Glance when you want a compact map of the language, and read the language philosophy for the design choices behind it.
The examples below are checked and executed with the Topaz tools.
What Topaz code feels like
Unicode-first
Identifiers are Unicode from the lexer up. Domain words stay in your language instead of becoming romanized approximations:
function greet(name: string, language: string) -> string {
return match language {
case "한국어" => "안녕하세요, {name}님!"
case "Русский" => "Привет, {name}!"
case _ => "Hello, {name}!"
}
}
let 사용자 = "김토파즈"
print(greet(사용자, "한국어"))
print(greet("Topaz", "Русский"))안녕하세요, 김토파즈님!
Привет, Topaz!사용자 is an ordinary variable. Unicode identifiers are a normal part of the language. Topaz does not silently rewrite the name you entered, and the module resolver rejects names that are easy to confuse.
A small, closed surface
Common decisions have a preferred form. Recoverable failure is Result, expected absence is Option, cleanup is defer, and match checks that all cases are covered. The language fixes these choices so every file does not become its own dialect.
function parsePort(raw: string) -> Result<int, string> {
let n = toInt(raw) ?? -1
if n < 1 {
return Err("not a port: {raw}")
}
return Ok(n)
}
function startup(raw: string) -> Result<string, string> {
defer print("config closed")
let port = parsePort(raw)?
return Ok("listening on {port}")
}
print("{startup("8080")}")
print("{startup("http")}")config closed
Ok(listening on 8080)
config closed
Err(not a port: http)The ? operator returns an Err to the caller, while defer runs on every exit path. That is why config closed appears before both results.
Templates keep intent structured
The current template registry is p, r, sh, and sql. For example, p"..." is a path template, while sql"..." keeps SQL text separate from interpolated parameters instead of collapsing everything into one string:
let table = "users"
let q = sql"select * from {table} where active = {true}"
print("{q}")<sql template, 3 part(s), 2 interpolation(s)>The output is a structural summary: the template still knows which pieces were literal text and which were interpolated values.
Check once, choose an output
Topaz is statically typed. The checker validates the whole program before execution:
type TrafficLight = "red" | "yellow" | "green"
function next(light: TrafficLight) -> TrafficLight {
return match light {
case "red" => "green"
case "green" => "yellow"
case _ => "red"
}
}topaz run parses, resolves, checks, and executes the program. From the same source, topaz emit and topaz build create other outputs. The Rust target produces a self-contained native binary. The Python target writes program.py plus its support file topaz_py_rt.py.
Rust and Python outputs are tested against the same language behavior. See Toolchain Status for current support and target-specific limits.
topaz build app.tpz --target python --out-dir py-out
When not to use Topaz
Use Rust, C, or Zig instead if you need direct ownership and lifetime control, unsafe boundaries, embedded targets, hand-tuned performance, or full access to a systems ecosystem. Topaz's narrow road is a real cost when you want every lever.
Topaz is for the opposite shape of work: deployable application logic without a systems-level source surface, domain language kept in code, and a small grammar that people and agents can produce consistently. When that describes your project, continue with the Learning path.
One way to say it.