A compact, explicitly-typed language built for clarity. Write expressive code with minimal syntax and zero ambiguity.
Every feature in Nano Script earns its place. The language is optimized for legibility and predictability — not cleverness.
A small set of keywords and constructs means less to memorize and less to misread. The entire token vocabulary fits on a single page.
Types are always visible. No hidden coercions, no implicit generics. What you write is what the compiler sees.
Run scripts instantly with the interpreter, or compile to native AArch64, x86-64, PE, Mach-O, or WebAssembly binaries.
Structs are plain data. Functions operate on data. There is no inheritance hierarchy to untangle — just shapes and transforms.
Nano Script syntax draws from Swift and Go — familiar, yet stripped to the essentials.
// Variables — type annotation is optional (inferred from value) let a = 1 // i32 by default let pi: f64 = 3.141592653 let hello: str = "hello world" let empty = nil // Primitive types: i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 str
// Functions fn add(a: f64, b: f64): f64 { return a + b } // Recursive functions fn fibonacci(n: i32): i32 { if n == 0 { return 0 } else if n == 1 { return 1 } else { return fibonacci(n - 1) + fibonacci(n - 2) } } // Async functions — stackful coroutines on the same thread async fn download(url: str): str { let response = await fetch(url) return await response.text() }
// Structs are plain data — no methods, no inheritance struct Point { x: f32, y: f32 } // Operator overloading via ops() convention fn ops(+)(lhs: Point, rhs: Point): Point { return Point(lhs.x + rhs.x, lhs.y + rhs.y) } // String formatting via to_str() fn to_str(p: Point): str { return `{p.x}, {p.y}` // template string interpolation } let a = Point(0, 0) let b = Point(1, 1) print(a + b) // → 1, 1
// Type aliases and function types type op_fn = (i32, i32) -> i32 // Block (closure) syntax — capture outer scope implicitly let add_op: op_fn = { a, b in return a + b } // Higher-order functions fn do_op(a: i32, b: i32, op: op_fn): i32 { return op(a, b) } fn main() { let r = do_op(1, 2, add_op) print(`1 + 2 = {r}`) // → 1 + 2 = 3 }
// ref — explicit reference semantics, no hidden aliasing let a = 1.0 let b = ref a // b is a reference to a let c = a // c is a copy of a's value b = 2.0 print(`{a} {b} {c}`) // → 2.0 2.0 1.0 // ref in function signatures — mutate caller data fn upper(s: ref str): ref str { for i in 0 to s.len() { s[i] = s[i].to_upper() } return s } // External function declarations (FFI) ref fn add(a: i32, b: i32): i32
Nano Script ships with a focused set of modules. Import them with use <module> at the top of any file.
print, open, read, write, sqrt, and other libc/libm essentials.
io_image struct (width, height, channels, pixel data) and io_load_image / io_save_image.
kernel fn functions and dispatch them on the GPU — used in the browser playground.
nsm.ns. Use the nsm CLI to create, build, run, and manage packages.
use std use io // Load an image and print its dimensions fn main() { let img = io_load_image("photo.png") print(`width={img.width} height={img.height} ch={img.channels}`) }
use nsm let module = NSModule{ name: "my_app", version: "0.1.0", description: "my first Nano Script app", type: "app", // or "lib" source: "src", dependencies: [ {name: "ref_lib", version: "0.1.0"} ] }
nsm create my_app — scaffold an app. Add --lib for a library.
nsm build compiles. nsm run builds and executes in one step.
nsm add <name> to add a dependency, nsm remove to remove one.
The Nano Script toolchain is a single, self-contained C project — no runtime dependencies, multiple output targets.
Evaluate scripts directly, print the AST or SSA IR, or emit Mach-O, PE, AArch64, or WebAssembly output. Includes a REPL.
LSP-compliant server providing code completion, hover information, and diagnostics for any LSP-compatible editor.
DAP-compatible debug adapter with breakpoints, step-through execution, and variable inspection.
Syntax highlighting, LSP integration, and debugger support for .ns files inside Visual Studio Code.
No install needed. The browser playground runs the full interpreter via WebAssembly.
Open Playground →