Appendix C: Standard Library Reference

This appendix documents every module and function in VibeLang's standard library. Each module includes its stability status, import syntax, and a complete function listing with signatures, descriptions, effects, and examples.

Stability Levels

BadgeMeaning
StableAPI is frozen. Breaking changes require a major version bump.
PreviewAPI is functional but may change. Pin toolchain versions and review changelogs on upgrade.

C.1 io — Input and Output (Stable)

Console output functions. Import: import std.io

All functions require @effect io.

println(message: Str) -> ()

Prints a string to standard output followed by a newline.

VibeLang
import std.io

pub main() -> Int {
  @effect io
  println("Hello, VibeLang!")
  0
}

print(message: Str) -> ()

Prints a string to standard output without a trailing newline.

VibeLang
print("Loading")
repeat 3 { print(".") }
println("")

eprintln(message: Str) -> ()

Prints a string to standard error followed by a newline. Use for diagnostics and warnings.

VibeLang
eprintln("warning: config not found, using defaults")

C.2 core — Deterministic Utilities (Stable)

Pure utility functions with no side effects. Import: import std.core

All functions are pure (no effects). The same inputs always produce the same outputs. Functions in core can be freely memoized, reordered, and inlined by the optimizer.

VibeLang
import std.core

pub double(n: Int) -> Int {
  @ensure . == n * 2
  n * 2
}

C.3 time — Time and Duration (Preview)

Functions for reading the current time and introducing delays. Import: import std.time

now_ms() -> Int

Returns wall-clock time as milliseconds since the Unix epoch.

Effects: nondet

VibeLang
start := time.now_ms()
do_work()
elapsed := time.now_ms() - start
println("took " + elapsed.to_str() + "ms")

sleep_ms(duration: Int) -> ()

Suspends the current task for at least the specified milliseconds.

Effects: nondet

VibeLang
time.sleep_ms(100)

duration_ms(ms: Int) -> Int

Creates a duration value in milliseconds. Pure constructor for readability.

Effects: None.

VibeLang
timeout := time.duration_ms(5000)

C.4 path — File Path Manipulation (Stable)

Pure functions for manipulating file paths as strings. These do not access the file system. Import: import std.path

All functions are pure (no effects).

join(base: Str, segment: Str) -> Str

Joins two path segments with the platform-appropriate separator.

VibeLang
config := path.join("/etc", "app.conf")  // "/etc/app.conf"

parent(p: Str) -> Str

Returns the parent directory. Returns empty string if no parent.

VibeLang
dir := path.parent("/home/user/file.txt")  // "/home/user"

basename(p: Str) -> Str

Returns the final component of a path.

VibeLang
name := path.basename("/home/user/file.txt")  // "file.txt"

is_absolute(p: Str) -> Bool

Returns true if the path is absolute.

VibeLang
path.is_absolute("/usr/bin")   // true
path.is_absolute("src/main")   // false

C.4a text — String utilities (Preview)

Pure string helpers. Import: import std.text. Other text.* functions are listed in the module summary and effects tables below.

index_of(haystack: Str, needle: Str) -> Int

Returns the starting byte index of the first occurrence of needle in haystack, or -1 if needle does not occur. The search is byte-oriented; both arguments must be valid UTF-8.

VibeLang
text.index_of("hello world", "world")  // 6
text.index_of("abc", "xyz")            // -1

C.5 fs — File System Operations (Preview)

Functions for reading and writing files and directories. All functions perform I/O and return Result types. Import: import std.fs

All functions require @effect io.

exists(p: Str) -> Bool

Returns true if a file or directory exists at the given path.

VibeLang
if fs.exists("config.json") {
  println("config found")
}

read_text(p: Str) -> Result<Str, Error>

Reads the entire contents of a file as a UTF-8 string.

VibeLang
pub load_config(path: Str) -> Result<Str, Error> {
  @effect io
  fs.read_text(path)
}

write_text(p: Str, content: Str) -> Result<(), Error>

Writes a string to a file, creating it if it does not exist, overwriting if it does. Parent directories must already exist.

VibeLang
fs.write_text("output.txt", report)?

create_dir(p: Str) -> Result<(), Error>

Creates a directory at the given path.

VibeLang
fs.create_dir(path.join(base, "output"))?

C.6 json — JSON Processing (Preview)

Structured JSON values (Json), text codecs, a canonical streaming builder for dynamic output, and compatibility helpers. Import: import std.json

All functions are pure (no effects).

Value type: Json

json.parse produces a Json value; json.stringify / json.stringify_pretty consume one. Scalar constructors wrap native values:

FunctionSignatureRole
json.null() -> JsonJSON null
json.bool(Bool) -> JsonJSON boolean
json.i64(Int) -> JsonJSON number (integer)
json.f64(Float) -> JsonJSON number (float)
json.str(Str) -> JsonJSON string

parse(raw: Str) -> Json

Parses UTF-8 JSON text into a Json value. Invalid input is handled by the runtime (this is not a Result); validate first with json.is_valid when you need a soft check.

VibeLang
doc := json.parse("{\"a\":1}")
println(json.stringify(doc))              // compact wire text
println(json.stringify_pretty(doc))       // indented, for debugging
println(json.stringify(json.str("vibe"))) // "\"vibe\""

stringify(value: Json) -> Str

Serializes a Json value to compact JSON text (UTF-8 Str).

stringify_pretty(value: Json) -> Str

Same as stringify, with insignificant whitespace added for readability.

json.builder — canonical dynamic construction

For objects and arrays whose shape is computed at runtime, json.builder is the recommended path: you write keys and typed values (value_bool, value_i64, value_f64, value_str, value_null, or nested value_json), not hand-escaped string literals. The builder returns a Str from finish (or you can treat that string as wire text for HTTP, files, and logs).

VibeLang
jb := json.builder.new(128)
jb = json.builder.begin_object(jb)
jb = json.builder.key(jb, "ok")
jb = json.builder.value_bool(jb, true)
jb = json.builder.key(jb, "count")
jb = json.builder.value_i64(jb, 2)
jb = json.builder.key(jb, "items")
jb = json.builder.begin_array(jb)
jb = json.builder.value_str(jb, "a")
jb = json.builder.value_str(jb, "b")
jb = json.builder.end_array(jb)
jb = json.builder.end_object(jb)
body := json.builder.finish(jb)

Typical call sequence: newbegin_object or begin_array → (key + value)* in objects → matching end_*finish. Use value_json to embed an already-built subtree when needed.

Runnable examples: examples/07_stdlib_io_json_regex_http/59_json_builder_object_basics.yb through 62_json_builder_http_post_body.yb, and 47_json_parse_stringify_and_codecs.yb.

Typed codecs: json.encode / json.decode

For nominal type declarations, the compiler generates typed codecs that are invoked through json.encode and json.decode. The compiler infers the struct type from the argument — no type suffix needed. This is the preferred approach for all structured data — API payloads, config objects, domain models:

VibeLang
type Address { city: Str, zip: Int }
type User { id: Int, name: Str, active: Bool, address: Address }

user := User { id: 7, name: "sam", active: true, address: Address { city: "NYC", zip: 10001 } }
wire := json.encode(user)
// {"id":7,"name":"sam","active":true,"address":{"city":"NYC","zip":10001}}

fallback := User { id: 0, name: "fb", active: false, address: Address { city: "", zip: 0 } }
decoded := json.decode(wire, fallback)

Nested struct fields are recursively encoded to JSON objects and recursively decoded back. Missing fields in the JSON fall back to the corresponding field in the fallback value.

json.encode vs json.stringify — when to use which:

  • json.encode(value) takes a typed struct and serializes it to a JSON Str. The compiler knows the fields at compile time.
  • json.stringify(json_val) takes a runtime Json value (from json.parse, json.i64, json.bool, etc.) and converts it to a Str.

Use json.encode when your data has a known shape (which is most of the time). Use json.stringify when working with dynamic/untyped Json values parsed from unknown sources.

is_valid(s: Str) -> Bool

Returns true if the string is syntactically valid JSON.

VibeLang
json.is_valid("{\"name\": \"vibe\"}")  // true
json.is_valid("not json")            // false

parse_i64(s: Str) -> Int / stringify_i64(n: Int) -> Str

Parse or emit a JSON text fragment that is a single integer (compatibility / scalar helpers).

VibeLang
val := json.parse_i64("42")   // 42
json.stringify_i64(42)        // "42"

minify(s: Str) -> Str

Removes insignificant whitespace from a JSON text string.

VibeLang
compact := json.minify("{ \"a\" : 1 }")  // "{\"a\":1}"

from_map(map: Map<Str, Str>) -> Str — convenience / legacy

Serializes a Map<Str, Str> to JSON object text using string values plus heuristic coercion (numeric- and boolean-looking strings become JSON numbers and booleans). Handy when you already have stringly-typed maps; it is not the canonical way to build JSON—prefer json.builder (or Json values + stringify) for structured intent.

VibeLang
preview := {"title": "VibeLang", "score": "95", "active": "true"}
json.from_map(preview)  // {"title":"VibeLang","score":95,"active":true}

C.7 http — HTTP Client and Server (Preview)

Structured HTTP client with HttpRequest/HttpResponse types, plus protocol helpers. These types are defined in stdlib/std/http.yb and loaded automatically.

Built-in types

VibeLang
type HttpRequest {
  method: Str,
  url: Str,
  headers: Str,
  body: Str,
  timeout_ms: Int
}

type HttpResponse {
  status: Int,
  headers: Str,
  body: Str
}

headers uses raw HTTP header format: "Content-Type: application/json\r\nAuthorization: Bearer tok".

send(req: HttpRequest) -> HttpResponse

Full-control HTTP client. Requires @effect net.

VibeLang
req := HttpRequest {
  method: "POST",
  url: "https://api.example.com/data",
  headers: "Content-Type: application/json",
  body: json.encode(MyPayload { name: "test" }),
  timeout_ms: 5000
}
resp := http.send(req)
if resp.status == 200 {
  result := json.decode(resp.body, fallback)
}

get(url: Str, timeout_ms: Int) -> HttpResponse

Convenience GET request. Returns structured HttpResponse.

VibeLang
resp := http.get("https://example.com/api/health", 3000)
println(resp.body)
println(convert.to_str(resp.status))

post(url: Str, body: Str, timeout_ms: Int) -> HttpResponse

Convenience POST request. Returns structured HttpResponse.

VibeLang
type LoginReq { email: Str, password: Str }

resp := http.post("https://api.example.com/login", json.encode(LoginReq { email: "a@b.com", password: "secret" }), 5000)
if resp.status == 200 {
  println(resp.body)
}

ok(resp: HttpResponse) -> Bool

True when resp.status is between 200 and 299 (inclusive).

get_with_headers(url: Str, headers: Str, timeout_ms: Int) -> HttpResponse

GET with a raw header block (same \r\n-separated format as HttpRequest.headers).

post_with_headers(url: Str, headers: Str, body: Str, timeout_ms: Int) -> HttpResponse

POST with explicit headers and body.

post_json(url: Str, body_json: Str, timeout_ms: Int) -> HttpResponse

POST with Content-Type: application/json and the given JSON string body.

get_retry(url: Str, timeout_ms: Int, retries: Int, retry_delay_ms: Int) -> HttpResponse

Calls http.get in a loop. After the first attempt, retries up to retries times when status == 0 (no HTTP response parsed — typical of connection failures), waiting retry_delay_ms between tries (time.sleep_ms). Requires @effect net and @effect io at the call site.

response(resp: HttpResponse) -> Str

Formats an HttpResponse into an HTTP/1.1 wire string for sending over a socket (server use).

VibeLang
wire := http.response(HttpResponse { status: 200, headers: "", body: json.encode(data) })
net.write(conn, wire)

build_response(status: Int, body: Str) -> Str

Convenience server helper — builds a wire-format HTTP response with JSON content type and CORS headers.

status_text(code: Int) -> Str

Returns the standard reason phrase for an HTTP status code.

VibeLang
http.status_text(200)   // "OK"
http.status_text(404)   // "Not Found"

default_port(scheme: Str) -> Int

Returns the default port for a URI scheme.

build_request_line(method: Str, path: Str) -> Str

Constructs an HTTP/1.1 request line from a method and path.

request(method: Str, url: Str, body: Str, timeout_ms: Int) -> Str

Legacy unstructured request — returns body text only. Prefer http.send.

request_status(method: Str, url: Str, body: Str, timeout_ms: Int) -> Int

Returns only the HTTP status code for the request.


C.8 convert — Additional Conversion Functions (Preview)

The core convert functions (to_int, parse_i64, to_float, parse_f64, to_str, to_str_f64) are listed above. The following functions were added to support Float codegen and bit-level operations.

format_f64(value: Float, precision: Int) -> Str

Formats a float with a fixed number of decimal places.

VibeLang
convert.format_f64(3.14159, 2)   // "3.14"
convert.format_f64(1.0, 6)       // "1.000000"

i64_to_f64(n: Int) -> Float

Converts an integer to a float.

VibeLang
f := convert.i64_to_f64(42)   // 42.0

f64_to_bits(f: Float) -> Int

Returns the IEEE 754 bit representation of a float as an integer. Useful for bit-level manipulation (e.g. hash functions, serialization).

VibeLang
bits := convert.f64_to_bits(1.0)   // 4607182418800017408

f64_from_bits(bits: Int) -> Float

Reconstructs a float from its IEEE 754 bit representation.

VibeLang
f := convert.f64_from_bits(4607182418800017408)   // 1.0

C.9 str_builder — String Builder (Preview)

Efficient mutable string construction. Use when building strings incrementally in a loop to avoid O(n²) concatenation. Import: import std.str_builder

All functions are pure (no effects).

new(capacity: Int) -> Int

Creates a new string builder with the given initial capacity. Returns a handle.

VibeLang
sb := str_builder.new(1024)

append(handle: Int, s: Str) -> Int

Appends a string to the builder. Returns the handle.

VibeLang
str_builder.append(sb, "Hello, ")
str_builder.append(sb, "world!")

append_char(handle: Int, ch: Int) -> Int

Appends a single byte (as an ASCII code point) to the builder. Returns the handle.

VibeLang
str_builder.append_char(sb, 10)   // newline

finish(handle: Int) -> Str

Finalizes the builder and returns the built string. The handle is invalidated.

VibeLang
result := str_builder.finish(sb)
println(result)   // "Hello, world!\n"

C.10 regex — Regular Expressions (Preview)

POSIX extended regular expression matching. Import: import std.regex

All functions are pure (no effects).

count(text: Str, pattern: Str) -> Int

Returns the number of non-overlapping matches of pattern in text.

VibeLang
regex.count("abcabc", "abc")   // 2
regex.count("hello", "x")      // 0

replace_all(text: Str, pattern: Str, replacement: Str) -> Str

Replaces all non-overlapping matches of pattern in text with replacement.

VibeLang
regex.replace_all("foo bar foo", "foo", "baz")   // "baz bar baz"

C.11 Module Summary

ModuleStabilityEffects RequiredFunctions
ioStableio3
coreStableNone
timePreviewnondet4
pathStableNone4
fsPreviewio4
netPreviewnet8
convertPreviewNone10
textPreviewNone10
encodingPreviewNone6
jsonPreviewNone13+
httpPreviewnet (client ops)7
logPreviewio3
metricsPreviewalloc / nondet5
envPreviewnondet3
cliPreviewnondet2
str_builderPreviewNone4
regexPreviewNone2
cryptoPreviewnondet (random)5
http_serverPreviewnet3
http_routerPreviewNone (uses http_server)5
wsPreviewnet4
resultPreviewNone4

C.11a crypto — Cryptographic Primitives (Preview)

Hashing, HMAC, random generation, and constant-time comparison.

sha256(data: Str) -> Str

Returns the SHA-256 hash of data as a lowercase hex string.

VibeLang
hash := crypto.sha256("hello world")
// "b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9"

hmac_sha256(key: Str, data: Str) -> Str

Computes HMAC-SHA256 for webhook signature verification and message authentication.

uuid_v4() -> Str

Generates a random UUID v4 string. Requires @effect nondet.

random_bytes(n: Int) -> Str

Generates n cryptographically secure random bytes as a hex string. Requires @effect nondet.

constant_time_eq(a: Str, b: Str) -> Bool

Compares two strings in constant time to prevent timing attacks.


C.11b http_server — HTTP Server Helpers (Preview)

Structured HTTP request parsing and response building for servers.

parse_request(raw: Str) -> HttpServerRequest

Parses a raw HTTP request into a structured HttpServerRequest with method, path, query, headers, and body fields.

format_response(status: Int, headers: Str, body: Str) -> Str

Builds a complete HTTP/1.1 response with correct Content-Length and custom headers.

cors_headers() -> Str

Returns standard CORS headers for API responses.


C.11c http_router — Tiny server routing helpers (Preview)

Pure VibeLang helpers on top of http_server.parse_request / format_response: lookup header and query values, build JSON or plain-text responses with CORS + Content-Type, and dispatch with a handler closure.

header_get(headers: Str, name: Str) -> Str

Returns the trimmed value for a header name, or "" if missing. Header names are matched case-insensitively.

query_get(query: Str, name: Str) -> Str

Returns the value for an exact query key (from the query field of HttpServerRequest), or "" if absent.

json_response(status: Int, body_json: Str) -> Str / text_response(status: Int, body: Str) -> Str

Build full HTTP/1.1 responses with CORS, Content-Type, and correct Content-Length via http_server.format_response.

route(req: HttpServerRequest, method: Str, path: Str, handler: fn(HttpServerRequest) -> Str, fallback: Str) -> Str

When req.method and req.path match, returns handler(req); otherwise returns fallback. Use this to wire a small set of routes without a callback table.


C.11d ws — WebSocket (Preview)

WebSocket handshake and frame handling for real-time communication.

upgrade(conn: Int, raw_request: Str) -> Bool

Performs the WebSocket handshake on an accepted TCP connection.

read_frame(conn: Int) -> Str

Reads and decodes the next WebSocket text frame.

write_frame(conn: Int, data: Str)

Sends a WebSocket text frame.

close_frame(conn: Int)

Sends a WebSocket close frame.


C.11e metrics — In-process counters and gauges (Preview)

Minimal observability for long-running programs: named counters (monotonic sums), gauges (last-written values), and a JSON snapshot for scraping or logging. Storage is per process and in memory (not shared across workers).

Import: metrics are available as the metrics namespace (e.g. metrics.counter_inc).

counter_inc(name: Str, delta: Int) -> ()

Adds delta to the named counter, creating it at zero if needed.

Effects: alloc

counter_get(name: Str) -> Int

Returns the counter value, or 0 if the name was never incremented.

Effects: nondet

gauge_set(name: Str, value: Int) -> ()

Sets the named gauge to value.

Effects: alloc

gauge_get(name: Str) -> Int

Returns the gauge value, or 0 if unset.

Effects: nondet

snapshot_json() -> Str

Returns UTF-8 JSON of the form {"counters":{...},"gauges":{...}} with string keys and integer values.

Effects: alloc

VibeLang
metrics.counter_inc("requests", 1)
metrics.gauge_set("workers", 4)
println(metrics.snapshot_json())

C.11f result — Result Helpers (Preview)

Utilities for working with Result values.

is_ok(result) -> Bool / is_err(result) -> Bool

Check the status of a Result value.

unwrap_or(result, default: Int) -> Int

Extract the Ok value or return a default.

wrap_err(result, context: Str) -> Result

Add context to an error message.


C.11g concurrent — spawn, timeout, parallel map (Preview)

Small helpers on top of go, chan, and time.sleep_ms. No async/await.

spawn(task: fn() -> Int)

Runs go task() (fire-and-forget).

with_timeout(task: fn() -> Int, timeout_ms: Int, fallback: Int) -> Int

Races task() against a timer; first value sent on an internal channel is returned (wall-clock semantics; requires @effect io for sleep).

map_int(items, worker: fn(Int) -> Int, max_workers: Int) -> List<Int>

map_str(items, worker: fn(Str) -> Str, max_workers: Int) -> List<Str>

Bounded parallelism with a token channel; results are written back by index so output order matches input order.

Effects: @effect concurrency; maps declare @effect alloc and @effect mut_state; with_timeout also uses @effect io and @effect alloc.


C.12 Import Quick Reference

VibeLang
import std.io          // println, print, eprintln
import std.core        // deterministic utilities
import std.time        // now_ms, sleep_ms, duration_ms
import std.path        // join, parent, basename, is_absolute
import std.fs          // exists, read_text, write_text, create_dir
import std.net         // listen, listener_port, accept, connect, read, write, close, resolve
import std.convert     // to_int, parse_i64, to_float, parse_f64, to_str, to_str_f64, format_f64, i64_to_f64, f64_to_bits, f64_from_bits
import std.text        // trim, contains, starts_with, ends_with, replace, to_lower, to_upper, byte_len, split_part, index_of
import std.encoding    // hex/base64/url encode/decode
import std.json        // Json: parse, stringify, stringify_pretty, null/bool/i64/f64/str; builder.*; is_valid, minify; parse_i64, stringify_i64; from_map; encode_<T>, decode_<T>
import std.http        // status_text, default_port, build_request_line, request, request_status, get, post, send, response, ok, get_with_headers, post_with_headers, post_json, get_retry
import std.log         // info, warn, error
import std.metrics     // counter_inc, counter_get, gauge_set, gauge_get, snapshot_json
import std.env         // get, has, get_required
import std.cli         // args_len, arg
import std.str_builder // new, append, append_char, finish
import std.regex       // count, replace_all
import std.crypto      // sha256, hmac_sha256, uuid_v4, random_bytes, constant_time_eq
import std.http_server // parse_request, format_response, cors_headers
import std.http_router // header_get, query_get, json_response, text_response, route
import std.ws          // upgrade, read_frame, write_frame, close_frame
import std.result      // is_ok, is_err, unwrap_or, wrap_err
import std.concurrent  // spawn, with_timeout, map_int, map_str

C.13 Effects by Function

FunctionModuleEffects
println(Str)ioio
print(Str)ioio
eprintln(Str)ioio
now_ms()timenondet
monotonic_now_ms()timenondet
sleep_ms(Int)timenondet
duration_ms(Int)timeNone
join(Str, Str)pathNone
parent(Str)pathNone
basename(Str)pathNone
is_absolute(Str)pathNone
exists(Str)fsio
read_text(Str)fsio
write_text(Str, Str)fsio
create_dir(Str)fsio
listen(Str, Int)netnet
listener_port(Int)netnet
accept(Int)netnet
connect(Str, Int)netnet
read(Int, Int)netnet
write(Int, Str)netnet
close(Int)netnet
resolve(Str)netnet
to_int(Str)convertNone
parse_i64(Str)convertNone
to_float(Str)convertNone
parse_f64(Str)convertNone
to_str(Int)convertNone
to_str_f64(Float)convertNone
format_f64(Float, Int)convertNone
i64_to_f64(Int)convertNone
f64_to_bits(Float)convertNone
f64_from_bits(Int)convertNone
trim(Str)textNone
contains(Str, Str)textNone
starts_with(Str, Str)textNone
ends_with(Str, Str)textNone
replace(Str, Str, Str)textNone
to_lower(Str)textNone
to_upper(Str)textNone
byte_len(Str)textNone
split_part(Str, Str, Int)textNone
index_of(Str, Str)textNone
hex_encode(Str)encodingNone
hex_decode(Str)encodingNone
base64_encode(Str)encodingNone
base64_decode(Str)encodingNone
url_encode(Str)encodingNone
url_decode(Str)encodingNone
is_valid(Str)jsonNone
parse(Str)jsonNone
stringify(Json)jsonNone
stringify_pretty(Json)jsonNone
null()str(Str)jsonNone
parse_i64(Str)jsonNone
stringify_i64(Int)jsonNone
minify(Str)jsonNone
from_map(Map<Str, Str>)jsonNone
status_text(Int)httpNone
default_port(Str)httpNone
build_request_line(Str, Str)httpNone
request(Str, Str, Str, Int)httpnet
request_status(Str, Str, Str, Int)httpnet
get(Str, Int)httpnet
post(Str, Str, Int)httpnet
info(Str)logio
warn(Str)logio
error(Str)logio
counter_inc(Str, Int)metricsalloc
counter_get(Str)metricsnondet
gauge_set(Str, Int)metricsalloc
gauge_get(Str)metricsnondet
snapshot_json()metricsalloc
get(Str)envnondet
has(Str)envnondet
get_required(Str)envnondet
args_len()clinondet
arg(Int)clinondet
new(Int)str_builderNone
append(Int, Str)str_builderNone
append_char(Int, Int)str_builderNone
finish(Int)str_builderNone
count(Str, Str)regexNone
replace_all(Str, Str, Str)regexNone