Zornux docs
Get started Spec

Language

Modules & Projects

A Zornux program can span many files. Group related code into modules, decide what each one exposes with public / private, and bring pieces together with import — using the same CLI and editor support you already have.

Declaring a module

A file begins with a module header. Declarations are private by default; mark the ones you want to share public.

zornux
module Math

# Squares a number.
public function square with n
    give back n * n
end

private function helper with n      # stays inside Math
    give back n
end

The same public / private modifier works on classes, services, and top-level values — not just functions:

zornux
public class Product
    has name
    has price
end

public create tax_rate = 0.1

Importing

FormMeaning
import MathBring in a module's public symbols.
import Products.InventoryDotted module names.
import Products.Inventory as InvAlias — use it as Inv.Product.
import Math showing square, cubeImport only the listed public symbols.
zornux
import Math showing square

show "square(5) = " + text(square(5))
Visibility, by default

A declaration is module-private unless you write public. Only public symbols can be imported; a module's own names always take precedence over imported ones.

Aliases & qualified access

As an application grows, two modules may legitimately export the same public name — a validate, a build_all. Flattening both into one scope would collide. import … as gives a module its own local namespace: it does not flatten anything, and you reach its public members by qualified name, alias.member.

zornux
import Packager as packager
import Manifests as manifests

function build_release
    create packages = packager.build_all()   # no clash — each alias
    create files = manifests.build_all()      # is its own namespace
end

Qualified access works for every kind a module exports — functions, values, and types (create user from models.User). Because a member is reached by name, the alias respects visibility: a non-public member can't be reached through it.

Projects

A folder of .zx files is a project. An optional zornux.project file names it — plain key = value lines, no XML or JSON:

text
name = InventorySystem
version = 1.0.0
entry = app.zx
source = src/

Then run, check, build, or serve the whole project at once:

bash
zornux run .
zornux check .
zornux build .

Helpful diagnostics

The compiler builds a module dependency graph and explains problems in plain language (the ZX1300–1399 range): unknown modules, importing a private symbol, duplicate modules, circular imports, and ambiguous names — each pointing at the exact file and line. Aliased, qualified access adds four more:

CodeMeaning
ZX1315No such public member on the aliased module (with a did-you-mean).
ZX1316The member exists but isn't public.
ZX1317Two imports bind the same alias.
ZX1318An alias clashes with a same-named declaration in your file.

Editor support understands modules too: jump to any symbol across files with workspace search, and navigate or rename across open files. See the command line.

Packages

A project can depend on packages — reusable modules from a local registry. Declare them in zornux.project, and a zornux.lock file pins the exact resolved versions. Packages resolve into the same compilation, so a package's public modules are imported just like your own.

text
name = InventorySystem
version = 1.0.0
source = src/

dependency MathTools = ^1.2.0

A version requirement can be exact, a minimum, or a compatible (caret) range:

FormMeaning
MathTools = 1.2.0Exactly version 1.2.0.
MathTools = >= 1.2.01.2.0 or newer.
MathTools = ^1.2.0Compatible with 1.2.0 (same major). A bare version is treated as caret.
bash
zornux init                 # scaffold a new project
zornux add ../math-tools    # add a local package
zornux restore              # resolve dependencies + write the lockfile
zornux run .                # dependencies resolve automatically
Safe by default

Package management runs no install scripts. Names and versions are validated, archive extraction is protected against path-traversal (zip-slip), and the lockfile records a content hash of every package.

For more, see the package manager reference.