Imports and Modules
OxigenLang has a module system that lets you organize code across files and use the standard library. The introduce keyword (or its shorthand intro) brings modules into scope.
#Standard Library Imports
Use a bare module name to import from the standard library:
introduce math
println(math.sqrt(16))
println(math.abs(-5))This creates a namespace — you access the module's functions through the module name with dot notation.
#Selective Imports
To import specific functions directly into your scope, use curly braces and from:
introduce {sqrt, abs} from math
println(sqrt(16))
println(abs(-5))Selective imports don't require the module prefix.
#Local File Imports
Use a dot prefix to import from local .oxi files relative to the current file:
// Import from ./helpers.oxi (same directory)
introduce .helpers
helpers.my_function()
// Selective import from local file
introduce {my_function} from .helpers
my_function()
// Import from ../utils/format.oxi (parent directory)
introduce ..utils.format.means the current file's directory..means one directory up- Additional dots go further up (e.g.,
...= two directories up) - Dots between names are path separators
#The intro Shorthand
intro is an alias for introduce — they are identical:
intro math
intro {split, join} from strings
intro .helpers#Module Behavior
#Namespacing
Whole-module imports create a namespace object. You access members with dot notation:
introduce math
introduce strings
println(math.pow(2, 10))
println(strings.upper("hello"))#Exports
Top-level bindings (functions, variables, structs, and patterns) are exported by default — public unless you say otherwise. There is no export list; the exception is marked at the declaration with hide.
Use top-level definitions for reusable module APIs, and put script-only work inside main. The main block is skipped when the file is imported with introduce.
#hide — module-private functions
A top-level fun marked hide stays callable inside its own file and is refused across the module boundary:
// text.oxi
hide fun __normalize(s <str>) { strings.trim(strings.lower(s)) }
fun matches(a <str>, b <str>) { __normalize(a) == __normalize(b) }introduce .text
text.matches(" Ada ", "ada") // True — the public face
text.__normalize(" Ada ") // error: '__normalize' is hidden inside module './text'Both routes in are closed, and the error names the reason rather than pretending the function does not exist:
introduce {__normalize} from .text
// error: '__normalize' is hidden inside module './text'
// hint: it is declared `hide fun` and cannot be importedhide applies to top-level functions only — hide x <int> = 1 is a parse error. For struct fields, hide goes inside the struct body; see structs.md.
The stdlib uses it: array.oxi marks _min_index_by and _remove_at hidden, since they are the selection sort behind sort_by rather than part of the module's API.
// mylib.oxi
fun greet(name) { "Hello, {name}!" }
PI := 3.14159// main.oxi
introduce .mylib
main {
println(mylib.greet("World"))
println(mylib.PI)
}#Module Caching
Each module file is evaluated only once. If multiple files import the same module, they share the same module object. This means module-level state is shared.
#Circular Import Detection
If file A imports file B which imports file A, OxigenLang will produce a clear error:
Error: circular import detected: /path/to/file.oxiRestructure your code to avoid circular dependencies.
#Standard Library Modules
OxigenLang ships with the following standard library modules:
| Module | Description |
|---|---|
math | Math functions (abs, sqrt, pow, floor, ceil, etc.) |
strings | String manipulation (split, join, trim, upper, etc.) |
array | Array operations (map, filter, reduce, sort, etc.) |
sets | Set algebra (union, intersection, difference, etc.) |
io | File I/O (read_file, write_file, etc.) |
os | OS interaction (exec, env vars, directories, etc.) |
path | File path manipulation and containment checks |
time | Timestamps, sleep, elapsed time measurement |
datetime | UTC calendar dates: format, parse, components |
random | Random number generation |
regex | Regular expressions (Rust regex syntax) |
json | JSON parsing, serialization, dotted-path access, and merging |
toml | TOML parsing, serialization, dotted-path access, and merging |
encoding | Base64, hex, and URL percent-encoding |
hash | SHA-256, SHA-1, MD5 hex digests |
net | HTTP client, streaming HTTP, TCP and UDP sockets |
api | HTTP server: routing, JSON responses, accept loop |
result | Helpers for the Error || Value system |
test | expect(...) matchers used by oxigen test |
ansi | Terminal colour, modifiers, cursor control |
env | Load a .env file into a map |
parse_args | Command-line flag parsing |
See the Standard Library Reference for full details on each module.
#Examples
#Using multiple modules together
introduce json
introduce net
introduce io
// Fetch JSON from an API
resp := net.get("https://api.example.com/data")
data := json.parse(resp["body"])
// Save to file
io.write_file("data.json", json.stringify(data))#Building a utility with local imports
// utils/format.oxi
fun pad_left(s, width, ch) {
result := s
repeat when len(result) < width {
result := str(ch) + result
}
result
}// main.oxi
introduce .utils.format
main {
println(format.pad_left("42", 5, "0"))
}