Getting Started with OxigenLang
Welcome to OxigenLang! This guide walks you through installation, running your first program, using the interactive REPL, and exploring the language's core features.
#Installation
#Install a prebuilt release
On Linux or macOS (x86-64 or ARM64), one command installs the latest
release. It works out your system, downloads the matching build from GitHub,
checks its SHA-256, and installs oxigen with its standard library under
~/.local (or /usr/local when run as root):
curl -fsSL https://www.oxigenlang.org/install.sh | shAdd -s -- --version 0.1.4 to pick a version, -s -- --prefix DIR to install
somewhere else, or -s -- --uninstall to remove it. The archives themselves,
with their checksums, are on the download page.
On Windows, run the installer inside WSL.
#Build from source
Ensure you have Rust, a C compiler and make
installed (the build compiles the bundled libffi for the ffi
module). Clone the repository and build the project:
cargo build --release -p oxigenThe compiled binary will be at target/release/oxigen (or you can run directly with cargo run -p oxigen -- ...).
To install it system-wide with the Makefile:
sudo make installCheck the installed version:
oxigen --version#The JIT
OxigenLang ships with a Cranelift-backed baseline JIT, compiled in and on by default: a default build tiers hot functions up to native code automatically after about 50 calls. Two run-time flags control it:
oxigen --jit file.oxi # eager: compile on first call
oxigen --no-jit file.oxi # pure interpreterTo build a smaller, interpreter-only binary without the Cranelift dependency tree, drop the default feature:
cargo build --release --no-default-features -p oxigenSee JIT Architecture for details, supported opcodes, safety notes, and benchmark methodology.
#Your First Program
Save the following code in a file named hello.oxi:
// My first OxigenLang program
main {
name := "Explorer"
println("Hello", name, "!")
println("OxigenLang is a modern, lightweight, interpreted programming language.")
}Run it using the command:
cargo run -p oxigen -- hello.oxiYou should see:
Hello Explorer !
OxigenLang is a modern, lightweight, interpreted programming language.main { ... } is the recommended entry point for runnable scripts. Definitions outside main remain available when the file is imported with introduce, while the main block only runs when the file is executed directly.
#Using the REPL
The interactive REPL (Read-Eval-Print Loop) is perfect for testing small code snippets. Start it by running:
cargo run -p oxigen --You'll see a prompt like this:
Oxigen REPL v0.1.1
Type 'exit' or 'quit' to exit, 'version' for version info
>>Type any expression or statement at the prompt and press Enter to see the result:
>> x := 42
42
>> x + 8
50
>> len([1, 2, 3])
3
>> println("Hello from REPL")
Hello from REPL#REPL Commands
| Command | Description |
|---|---|
exit | Exit the REPL |
quit | Exit the REPL |
version | Show the OxigenLang version |
The REPL maintains state across lines — variables, functions, structs, and patterns defined in one line are available in subsequent lines.
#Command-Line Usage
| Command / Flag | Description |
|---|---|
oxigen file.oxi [args...] | Execute a script (bytecode VM) |
oxigen --jit file.oxi | Tier up to the baseline JIT on first call instead of after ~50 calls. OXIGEN_JIT=1 is an equivalent env toggle. Ignored by an interpreter-only (--no-default-features) build. |
oxigen --no-jit file.oxi | Force the pure interpreter even in a JIT-enabled build. |
oxigen | Start the interactive REPL |
oxigen fmt file.oxi [...] | Format one or more .oxi files in-place |
oxigen check file.oxi | Report problems without running the file: syntax and compile errors, names nothing defines, and suspicious logic such as x == "a" or "b". Exits 1 on an error. Prints text at a terminal, JSON otherwise or with --json (for editors) |
oxigen doc [topic] | Show the reference docs: oxigen doc lists the modules, oxigen doc os shows one, oxigen doc os.exec_argv or oxigen doc exec_argv one function, oxigen doc builtins the built-in functions |
oxigen explain CODE | Explain an error code, such as oxigen explain E0038 |
oxigen test [path ...] | Run <test> blocks. With no arguments, discovers *_test.oxi files recursively; a path may be a file or directory (testing guide) |
--version, -v | Print the version and exit |
Options must come before the file. Anything after it is passed to the
script itself, so oxigen file.oxi --no-jit hands --no-jit to your program
rather than to Oxigen.
Scripts can read forwarded arguments through os.args():
introduce os
main {
println(os.args())
}To make a script executable directly on Unix-like systems, add a shebang as the first line:
#!/usr/local/bin/oxigen
#[location=/usr/local/bin/oxigen]
introduce os
main {
println("Hello from", os.args())
}Then mark it executable and run it:
chmod +x hello.oxi
./hello.oxi AliceIf Oxigen is on your PATH, #!/usr/bin/env oxigen is also valid.
Oxigen also recognizes #[location=/path/to/oxigen] as top-of-file metadata and preserves it during formatting. Use it when you want the interpreter path recorded in the file, but keep the real shebang on line 1 if you want ./hello.oxi to work.
#Exploring Indentation Mode
OxigenLang supports two block styles: brace-based (default) and Python-style indentation blocks. To enable indentation mode, add #[indent] near the top of your file. It can appear by itself or after a shebang / #[location=...] header:
#[indent]
main:
x := 10
result := option:
x > 0 -> "positive",
"not positive"
println(x, "is", result)
each i in [1, 2, 3]:
println("Iteration", i)In indentation mode, a colon : at the end of a line starts a new block, and returning to a previous indentation level closes the block. Use main: as the indentation-mode equivalent of main { ... }. See the Control Flow guide for more details on block styles.
#Quick Examples
#Pattern Matching
Define reusable patterns and match against them with choose:
pattern is_even(n) when n % 2 == 0
pattern is_odd(n) when n % 2 != 0
main {
nums := [1, 2, 3, 4, 5]
each n in nums {
choose n {
is_even -> println(n, "is even"),
is_odd -> println(n, "is odd")
}
}
}See the full Pattern Matching guide for details.
#Structs
Define composite data types with typed fields, methods, and inheritance:
struct Person {
name <str>
age <int>
}
Person includes {
fun greet() { println("Hi, I'm " + name) }
fun is_adult() { age >= 18 }
}
struct Student(Person) {
school <str>
}
main {
p := Person("Alice", 30)
p.greet()
println(p.is_adult())
p.age = 15
println(p.is_adult())
s := Student("Bob", 20, "MIT")
s.greet()
println(s.school)
}See the full Structs guide for details.
#Functions
Functions are first-class values in OxigenLang:
fun add(a, b) { a + b }
fun greet(name <str>) {
println("Hello, " + name + "!")
}
double := fun(x) { x * 2 }
main {
println(add(3, 4))
greet("World")
println(double(5))
}See the full Functions guide for details.
#Conditional Expressions
The option keyword provides multi-arm conditional expressions:
main {
age := 25
status := option {
age < 13 -> "child",
age < 20 -> "teenager",
"adult"
}
println(status)
}See the full Control Flow guide for details.
#Next Steps
- Variables and Assignments — how to declare and work with variables
- Data Types — all supported data types and their operations
- Operators — arithmetic, comparison, logical, and postfix operators
- Control Flow — conditionals, loops, guards, and block styles
- Functions — defining and using functions
- Pattern Matching — patterns and choose expressions
- Structs — composite types, methods, and inheritance
- Type System — optional type annotations and mutability control
- Built-in Functions — the standard library of built-in functions
- Imports and Modules — the
introducekeyword and module system - Standard Library — math, strings, array, sets, io, os, path, time, datetime, random, regex, json, toml, encoding, hash, net, api, result, test, ansi, env, parse_args