Nexo 1.0 Manual
Complete, single-file reference for Nexo v1.0. Syntax, standard modules, CLI, and practical examples.
Quick Start
Run the official starter script:
nexo run docs/hello_real_world.nx
Create your first script:
print("hello")
Run it:
nexo run hello.nx
Installation
- Windows: use the installer or ZIP, add folder to PATH
- Linux/macOS: extract tar.gz,
chmod +x nexo, add to PATH
Hello Real World
This script is the recommended starting point and is included as:
docs/hello_real_world.nx
import log
import re
def extract_title(res):
titles = re.findall("<title>[^<]+</title>", res["body"])
if len(titles) == 0:
return "<no title>"
return re.replace("<[^>]+>", titles[0], "")
"https://example.com" |> http_get |> extract_title |> log.info |> print
Language Basics
Values:
- Number (f64)
- String
- Bool (
true/false) - Null (
null) - Array
- Map
- Function / Closure
Variables:
x = 10
name = "Nexo"
Strings:
print("hello")
print("# is not a comment in strings")
Comments
Single-line comments use # and are ignored by the lexer:
# full line comment
print("ok") # inline comment
Comments do not work inside strings (they are literal text).
Pipelines |>
Pipelines pass the left value into the right expression:
"hello" |> len |> print
Multiline pipelines are supported with indentation:
"https://example.com"
|> http_get
|> len
|> print
- Keep each stage simple.
- Use small functions for readability.
Control Flow
If/else:
if x > 10:
print("big")
else:
print("small")
While loop:
i = 0
while i < 3:
print(i)
i = i + 1
break and continue are supported inside loops.
Functions and Closures
def add(a, b):
return a + b
print(add(1, 2))
Closures capture by value:
def make_adder(x):
def add(y):
return x + y
return add
add5 = make_adder(5)
print(add5(3))
Arrays and Maps
Arrays:
items = [1, 2, 3]
print(items[0])
Maps:
user = {"name": "Ana", "age": 30}
print(user["name"])
Index assignment:
items[1] = 99
user["age"] = 31
Errors and try/catch
Errors are strings. Use try/catch:
try:
print(len(1))
catch e:
print("error: " + e)
Modules and Imports
Import modules by name:
import fs
print(fs.read("file.txt"))
Import a file directly:
import "./my_module.nx"
Module resolution order:
- Relative to the current file
nexo_modulesnext to the current file- Parent
nexo_modules NEXO_MODULES(env var)NEXO_HOME/nexo_modulesnexo_modulesnext to thenexobinary
Exports:
def greet(name):
return "hi " + name
export greet
Builtins
Core
| print(x) | Print value to stdout |
| input() | Read line from stdin |
| len(x) | Length of string, array, or map |
| str(x) | Convert to string |
| int(x) | Convert to integer |
| round(x) / floor(x) / ceil(x) | Rounding functions |
| append(array, value) | Append value to array |
Args
| args() | Array of CLI args |
| arg_has("--flag") | Bool |
| arg_get("--flag", default) | String or default |
Logging
| log_info(x) | Info level |
| log_warn(x) | Warning level |
| log_error(x) | Error level |
JSON
| json_parse(string) | Parse JSON string |
| json_stringify(value) | Convert to JSON string |
File / Process / Env / Time
| fs_read(path) / fs_write(path, data) | Read / write files |
| fs_exists(path) / fs_list(path) | Check / list files |
| proc_run(cmd) | Returns {code, out, err} |
| env_get(key) | Get environment variable |
| time_sleep(ms) / time_now() | Sleep / current timestamp |
HTTP / Regex / Path
| http_get(url) / http_post(url, body, headers) | HTTP requests |
| re_match / re_findall / re_replace | Regex operations |
| path_join(a, b) / path_dirname(path) | Path utilities |
| glob(pattern) | File glob matching |
Standard Modules
These are simple wrappers around builtins.
env
import env
print(env.get("HOME"))fs
import fs
print(fs.exists("config.json"))http
import http
res = http.get("https://example.com")
print(res["status"])log
import log
"hello" |> log.info |> printpath
import path
print(path.join("a", "b"))proc
import proc
print(proc.run("echo hi"))py
import py
print(py.run("script.py", null))re
import re
print(re.findall("[ab]", "abba"))time
import time
time.sleep(500)Interop (FFI and Python)
C FFI:
h = ffi_load("mylib.dll")
print(ffi_call(h, "nexo_square", [3.0]))Python external:
print(py_run("script.py", null))CLI Commands
nexo <file.nx>
nexo run <file.nx|file.nxbc>
nexo --emit <file.nx>
nexo lint [--strict] <file.nx>
nexo fmt <file.nx>
nexo repl [--safe]
nexo lsp
nexo add <github:user/repo[@tag]|url>
nexo add --path <dir>
nexo add --update <name>
nexo remove <name>
nexo bc-upgrade <file.nxbc> [--out <file.nxbc>]
nexo --version
Linting and Formatting
Lint:
nexo lint file.nx
nexo lint --strict file.nxFormat:
nexo fmt file.nxREPL
Start with:
nexo replCommands:
:help
:load
:ast
:bc
:time
:vars
:clear
:pwd
:exit
LSP
nexo lspCapabilities:
- Diagnostics
- Document symbols
- Hover docstrings for functions
Bytecode .nxbc
Compile to bytecode:
nexo --emit script.nxRun bytecode:
nexo run script.nxbcSafe Mode
Safe mode disables builtins that access the file system, network, processes, and interop:
nexo --safe script.nx
nexo repl --safeRecipes
Watch a folder
import fs
import time
dir = "."
prev = fs.list(dir)
prev |> len |> print
i = 0
while i < 3:
time.sleep(500)
cur = fs.list(dir)
if len(cur) != len(prev):
print("change detected")
prev = cur
i = i + 1
print("watch done")CSV to JSON
import re
csv = "name,age\nAna,30"
parts = re.findall("[^,\n]+", csv)
row = {parts[0]: parts[2], parts[1]: parts[3]}
rows = [row]
rows |> json_stringify |> printCLI flags
name = arg_get("--name", "world")
verbose = arg_has("--verbose")
if verbose:
print("hello " + name)
else:
print(name)Simple scraper
import re
def extract_title(res):
titles = re.findall("<title>[^<]+</title>", res["body"])
if len(titles) == 0:
return "<no title>"
return re.replace("<[^>]+>", titles[0], "")
"https://example.com" |> http_get |> extract_title |> printPipeline automation
import re
def normalize(text):
return re.replace("\\s+", text, " ")
out = proc_run("echo alpha beta")
out["out"] |> normalize |> printLogging pipeline
import log
"task start" |> log.info |> print