Skip to content

Standard Library

All system functions in NSL are organized into namespaces. These namespaces serve dual purposes:

  1. Organization: Grouping related functions logically
  2. Security: Namespace prefixes act as keywords, preventing user code from shadowing system functions

The Library Registry defines every available function, its namespace, parameters, return type, and the Kotlin implementation behind it. This registry is the single source of truth for both the compiler (semantic validation) and the VM (execution). It is populated at startup from built-in libraries and any registered plugins.

All File operations trigger the Permission Bridge. The script must receive explicit permission before any file system access.

FunctionSignatureDescription
File.readstring File.read(string path)Read the entire contents of a file as a string
File.writevoid File.write(string path, string content)Write content to a file (creates or overwrites)
File.appendvoid File.append(string path, string content)Append content to an existing file
File.deletevoid File.delete(string path)Delete a file
File.existsboolean File.exists(string path)Check whether a path exists
File.liststring[] File.list(string dir)List entries in a directory
File.metadatajson File.metadata(string path)Get size, timestamps, and type for a path
File.createDirvoid File.createDir(string path)Create a directory (and parents)
string[] entries = File.list("/data/");
foreach (string name in entries) {
json meta = File.metadata(`/data/${name}`);
yield `${name}: ${meta.getInt("size", 0)} bytes`;
}
string content = File.read("/data/config.json");
File.append("/output/log.txt", `Loaded config at ${Date.now()}\n`);
Script: File.read("/data/secret.txt")
VM: requestPermission(PermissionRequest.File.Read("/data/secret.txt"))
Host: Pattern-match on request type -> FileGrant(allowedDirectories, allowedExtensions, ...) / Denied
ConstraintTypeEffect
maxBytesLong?Maximum file size the operation may read/write
rewrittenPathString?Redirect the path to a safe location
allowedDirectoriesList<String>?Restrict access to specific directories
allowedExtensionsList<String>?Restrict to specific file extensions
readOnlyBooleanDeny any write/append/delete attempt

All Http operations trigger the Permission Bridge.

FunctionSignatureDescription
Http.getstring Http.get(string url)Perform an HTTP GET, return response body as string
Http.getJsonjson Http.getJson(string url)GET and parse response as JSON
Http.poststring Http.post(string url, string body)Perform an HTTP POST, return response body
Http.putstring Http.put(string url, string body)Perform an HTTP PUT, return response body
Http.deletestring Http.delete(string url)Perform an HTTP DELETE, return response body
json data = Http.getJson("https://api.example.com/users");
yield `Received ${data.size()} users`;
string result = Http.put("https://api.example.com/users/42", `{"name": "Alice"}`);
ConstraintTypeEffect
maxResponseSizeLong?Maximum response body size in bytes
timeoutMsLong?Maximum time to wait for a response
allowedDomainsList<String>?Restrict requests to specific domains
allowedPortsList<Int>?Restrict to specific ports (e.g. [443])
httpsOnlyBooleanDeny any plain HTTP request

All Env operations trigger the Permission Bridge. Environment variables can carry secrets; system properties can be used for fingerprinting.

FunctionSignatureDescription
Env.getstring? Env.get(string name)Read an environment variable (returns null if not set)
Env.systemstring? Env.system(string property)Read a system property (e.g. "os.name", "os.arch")
string? apiKey = Env.get("API_KEY");
if (apiKey == null) {
return "Missing API_KEY environment variable";
}
string os = Env.system("os.name");
yield `Running on ${os}`;
ConstraintTypeEffect
allowedVarNamesList<String>?Restrict which variable/property names are readable

No permissions required. All Math functions are pure computations.

FunctionSignatureDescription
Math.sqrtdouble Math.sqrt(double x)Square root
Math.absdouble Math.abs(double x)Absolute value
Math.mindouble Math.min(double a, double b)Minimum of two values
Math.maxdouble Math.max(double a, double b)Maximum of two values
Math.floorint Math.floor(double x)Floor (round down)
Math.ceilint Math.ceil(double x)Ceiling (round up)
Math.roundint Math.round(double x)Round to nearest integer
Math.randomdouble Math.random()Random value in [0.0, 1.0)
Math.powdouble Math.pow(double base, double exp)Exponentiation
double hypotenuse = Math.sqrt(Math.pow(3.0, 2.0) + Math.pow(4.0, 2.0));
// hypotenuse = 5.0
int randomIndex = Math.floor(Math.random() * 100.0);

No permissions required.

FunctionSignatureDescription
Date.nowint Date.now()Current Unix timestamp in milliseconds
int start = Date.now();
// ... do work ...
int elapsed = Date.now() - start;
yield `Operation took ${elapsed}ms`;

No permissions required.

FunctionSignatureDescription
Json.parsejson Json.parse(string text)Parse a JSON string into a json value
Json.stringifystring Json.stringify(json value, boolean pretty = true)Serialize a json value to a JSON string
string raw = Http.get("https://api.example.com/data");
json data = Json.parse(raw);
string name = data.getString("name", "unknown");
json response = {status: "ok", count: 42};
// Pretty-printed by default
string body = Json.stringify(response);
// {
// "status": "ok",
// "count": 42
// }
// Compact output
string compact = Json.stringify(response, false);
// {"status":"ok","count":42}
Http.post("https://api.example.com/submit", compact);
  • Integers without decimals parse as int, with decimals as double
  • Json.stringify preserves this distinction (42 vs 42.0)
  • NaN and Infinity serialize as null (per JSON spec)

Primitive types and arrays have “methods” available through UFCS. These are defined in the Library Registry and linked to specific types rather than namespaces.

MethodSignatureDescription
.length()string -> intNumber of characters in the string
.upper()string -> stringConvert to uppercase
.lower()string -> stringConvert to lowercase
.contains(sub)string -> booleanCheck if substring exists
.split(delim)string -> string[]Split into array by delimiter
string text = "Hello, World!";
int len = text.length(); // 13
string upper = text.upper(); // "HELLO, WORLD!"
string lower = text.lower(); // "hello, world!"
boolean has = text.contains("World"); // true
string[] parts = text.split(", "); // ["Hello", "World!"]
MethodSignatureDescription
.length()T[] -> intNumber of elements in the array
.push(item)voidAppend an element to the end
.pop()TRemove and return the last element
int[] numbers = [1, 2, 3];
int len = numbers.length(); // 3
numbers.push(4); // [1, 2, 3, 4]
int last = numbers.pop(); // last = 4, numbers = [1, 2, 3]

See Type System, The json Type for the full reference.

MethodSignatureDescription
.getString(key, default)stringGet string value or default
.getInt(key, default)intGet integer value or default
.getBool(key, default)booleanGet boolean value or default
.getDouble(key, default)doubleGet double value or default
.getJSON(key, default)jsonGet nested JSON or default
.getObject(key, default)typedGet and typecheck against default
.has(key)booleanCheck if key exists
.keys()string[]Get all top-level keys
.size()intNumber of keys (object) or elements (array)
.setString(key, value)voidSet a string value
.setInt(key, value)voidSet an integer value
.setBool(key, value)voidSet a boolean value
.setDouble(key, value)voidSet a double value
.setJson(key, value)voidSet a nested json value
.remove(key)voidRemove a key from the object
.getIntArray(key, default)int[]Extract typed integer array or default
.getStringArray(key, default)string[]Extract typed string array or default
.getDoubleArray(key, default)double[]Extract typed double array or default
.getArray(key, Type, default)Type[]Extract and cast each element to struct type
json response = {};
response.setString("status", "ok");
response.setInt("count", 42);
response.setBool("active", true);
json meta = {};
meta.setDouble("score", 3.14);
response.setJson("meta", meta);
// Serialize: {"status": "ok", "count": 42, "active": true, "meta": {"score": 3.14}}
string body = Json.stringify(response, false);
// Remove a key
response.remove("active");
json data = Http.getJson("/api/report");
// Extract typed arrays safely
int[] ids = data.getIntArray("ids", []);
string[] labels = data.getStringArray("labels", []);
// Extract struct-typed arrays (each element is cast)
ReportItem[] items = data.getArray("items", ReportItem, []);
// Iterate over json as an array
json rows = data.getJSON("rows", []);
for (int i = 0; i < rows.size(); i++) {
json row = rows[i]; // index access on json array
string name = row.getString("name", "unknown");
}
NamespaceRequires PermissionRequest Type
File.*YesPermissionRequest.File.*
Http.*YesPermissionRequest.Http.*
Env.*YesPermissionRequest.Env.*
Math.*No
Date.*No
Built-in methodsNo

In addition to namespace-scoped libraries, NSL provides methods bound directly to types for explicit conversion. See Type System, Type Conversion for full details.

MethodReturnsDescription
.toDouble()doubleWidening conversion
.toString()stringString representation
MethodReturnsDescription
.toInt()intTruncation toward zero
.toString()stringString representation
MethodReturnsDescription
.toInt(default)intParse as integer; return default on failure
.toDouble(default)doubleParse as double; return default on failure

The standard library is not fixed. Developers can create custom namespaces and functions using the @NoxModule Plugin API. See Plugin Development Guide for details.