Skip to content

TuffSeal stdlib Reference

task

wait

Yields the current thread for a specified amount of time.

Usage:

task.wait(time: int); // time should be in seconds.
let task = loadmodule("@stdlib/task")!;

print("Waiting 5 seconds...");
task.wait(5);
print("Done!");

delay

Runs a function after a specified amount of time

Usage:

task.delay(seconds: int, f: fn)
let task = loadmodule("@stdlib/task")!;

fn to_delay()
{
    print("this task was delayed!");
}

task.delay(2, to_delay());

spawn

Creates a new task that runs concurrently.

Usage:

task.spawn(f: fn)
let task = loadmodule("@stdlib/task")!;

fn task_func()
{
    while (true) {
        task.wait(1);
        print("hi!");
    }
}

let new_task = task.spawn(task_func);

defer

Defers a thread or function to run at the end of the current task queue.

Usage:

task.defer(f: fn)
let task = loadmodule("@stdlib/task")!;

fn task1() { print("OK") };
fn task2() { print("OK") };

fn __d()
{
    print("this task runs last.");
}

let task_1 = task.spawn(task1);
let task_2 = task.spawn(task2);
let deferred_thread = task.defer(__d);

cancel

Stops a currently scheduled thread from resuming.

Usage:

task.cancel(thread)
let task = loadmodule("@stdlib/task")!;

fn task_fn()
{
    while (true) {
        task.wait(1);
        print("hello!");
    }
}

let t = task.spawn(task_fn);
task.wait(5);
task.cancel(t); // terminate the task after 5 seconds

stdio

prompt

Prompts for user input using the wanted kind of prompt:

  • text - Prompts for a plain text string from the user.
  • confirm - Prompts the user to confirm with y / n (yes / no)
  • select - Prompts the user to select one or more values from a list
  • null - Equivalent to "text" with no extra arguments

Usage:

stdio.prompt(kind: str, message: str): str
let stdio = loadmodule("@std/stdio")!;

let text = stdio.prompt("text", "Write some text: ");

print(text);

color

Returns an ANSI string that can be used to modify the persistent output color.

Pass "reset" to get a string that resets the persistent output color.

Usage:

stdio.color(color: str): str
let stdio = loadmodule("@std/stdio")!;

print(stdio.color("red"));
print("This text is red!");
print(stdio.color("reset"));
print("This text is back to normal.");

style

Return an ANSI string that can be used to modify the persistent output style.

Pass "reset" to get a string that can reset the persistent output style.

Usage:

stdio.style(style: str): str
let stdio = loadmodule("@std/stdio")!;

print(stdio.style("bold"));
print("This text will be bold!");
print(stdio.style("reset"));

write

Writes a string directly to stdout, without any new line.

Usage:

stdio.write(s: str)
let stdio = loadmodule("@std/stdio")!;

stdio.write("Hello, ");
stdio.write("world!\n");

// both of these will output on the same line.

ewrite

Writes a string directly to stderr, without any new line.

Usage:

stdio.ewrite(s: str)
let stdio = loadmodule("@std/stdio")!;

stdio.ewrite("Error: ");
stdio.ewrite("whatever\n");

// Both of these will output on the same line.

readLine

Reads a single line from stdin.

Usage:

stdio.readLine(): str
let stdio = loadmodule("@std/stdio")!;

print(stdio.readLine());

readToEnd

Reads the entire input from stdin.

Usage:

stdio.readToEnv(): str
let stdio = loadmodule("@std/stdio")!;

print(stdio.readToEnd());

Here is a clean, consistent Markdown documentation section for the fs module in TuffSeal, based on the functions and types you provided:

fs

File system operations module.
Provides synchronous file and directory manipulation.

All functions throw an error on failure (file/directory not found, permission denied, I/O error, invalid operation, etc.).

readFile

Reads the entire contents of a file as a string.

fs.readFile(path: str): str

Throws if: - path does not point to an existing file - no read permission - I/O error occurred

readDir

Returns a list of file and directory names (base names only) in the specified directory.

fs.readDir(path: str): [str]

Throws if: - path is not an existing directory - no read permission - I/O error occurred

Example:

let entries = fs.readDir("scripts");
for (name in entries) {
    print(name);
}

writeFile

Writes (or overwrites) a file with the given content.

fs.writeFile(path: str, contents: str)

Throws if: - parent directory does not exist - no write permission - I/O error occurred

writeDir

Creates a directory and all necessary parent directories (like mkdir -p).

fs.writeDir(path: str)

Throws if: - path already exists as a file or directory - no permission to create directory/parents - I/O error occurred

removeFile

Deletes a file (does not work on directories).

fs.removeFile(path: str)

Throws if: - path is not an existing file - no permission to remove - I/O error occurred

removeDir

Removes a directory and all of its contents recursively.

fs.removeDir(path: str)

Throws if: - path is not an existing directory - no permission to remove - I/O error occurred

Warning: This operation is destructive — use with caution!

metadata

Returns detailed metadata about a file or directory.

fs.metadata(path: str): Metadata

Throws if: - no permission to read metadata - I/O error occurred

Returns: A dictionary with the following keys: - kind: "file", "dir", or "symlink" - exists: bool - createdAt: DateTime (creation time) - modifiedAt: DateTime (last modification time) - accessedAt: DateTime (last access time) - permissions: MetadataPermissions dictionary

Note: Timestamps are Unix epoch based and depend on system clock accuracy.

isFile

Checks whether the path points to a regular file.

fs.isFile(path: str): bool

Throws if: - no permission to read metadata - I/O error occurred

isDir

Checks whether the path points to a directory.

fs.isDir(path: str): bool

Throws if: - no permission to read metadata - I/O error occurred

move

Moves (renames) a file or directory to a new location.

fs.move(from: str, to: str, overwriteOrOptions: bool | WriteOptions = false)

Throws if: - no read permission at source or write permission at destination - target already exists (unless overwrite is true) - source and destination are on different mount points - I/O error occurred

copy

Recursively copies a file or directory to a new location.

fs.copy(from: str, to: str, overwriteOrOptions: bool | WriteOptions = false)

Throws if: - no read permission at source or write permission at destination - target already exists (unless overwrite is true) - I/O error occurred

Types

MetadataPermissions

{
    readOnly: bool
}

Metadata

{
    kind: str,          // "file" | "dir" | "symlink"
    exists: bool,
    createdAt: DateTime,
    modifiedAt: DateTime,
    accessedAt: DateTime,
    permissions: MetadataPermissions
}

WriteOptions

Options for write/move/copy operations:

{
    overwrite: bool     // whether to overwrite existing target (default: false)
    // more keys may be added in future versions
}

Loading the module:

let fs = loadmodule("@std/fs")!;

process

Process management module.
Provides access to current process information, environment, command-line arguments, and the ability to spawn and interact with child processes (synchronously or asynchronously).

Properties

os
The current operating system identifier.
Possible values: "linux", "macos", "windows"

arch
The processor architecture.
Possible values: "x86_64", "aarch64"

endianness
The processor endianness.
Possible values: "little", "big"

args
Array of command-line arguments passed when the script was executed ([str]).

cwd
The current working directory of the running process (str).

env
Table of current environment variables ({ [str]: str? }).
Reading returns the current env vars.
Writing to this table updates the process environment variables.

exit

Immediately terminates the script with the given exit code.
0 indicates success; any other value indicates an error.

process.exit(code: int)

Returns: never

create

Spawns a child process in the background and returns immediately.
Useful when you need to interact with stdin/stdout/stderr while the process runs.

process.create(
    program: str,
    params: [str]? = nil,
    options: CreateOptions? = nil
): ChildProcess

Returns a ChildProcess dictionary containing: - stdinChildProcessWriter - stdoutChildProcessReader - stderrChildProcessReader - kill() → method to forcefully terminate the process - status() → yields until process exits and returns exit code/status

exec

Runs a child process synchronously and waits for it to complete.
Returns the final status and captured output.

process.exec(
    program: str,
    params: [str]? = nil,
    options: ExecOptions? = nil
): ExecResult

Returns an ExecResult dictionary containing: - ok: bool (true if exit code was 0) - code: int (exit code, 0 if none was set) - stdout: str (captured standard output) - stderr: str (captured standard error)

Types

ExecStdioKind

Controls how stdio streams are handled during process.exec.
Possible values: - "default" - capture into result table only - "inherit" - inherit from parent (write to both result and parent's stream) - "forward" - forward to parent's stream only (no capture) - "none" - no stream created

ExecStdioOptions

{
    stdin?: str | buffer,               // input data to send to child stdin
    stdout?: ExecStdioKind,             // how to handle stdout
    stderr?: ExecStdioKind              // how to handle stderr
}

ExecOptions

{
    cwd?: str,                          // working directory for the child
    env?: { [str]: str? },              // additional/modified environment variables
    shell?: bool | str,                 // run in shell (true = default shell, str = specific shell)
    stdio?: ExecStdioOptions | ExecStdioKind
}

CreateOptions

{
    cwd?: str,
    env?: { [str]: str? },
    shell?: bool | str
}

ChildProcess

Returned by process.create.

{
    stdin: ChildProcessWriter,
    stdout: ChildProcessReader,
    stderr: ChildProcessReader,
    kill: fn(),                         // kill the child process
    status: fn(): int                   // yields until exit, returns exit code
}

ExecResult

Returned by process.exec.

{
    ok: bool,
    code: int,
    stdout: str,
    stderr: str
}

ChildProcessReader

Reader for child process output streams (stdout/stderr).

Methods:

read(chunkSize: int? = 1024): str?
Reads up to chunkSize bytes. Returns nil when no more data is available.
May yield if waiting for new data.

readToEnd(): str
Reads all remaining data until the process exits (yields).

ChildProcessWriter

Writer for child process input stream (stdin).

Methods:

write(data: str | buffer)
Writes data to the child’s stdin.

close()
Closes the stdin stream (signals end-of-input to the child).


Loading the module:

let process = loadmodule("@std/process")!;

Most operations are synchronous where possible.
Child process handling is blocking only when using exec or when explicitly waiting via status() / readToEnd().
Future versions may add more advanced process control features (signals, priority, etc.).

serde

Serialization, deserialization, compression, decompression, and hashing utilities.
The serde module provides a clean, high-level interface for common data encoding/decoding and integrity operations.

Functions

encode

Encodes a value into a string using the specified format.

serde.encode(
    format: EncodeDecodeFormat,
    value: any,
    pretty: bool = false
): str
  • pretty is only supported for "json" and "toml" formats

decode

Decodes a string into a TuffSeal value using the specified format.

serde.decode(
    format: EncodeDecodeFormat,
    encoded: str
): any

compress

Compresses a string using the given compression format.

serde.compress(
    format: CompressDecompressFormat,
    s: str,
    level: int? = nil
): str
  • If level is omitted, the best (usually highest) compression level is used
  • Level is automatically clamped to the format’s valid range

decompress

Decompresses a previously compressed string.

serde.decompress(
    format: CompressDecompressFormat,
    s: str
): str

hash

Computes a cryptographic hash of the message and returns it as a lowercase hex string.

serde.hash(
    algorithm: HashAlgorithm,
    message: str
): str

hmac

Computes HMAC (keyed-hash message authentication code) using the given algorithm, message, and secret.
Returns the result as a base64-encoded string.

serde.hmac(
    algorithm: HashAlgorithm,
    message: str,
    secret: str | buffer
): str

Supported Formats & Algorithms

EncodeDecodeFormat

Supported serialization/deserialization formats:

  • "json" – https://www.json.org
  • "yaml" – https://yaml.org
  • "toml" – https://toml.io

CompressDecompressFormat

Supported compression/decompression algorithms:

  • "brotli" – https://github.com/google/brotli
  • "gzip" – https://www.gnu.org/software/gzip
  • "lz4" – https://github.com/lz4/lz4
  • "zlib" – https://www.zlib.net
  • "zstd" – https://github.com/facebook/zstd

HashAlgorithm

Supported hash algorithms:

  • "md5" – https://en.wikipedia.org/wiki/MD5
  • "sha1" – https://en.wikipedia.org/wiki/SHA-1
  • "sha224"
  • "sha256"
  • "sha384"
  • "sha512" – (all part of SHA-2 family)
  • "sha3-224"
  • "sha3-256"
  • "sha3-384"
  • "sha3-512" – (SHA-3 family)
  • "blake3" – https://en.wikipedia.org/wiki/BLAKE3

Loading the module:

let serde = loadmodule("@std/serde")!;

Quick examples:

// JSON pretty-print
let data = { name: "TuffSeal", version: 1.0 };
print(serde.encode("json", data, true));

// Compress & decompress
let original = "very very long text...";
let compressed = serde.compress("zstd", original);
let restored = serde.decompress("zstd", compressed);

// Hashing
print(serde.hash("sha256", "hello world")); // hex string

// HMAC example
let signature = serde.hmac("sha256", "message", "my-secret-key");

All functions throw errors on invalid formats, malformed input, or unsupported operations.

net

Built-in library for network access.
Provides high-level HTTP client/server functionality, WebSocket support, URL encoding/decoding, and low-level TCP socket operations.

Functions

request

Sends an HTTP request and returns the response.

net.request(config: str | FetchParams): FetchResponse
  • Accepts a simple URL string or a full FetchParams dictionary
  • Does not throw on HTTP error status codes (4xx/5xx) — check response.ok instead
  • Throws only on network/connection failures

socket

Connects to a WebSocket server at the given URL.

net.socket(url: str): WebSocket

Throws if: - The server does not support WebSockets - Connection/handshake fails

serve

Starts an HTTP server listening on the given port.

net.serve(port: int, handlerOrConfig: fn | ServeConfig): ServeHandle
  • Non-blocking — returns immediately
  • Server runs until handle.stop() is called
  • Simple usage: pass a handler function
  • Advanced usage: pass a ServeConfig dictionary

urlEncode

URL-encodes a string.

net.urlEncode(s: str, binary: bool = false): str

urlDecode

URL-decodes a string.

net.urlDecode(s: str, binary: bool = false): str

TCP Support

net.tcp.connect

Connects to a remote host/port and returns a TcpStream.

net.tcp.connect(
    host: str,
    port: int,
    config: bool | TcpConfig = false
): TcpStream
  • config can be true for simple TLS, or a full TcpConfig table
  • Throws on connection failure

Types

FetchParams

{
    url: str,                           // required
    method?: str,                       // default: "GET"
    body?: str,
    query?: { [str]: str },
    headers?: { [str]: str },
    options?: FetchParamsOptions
}

FetchParamsOptions

{
    decompress?: bool                   // auto-decompress response (default: true)
}

FetchResponse

{
    ok: bool,                           // true if 200–299
    statusCode: int,
    statusMessage: str,
    headers: { [str]: str },
    body: str
}

ServeRequest

Incoming request in serve handler:

{
    path: str,
    query: { [str]: str },
    method: str,                        // uppercase
    headers: { [str]: str },
    body: str
}

ServeResponse

What your handler should return:

{
    status?: int,                       // 100–599, default 200
    headers?: { [str]: str },
    body?: str
}

ServeConfig

Advanced server configuration:

{
    address?: str,                      // e.g. "http://0.0.0.0"
    handleRequest?: fn(request): ServeResponse,
    handleWebSocket?: fn(ws: WebSocket)
}

ServeHandle

{
    stop: fn()                          // gracefully shuts down the server
}

WebSocket

{
    // When open:
    send: fn(data: str | buffer),
    next: fn(): str?,                   // yields for next message, nil on close
    close: fn(code?: int),

    // Read-only:
    closeCode: int?                     // nil until closed, 1000–4999 after
}

TcpConfig

{
    tls?: bool,                         // enable TLS
    ttl?: int                           // IP time-to-live
}

TcpStream

Low-level TCP/TLS stream:

{
    read: fn(): str?,                   // read available data, may return nil
    write: fn(data: str | buffer),
    close: fn()
}

Loading the module:

let net = loadmodule("@std/net")!;

Quick examples:

// Simple GET
let resp = net.request("https://api.example.com/data");
print(resp.statusCode, resp.body);

// POST JSON
let resp = net.request({
    url: "https://api.example.com/items",
    method: "POST",
    headers: { ["Content-Type"]: "application/json" },
    body: serde.encode("json", { name: "New Item" })
});

// Tiny echo server
net.serve(8080, fn(req) {
    {
        status: 200,
        body: "You said: " + req.body
    };
});

datetime

Date and time manipulation module.
Provides a modern, precise DateTime type with support for multiple time zones (local/UTC), formatting, parsing, and conversions.

Properties (on DateTime instances)

unixTimestamp
number
Seconds since UNIX epoch (1970-01-01 00:00:00 UTC), with fractional part for sub-second precision.

unixTimestampMillis
number
Milliseconds since UNIX epoch.

Constructors

now
Returns the current date and time.

datetime.now(): DateTime

fromUnixTimestamp

Creates a DateTime from a UNIX timestamp (seconds since epoch).
Supports fractional seconds down to nanosecond precision (truncated).

datetime.fromUnixTimestamp(unixTimestamp: number): DateTime

fromUniversalTime
Creates a DateTime from UTC date/time components.

datetime.fromUniversalTime(values: DateTimeValueArguments): DateTime

Throws if the date is invalid (e.g. February 30, non-leap February 29).

fromLocalTime
Creates a DateTime from local date/time components.

datetime.fromLocalTime(values: DateTimeValueArguments): DateTime

Throws on invalid dates (same rules as fromUniversalTime).

fromRfc3339
Parses an RFC 3339 / ISO 8601 date-time string (preferred modern format).

datetime.fromRfc3339(rfc3339Date: str): DateTime

Throws on invalid format.

fromRfc2822
Parses an RFC 2822 date-time string (common in email/HTTP).

datetime.fromRfc2822(rfc2822Date: str): DateTime

Throws on invalid format.

fromIsoDate
DEPRECATED — use fromRfc3339 instead.

Methods (on DateTime instances)

formatLocalTime

Formats as local time using strftime-style pattern.

dt:formatLocalTime(formatString?: str, locale?: Locale): str

Defaults: "%Y-%m-%d %H:%M:%S", "en"

formatUniversalTime

Formats as UTC using strftime-style pattern.

dt:formatUniversalTime(formatString?: str, locale?: Locale): str

toRfc3339

Formats as RFC 3339 string (recommended).

dt:toRfc3339(): str

toRfc2822

Formats as RFC 2822 string.

dt:toRfc2822(): str

toIsoDate
DEPRECATED — use toRfc3339 instead.

toLocalTime

Returns local date/time components as a table.

dt:toLocalTime(): DateTimeValueReturns

Contains: year, month, day, hour, minute, second, millisecond

toUniversalTime

Returns UTC date/time components as a table.

dt:toUniversalTime(): DateTimeValueReturns

Types

Locale
Supported formatting locales:

  • "en" – English
  • "de" – German
  • "es" – Spanish
  • "fr" – French
  • "it" – Italian
  • "ja" – Japanese
  • "pl" – Polish
  • "pt-br" – Brazilian Portuguese
  • "pt" – Portuguese
  • "tr" – Turkish

DateTimeValues / DateTimeValueArguments / DateTimeValueReturns

{
    year: int,        // 1400–9999
    month: int,       // 1–12
    day: int,         // 1–31
    hour: int,        // 0–23
    minute: int,      // 0–59
    second: int,      // 0–60 (60 = leap second)
    millisecond?: int // 0–999 (optional in input, always present in output)
}

Loading the module:

let datetime = loadmodule("@std/datetime")!;

Quick examples:

let now = datetime.now();
print(now:toRfc3339());                    // 2026-01-11T11:30:45.123Z

print(now:formatLocalTime("%A, %d %B %Y")); // Sunday, 11 January 2026

let custom = datetime.fromUniversalTime({
    year = 2025,
    month = 12,
    day = 25,
    hour = 18,
    minute = 30
});

print(custom:toRfc3339());                 // 2025-12-25T18:30:00Z

The datetime module is built for reliability, modern standards (RFC 3339 preferred), and easy localization.
Leap seconds are supported where present in the underlying system.
Future versions may add timezone-aware objects and more locales.

math

Built-in library for mathematical operations.

Functions

abs

Returns the absolute value of n. Returns null if the input is null.

abs(n: int): int
let math = loadmodule("@std/math")!;
print(math.abs(-3));

cos

Returns the cosine of n, which is an angle in radians. Returns a value in [0, 1] range.

cos(n: int): int
let math = loadmodule("@std/math")!;
print(math.cos(67));

cosh

Returns the hyperbolic cosine of n.

cosh(n: int): int

ceil

Rounds n upwards to the next integer boundary.

ceil(n: number): number
let math = loadmodule("@std/math")!;
print(math.ceil(41));

random

Returns a rando, number using the global random number generator. A zero-argument version returns a number in [0, 1] range. A one-argument version returns a number in [1, n] range, The input arguments are truncated to integers, so math.random(1.5) always returns 1.

random(): int
random(n: int): int
random(min: int, max: int): int
let math = loadmodule("@std/math")!;

print(math.random());
print(math.random(5));
print(math.random(10, 60));

round

Rounds n to the nearest integer boundary. If n is exactly halfway between two integers, rounds n away from 0.

round(n: int): int

rad

Converts n from degrees to radians and returns the result.

rad(n: int): int

fmod

Returns the remainder of x modulo y, rounded towards zero. Returns null if y is zero.

fmod(x: int, y: int): int

floor

Rounds n downwards to previous integer boundary.

floor(n: int): int

frexp

Splits the number into a significand (a number in [-1, +1] range) and binary exponent such that n = s * 2^e, and returns s, e

frexp(n: int): (int, int)

max

Returns the maximum number of the input arguments. The function requires at least one input and will error if zero parameters are passed. If one of the inputs is null, the result may or may not be null.

max(list: ...int): int

min

Returns the minimum number of the input arguments. The function requires at least one input and will error if zero parameters are passed. If one of the inputs is null, the result may or may not be null.

min(list: ...int): int

modf

Returns the integer and fractional part of the input number. Both the integer and fractional part have the same sign as the input number, e.g. math.modf(-1.5) returns -1, -0.5.

modf(n: int): (int, int)

map

Returns a value that represents x mapped linearly from the input range (inmin to inmax) to the output range (outmin to outmax)

map(x: int, inmin: int, inmax: int, outmin: int, outmax: int): int

log

Returns logarithm of the input number in the specified base; base defaults to e. Returns null if the input is negative, and negative infinity if the input is 0.

log(n: int, base: int?): int

log10

Returns base-10 logarithm of the input number. Returns null if the input is negative, and negative infinity if the input is 0. Equivalent to `log(n, 10).

log10(n: int): int

lerp

Linearly interpolated between number value a and b using factor t, generally returning the result of a + (b - a) * t. When t is exactly 1, the value of b will be returned instead to ensure that when t is on the interval [0,1] the result of lerp will be on the interval [a,b].

lerp(a: int, b: int, t: int): int

ldexp

Given the significand and a binary exponent, returns a number s * 2^e.

ldexp(s: int, e: int): int

isinf

Returns true if x is positive or negativy infinity (Inf), and false otherwise.

isinf(n: int): bool

isnan

Returns true if x is Not-a-Number (NaN), and false otherwise.

isnan(n: int): bool

isfinite

Returns true if x is a finite number, meaning it is neither NaN nor positive or negative infinity (math.huge).

isfinite(n: int)

pow

Returns x raised to the power of y.

pow(x: int, y: int): int

Values

huge

Positive infinity.

huge: int

pi

Value of pi (~3.14...)