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:

hello.nx
print("hello")

Run it:

nexo run hello.nx

Installation


Hello Real World

This script is the recommended starting point and is included as:

docs/hello_real_world.nx

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:

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

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:

  1. Relative to the current file
  2. nexo_modules next to the current file
  3. Parent nexo_modules
  4. NEXO_MODULES (env var)
  5. NEXO_HOME/nexo_modules
  6. nexo_modules next to the nexo binary

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_replaceRegex 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 |> print

path

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.nx

Format:

nexo fmt file.nx

REPL

Start with:

nexo repl

Commands:

:help :load :ast :bc :time :vars :clear :pwd :exit

LSP

nexo lsp

Capabilities:


Bytecode .nxbc

Compile to bytecode:

nexo --emit script.nx

Run bytecode:

nexo run script.nxbc

Safe Mode

Safe mode disables builtins that access the file system, network, processes, and interop:

nexo --safe script.nx
nexo repl --safe

Recipes

Watch a folder

watch.nx
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

csv_to_json.nx
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 |> print

CLI flags

cli_flags.nx
name = arg_get("--name", "world")
verbose = arg_has("--verbose")
if verbose:
    print("hello " + name)
else:
    print(name)

Simple scraper

scraper.nx
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 |> print

Pipeline automation

pipeline.nx
import re
def normalize(text):
    return re.replace("\\s+", text, " ")
out = proc_run("echo alpha   beta")
out["out"] |> normalize |> print

Logging pipeline

logging.nx
import log
"task start" |> log.info |> print

Nexo v1.0 · Home · GitHub

Copied to clipboard