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 code is written by a person or generated by a tool.
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 that code directly or build it as a native program or Python source.
The examples on this page are checked and executed with the Topaz tools.
Lena Code integration. Topaz is part of the STUDIO HAZE product family alongside Lena Code. Lena Code conversion workflows can use Topaz as either a source or a target language. See Lena Code Integration for the current workflow.
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.
Four things to know
A small, closed surface
For each intent there is one way to write it. Recoverable failure is Result, absence is optional, cleanup is defer, and match is exhaustive by design. The language decides these policies 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 propagates the Err, and defer runs on every exit path. That is why config closed appears in both transcripts above.
Friendly to code generation
Topaz gives human-written and generated code the same focused syntax. Invalid forms produce clear errors, and examples on this site are checked with the real tools. Code remains readable and reviewable regardless of who produced it.
Templates keep intent structured
sql, sh, and path strings are templates. They are structured values whose parts and interpolations stay separate instead of collapsing into a string:
let table = "users"
let q = sql"select * from {table} where active = {true}"
print("{q}")<sql template, 3 part(s), 2 interpolation(s)>The current renderer shows a structural summary. Domain-specific rendering for SQL, shell, and other template kinds is planned for a future version.
Static checking and multiple outputs
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 can 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.
Start here
- Getting Started: install Topaz and run the first program
- Philosophy: why Topaz treats code as an executable specification
- Syntax: the surface of the language, page by page
- Modules & Visibility: multi-file units
- Toolchain Status: current tools, targets, and limits
One way to say it.