Getting Started
OverviewLanguage GuideFull Reference
Book
Table of ContentsIntroductionPrefaceGetting StartedLanguage TourOwnershipErrorsConcurrencyStdlibNetworkingDataPackagesSpeed & SafetyCross-PlatformToolingCookbookAppendix
Reference
Standard LibraryKeywordsPerformanceSecurityBuilt-in FunctionsStatusDebuggingABI
How-To
Getting StartedHTTP APIsErrorsPackagesConcurrencyMemoryWASITestingRelease Builds
Project
RoadmapVisionChangelogContributing

Makori standard library

Makori is its own language with its own syntax and ownership model. Standard library parity means safe capability coverage, not Go/Rust syntax cloning and not importing their unsafe surfaces.

Batteries for web and backends, with naming conventions adapted to Makori.

Product tip: 0.6.5. Application packs have Go-equivalent surfaces (2026-08-18 wave) — snake_case, no panic-on-OOB, Result / (value, err) instead of nil. Not a syntax clone and not every Go toolchain package. Lower-level hot path remains builtins over C runtime headers.

Memory-safety bar: safe stdlib APIs must be memory safe by construction. C/OS/crypto/compression-backed code is allowed only behind checked wrappers with documented ownership, cleanup, bounds, and handle lifecycle rules. Raw-memory or unverifiable behavior is excluded from safe parity or isolated behind an explicit unsafe boundary. See STDLIB_SAFETY.md. Package-level classification is tracked in STDLIB_SAFETY_MATRIX.md.

Default-safe means safe plus audited checked-native packages with package-local evidence and passing hard gates. unsafe-boundary packages (os/exec, plugin, runtime, syscall) and external/environmental behavior are excluded from that claim unless a future release hardens and reclassifies them.

Call builtins directly (str_split, path_join, …) or import std packages:

import "strings"
import "path"
import "sync"

let s = strings.concat(strings.split("a,b", ","), "-")
let p = path.clean("/a/../b")
let m = sync.rwmutex()

Bare names like import "strings" resolve under std/ (override with MAKO_STD) and auto-alias so strings.split works. Relative import "./x.mko" unchanged. Note: method names that are keywords (join, match, …) use aliases (concat, matches, join_path).

Performance bar: fast and lean on the same hardware — no mandatory GC, arena-per-request, few copies, structured concurrency.

Book (stdlib chapter): book/src/ch07-stdlib.md · Working APIs with syntax: GUIDE.md · How-tos: howto/ · North star: VISION.md · Honest matrix: STATUS.md · Queue: ROADMAP.md.

Runtime: runtime/mako_rt.h, runtime/mako_stdlib.h, runtime/mako_std.h, runtime/mako_http.h, runtime/mako_db.h, runtime/mako_security.h.

Tests: examples/testing/stdlib_*, stdlib_parity_*_test.mko, plus area tests (base64_test, regex_*, errors_test, path_join_test, …). Demo: examples/stdlib/demo.mko. The claims gate also runs scripts/stdlib-gate.sh, which type-checks every checked-in std/**/*.mko package file so a stale wrapper cannot remain hidden because no application imports it. This proves package-surface validity, not symbol-for-symbol parity with Go or any optional platform integration. A package is not complete for safe parity until it also satisfies the stdlib memory-safety gate.


Package index (synced 2026-08-18 · Go-equivalent + wave 3)

Mako names are snake_case and keyword-safe (concat not join, matches not match). Indexes never panic: searches return −1, slices clamp. Parse failures are Result, never nil pointers.

Package Status Role
strings / bytes Done search/cut/split_n/fields_fn + []byte index/compare/clone
strconv / fmt / print Done parse/format + quote/unquote/is_print
io / io/fs / path / filepath Done Limit/Section readers, walk, glob matches, rel/abs
bufio Done buffered reader/writer + scan_lines
os / os/env / os/user / os/exec / os/signal Done env expand/lookup, uid/home, exec, signal Unix
flag Done CLI flags
net / net/netip / http / cookiejar / httputil / httptrace / net/url / net/mail / net/smtp Done host/port, IPv4/IPv6/prefix, HTTP, MIME/SMTP
encoding/* + ascii85 / pem / gob / binary / yaml / toml / cbor / msgpack / avro / protobuf Done wire + config + binary codecs
compress/gzip · flate · zlib · lzw · bzip2 · archive/tar · archive/zip Done C hot path; bzip2 optional
mime / multipart / quotedprintable · context · crypto Done context values are string pairs (with_value / value)
math / math/bits / math/cmplx / math/big / rand Done bits, complex pairs, big.Int add/mul, shuffle/perm
text/template / html/template / text/tabwriter / text/scanner Done Go-style engine + tab align + token scan
html · utf8 · utf16 · unicode · sync / atomic · slices / maps / cmp · iter · unique Done UCD + UTF-16 + compare + intern
errors / testing / httptest / quick / fstest / slogtest / regexp / regexp/syntax / log / slog / sql Done RE2-ish + property checks + MapFS
hash / hash/crc32 / hash/adler32 / hash/fnv Done IEEE CRC-32, Adler-32, FNV-1/1a
index/suffixarray Done suffix index + lookup
image / image/color / draw / png / gif / jpeg Done Point/Rect + LZW dict; DCT + Huffman; JFIF
reflect Done POD value bag (N fields + nested POD flatten) + clone/equal; map fields rejected
plugin Done product host (std/plugin): load/call/meta/reload/manifest + live dylib
syscall Done portable OS primitives (std/syscall): pid/uid/host/pipe/dup/…
time Done clocks + calendar + parse/format + Go-style parse_duration
timer Done general deadline min-heap (timer_heap_*) — protocol-agnostic
peer Done general named peers + string-key routes (peer_table_*)
sctp Done general SCTP transport (streams/PPID/HB/multihome where kernel allows)
dtls Done DTLS 1.2 over UDP + SRTP key export + fingerprints (WebRTC building block)
diameter Optional pack RFC 6733 codec + optional managers; one protocol over general primitives
collections Done List[T]=[]T + set/heap/ring/stack/queue/stats
graphql Done seed HTTP body query/vars, field list, data/error JSON (MESSAGING_GRAPHQL.md)
messaging Done seed In-process message queues mq_* (MESSAGING_GRAPHQL.md)
embed Done helper (not compile-time)

Runtime: mako_rt.h + mako_goext.h (Waves 1–9). Tests: goext_wave{,3,4,5,6,7,8,9}_test.mko, stdlib_parity_*_test.mko.

Go package → Mako equivalent (adversarial)

This is capability parity, not a syntax clone. Preferred surface is fn / let / on / pack / pull.

Go Mako pack Notes
strings / bytes strings / bytes concatJoin; cut returns (head, tail, ok)
slices / maps / cmp / sort same names typed monomorphs; OOB clamps
strconv strconv quote / unquote / is_print
io / io/fs io / io/fs LimitReader / SectionReader / FileInfo
path / path/filepath path / path/filepath matchesMatch
os / os/user os / os/env / os/user lookup / expand / current
net / net/netip net / net/netip split_host_port, parse_addr, prefixes
math / bits / cmplx / big math / math/bits / math/cmplx / math/big complex is a Complex pair
hash/crc32 / adler32 / fnv / crc64 same CRC-64 ECMA is a C builtin; result is int bits (do not uint64() a negative pattern)
encoding/ascii85 / pem same Adobe ASCII85 + PEM wrap
mime/quotedprintable same RFC 2045
unicode/utf16 same surrogate pairs, U+FFFD
text/tabwriter / scanner same column pad + token scan
index/suffixarray same naive build, lookup
time.ParseDuration time.parse_duration result in milliseconds
sync.Once sync.once / do_once CAS handle + fn() -> int
unsafe / raw pointer APIs / unchecked memory primitives won't conflicts with safe Mako
weak / go/* / debug/* won't / blocked Go toolchain or binary-parser surfaces; only bounded safe data parsers may be reconsidered
compress/{flate,zlib,bzip2,lzw} Done C zlib/flate/LZW hot path; bzip2 when MAKO_BZ2
crypto/{rsa,ecdsa,md5,sha3} Done MD5/SHA3-256 C; ES256/RS256 via existing JWT/OpenSSL
crypto/{rand,hkdf,pbkdf2} Done CSPRNG / RFC 5869 / PBKDF2-HMAC-SHA256; no RSA keygen
context.WithValue context.with_value string pairs only; later key shadows
time.LoadLocation time.load_location fixed-offset table (EST/JST/…), not IANA tzdb
math/rand.Shuffle / Perm rand.shuffle / perm Fisher–Yates; empty/n<=0 → empty
image.Point / Rectangle image half-open [min, max)
testing/quick / fstest / slogtest same predicates return int 1/0
regexp/syntax same literal/meta + quote; not a parse tree
net/http/httptrace same event log, does not hook the client

New pack APIs (2026-08-18)

pull "strings"
pull "strconv"
pull "slices"
pull "cmp"
pull "math/bits"
pull "math/cmplx"
pull "math/big"
pull "hash/crc32"
pull "net/netip"
pull "time"
pull "sync"
pull "os/env"

fn main() {
    let head, tail, ok = strings.cut_ok("a=b=c", "=")
    let q = strconv.quote("a\nb")
    let text, err = strconv.unquote(q)

    let i, found = slices.binary_search([1, 3, 5], 3)
    assert_eq(cmp.compare_int(1, 2), -1)

    assert_eq(bits.ones_count64(7), 3)
    let z = cmplx.rect(3.0, 4.0)
    let n, e = big.from_string("1000000000000")

    assert_eq(crc32.checksum_ieee("123456789"), 0xCBF43926)

    let addr, ae = netip.parse_addr("10.1.2.3")
    let pref, pe = netip.parse_prefix("10.0.0.0/8")

    match time.parse_duration("1h30m") {
        Ok(ms) => print_int(ms)   // 5400000
        Err(_) => {}
    }

    let once = sync.once()
    // do_once takes fn() -> int; first call runs it, later calls return 0

    let _ = env.set("K", "v")
    print(env.expand("x=$K"))     // x=v
}

Wave 3 (CSPRNG, HKDF, context values, named offsets):

pull "crypto/rand" as crand
pull "crypto/hkdf"
pull "context"
pull "math/rand"
pull "time"

fn main() {
    print_int(len(crand.read(16)))
    let ctx = context.background().with_value("user", "ada")
    print(ctx.value("user"))
    rand.seed(1)
    print_int(len(rand.perm(5)))
    print_int(time.load_location("EST"))   // -18000
}

Tests: examples/testing/stdlib_parity_core_test.mko, stdlib_parity_packs_test.mko, stdlib_parity_io_test.mko, stdlib_parity_os_test.mko, stdlib_parity_net_test.mko, stdlib_parity_time_sync_test.mko, stdlib_parity_gap_test.mko, stdlib_parity_adversarial_test.mko, stdlib_parity_wave3_test.mko.


Event Loop (mako_evloop.h)

Non-blocking I/O multiplexing (epoll/kqueue):

Builtin Role
evloop_new / evloop_close Create / destroy event loop
evloop_add / evloop_mod / evloop_del Register / modify / remove fd
evloop_wait(el, timeout_ms) Wait for events, returns count
evloop_event_fd / evloop_event_flags Inspect ready events by index
nb_listen / nb_accept / nb_read / nb_write / nb_close Non-blocking TCP helpers
nb_udp_bind / nb_udp_recv Non-blocking UDP helpers

Game UDP (mako_game.h)

High-performance UDP networking for game servers:

Builtin Role
game_udp_bind / game_udp_close Bind / close game UDP socket
game_udp_recv / game_udp_sender Receive packet, get sender peer ID
game_udp_send / game_udp_broadcast Send to peer / broadcast to all
game_udp_kick / game_udp_peers Disconnect peer / count peers
game_udp_fd Raw fd for event loop integration
tick_now_us / tick_sleep_us Microsecond tick timing

Cloud / Distributed (mako_cloud.h)

Primitives for distributed services:

Builtin Role
chash_new / chash_get / chash_add_node / chash_remove_node / chash_node_count / chash_free Consistent hash ring
ratelimit_new / ratelimit_allow / ratelimit_remaining / ratelimit_free Token-bucket rate limiter
breaker_new / breaker_allow / breaker_success / breaker_failure / breaker_state / breaker_reset / breaker_free Circuit breaker

HTTP Engine (mako_httpengine.h)

High-level HTTP server with declarative routing:

Builtin Role
httpengine_new / httpengine_free Create / destroy engine
httpengine_route(e, method, path, handler_id) Register route
httpengine_start(e, port) Start listening
httpengine_stop(e) Stop engine

Core APIs (Wave 1–9)

Builtin Package
flag_string / flag_int / flag_bool flag
exec_output / exec_run os/exec
url_scheme / host / path / query / query_escape net/url
csv_split_line / csv_join_row encoding/csv
xml_escape / xml_tag_text / html_escape encoding/xml · html
gzip_compress / decompress / available compress/gzip
tar_write_file / tar_first_name archive/tar
mime_type mime
context_with_timeout / expired / remaining context
bytes_buffer* bytes
rand_seed / rand_intn / rand_float math/rand
tmpl_data_* / tmpl_new / tmpl_execute / tmpl_html_* text/html templates (Go-style)
template_execute text/template (legacy one-key)
base32_encode · sha1 · sha512 encoding/base32 · crypto
lookup_host / parse_ip_ok / dns_* net / DNS and address helpers
signal_notify / signal_received os/signal
atomic_* sync/atomic
utf8_valid / utf8_rune_len / encode·decode / constants unicode/utf8
unicode_is_* / unicode_to_* / unicode_is(prop,r) unicode (Unicode 17 UCD)
unicode_nfc / nfd / nfkc / nfkd unicode (Unicode 17 normalization)
list_* / stack_peek_* / queue_pop_* / slices_*_strs collections / List[T]
plugin_open / call / close / info·error·slots / hot-reload plugin
filepath_walk / filepath_walk_n path/filepath
slices_reverse / slices_unique slices
embed_file embed helper
zip_write_file / zip_first_name / zip_read_file / zip_deflate_available archive/zip
png_* / gif_* / jpeg_* image
maps_keys / values / clear / clone / equal / copy maps
reflect_* / reflect_struct_* reflect
httptest_serve_once / get / status / header testing/httptest
aead_available / aes_gcm_* / chacha20_poly1305_* crypto
multipart_boundary / multipart_form_value / multipart_file_* mime/multipart
regex_find_all / replace* / valid / quote_meta regexp
html_template_* html/template (legacy helpers)
gob_encode_* / gob_decode_* / gob_*_map_ss encoding/gob
mail_parse_address / mail_header_get / mail_address_ok net/mail
smtp_format_message / smtp_send_soft net/smtp
binary_put_u*le / binary_u*le encoding/binary
zip_create / zip_add / zip_write_to / zip_list archive/zip
reflect_value_* reflect
jpeg_encode_gray_dct / gif_encode_rgb_lzw image
slog_* / log_* strong structured logging (mako_log.h: JSON/logfmt, levels, multi-field)
slog_redact / slog_with_redacted / slog_set_json / slog_set_output redaction, format, file sink
metric_* / gauge_* / hist_* / metrics_export / metrics_export_prom / metrics_export_otlp_json process-local metrics + Prometheus + OTLP JSON
trace_id / begin / end / trace_export_json / trace_export_otlp_json / trace_span_id span-lite + OTLP/HTTP JSON seed
profile_snapshot_json / stack_trace / crash_report_install / process_rss_bytes observability depth seeds
error_trace / error_wrap_trace / error_message / error_cause / error_chain error tracing with source locations
mldsa44_keygen / mldsa65_keygen / mldsa87_keygen / mldsa_sign / mldsa_verify ML-DSA post-quantum signatures (FIPS 204)
mldsa_self_signed_cert / mldsa_verify_cert / tls_server_pqc / tls_enable_pqc PQC X.509 + TLS 1.3
json_f / json_b / json_get_float / json_get_bool JSON float/bool marshal/unmarshal
uuid_v1 / uuid_v6 / uuid_v8 / uuid_timestamp UUID v1/v6/v8 (RFC 9562)
validate_required / validate_*_len / validate_int_range / validate_email backend request validation
game_fixed_steps / game_fixed_remainder / game_alpha / game_frame_budget_ok fixed-timestep game-loop helpers
fx_* / det_rng_* / replay_* deterministic simulation math, RNG, and replay streams
frame_* / obj_* / alloc_* / leak_* game frame allocators, object pools, allocation tracking, scoped leak reporting
ecs_* ECS seed: entities, components, queries, archetype masks, system updates
ring_* / lfq_* / sg_* fixed-capacity rings, SPSC queue seed, scatter/gather string helpers
fsm_rule / fsm_can / fsm_transition / fsm_is finite-state-machine helpers for session systems
cookie_get / cookie_make / session_id_new / csrf_* / auth_* / authz_* cookies, sessions, CSRF, authentication, authorization (see Session/Auth section below)
rate_allow / rate_remaining / cache_* / http_compress_if_accepted backend rate limiting, TTL cache, compression negotiation
job_schedule / job_due / job_delay_ms / job_cancel background job scheduling primitives
conn_pool_slot / conn_pool_next / lb_pick2 / lb_pick3 connection-pool slotting and load balancing
openapi_route / openapi_doc OpenAPI 3.1 route and document generation
graphql_field / graphql_arg / graphql_data / graphql_error / graphql_request / graphql_is_mutation GraphQL request parsing and response seed helpers
sse_event / sse_retry / rpc_frame / rpc_method / rpc_payload SSE and streaming RPC wire helpers
io_read_ready / io_write_ready / io_set_nonblocking / io_try_write / io_backoff_ms / io_should_pause backpressure-aware readiness, nonblocking write, and retry policy helpers

dio (Direct I/O)

Low-level unbuffered file operations and memory-mapped files (runtime/mako_dio.h):

Builtin Role
file_open / file_close open/close file descriptors
pread / pwrite positional read/write (no seek side-effect)
file_append append to fd
fsync / fdatasync flush to disk (data+meta / data-only)
fallocate / file_truncate pre-allocate / truncate
file_size / file_seek / file_read_exact fd size, seek, exact read
path_file_size stat path size (−1 if missing; no open required)
mmap_open / mmap_create map existing or new file
mmap_read / mmap_write / mmap_sync read/write/flush mapping
mmap_size / mmap_close size / unmap
page_alloc / page_read / page_write / page_free fixed-size memory pages
wal_open / wal_append / wal_sync / wal_read_at / wal_next_off / wal_close length-prefixed WAL
hindex_* open-addressing int→int hash index
store_* transactional KV (begin / commit / rollback; optional WAL; store_recover_wal)

Tests: dio_test.mko, storage_portable_io_test.mko, windows_direct_io_test.mko, storage_wal_test.mko, store_index_test.mko, domain_tracks_test.mko. Header: runtime/mako_dio.h.


Domain seeds (mako_domain.h)

Storage depth, multiplayer helpers, soft graphics, host AI, debug frame. SIPREC/WebRTC are out of scope.

Area Surface Tests
B-tree btree_new / put / get / save / load / free domain_tracks_test · storage_depth_test
Page B-tree pbtree_new / put / get / pages / free (nodes in MakoPage) domain_tracks_test
LSM lsm_new / put / get / flush / compact / compact_down / attach_run domain_tracks_test
LSM levels lsm_sst_levels / lsm_level_len (L1–L3 SST) domain_tracks_test
SST sst_build4 / sst_get / sst_len / sst_free storage_depth_test
Crash recovery store_recover_wal domain_tracks_test
Hot reload file_mtime_ns / hot_reload_watch / hot_reload_changed domain_tracks_test
Page cache pcache_new / pcache_get / hits·misses storage_depth_test
MVCC mvcc_new / begin / put / get / gc / live both
Snapshots snap_encode2 / encode4 / get / predict / reconcile store_index_test
Rollback rollback_new / push / get / restore_slot0 domain_tracks_test
Graphics soft gfx_window_*, gfx_shader_compile, gfx_asset_size domain_tracks_test
Audio / physics audio_mix, physics_step_x / _v domain_tracks_test
AI host RoPE, kv_cache_*, gemm2x2, f32_to_f16_bits domain_tracks_test
SIMD seed simd_dot_i64_4 / simd_sum_i64_4 storage_depth_test
Debug frame debug_set_loc / debug_file / debug_line / debug_frame_json domain_tracks_test

Header: runtime/mako_domain.h (included by codegen after mako_dio.h).


buf (Binary Buffer)

Structured binary read/write for protocols and file formats (runtime/mako_buf.h):

Builtin Role
buf_pack_new(cap) / buf_from_string(s) create buffer
buf_to_string(b) extract contents
buf_len / buf_pos / buf_reset / buf_seek / buf_free navigation/lifecycle
buf_write_u8/u16/u32/u64/i32/f32/f64 write typed values (LE)
buf_write_u16be/u32be write big-endian
buf_read_u8/u16/u32/u64/i32/f32/f64 read typed values (LE)
buf_read_u16be/u32be read big-endian
buf_write_bytes/str / buf_read_bytes/str raw byte/string I/O

Tests: examples/testing/buf_test.mko. Header: runtime/mako_buf.h.


strings / bytes

String manipulation and byte buffer utilities.

import "strings"
Builtin Role
str_len / str_eq / str_contains length, equality, substring
str_has_prefix / str_has_suffix prefix/suffix
str_index / str_last_index find (−1 if missing)
str_slice_eq / str_slice_ci_eq / str_slice_contains / str_slice_index region ops without substring alloc
str_at_eq / str_byte_at prefix-at-offset compare · byte load
str_trim / str_trim_space / str_trim_left / str_trim_right trim
str_to_lower / str_to_upper / str_repeat case / repeat
str_replace replace all
str_split / str_fields / str_join split/join
str_builder + builder_write* / builder_string / builder_len builder
rune_count UTF-8 rune count
as_bytes / bytes_as_str / bytes_view / bytes_is_view zero-copy views
buf_get / buf_put process-local reusable byte buffers

Package wrappers (pull "strings") add the Go-equivalent surface. join is a keyword, so joining parts is concat. Indexes never panic.

Package fn Go equivalent Notes
contains / has_prefix / has_suffix Contains / HasPrefix / HasSuffix
index / last_index / count Index / LastIndex / Count −1 if missing
index_byte / last_index_byte IndexByte / LastIndexByte OOB byte → −1
index_rune / contains_rune IndexRune / ContainsRune
index_any / contains_any IndexAny / ContainsAny
cut_ok Cut (head, tail, ok)
cut_prefix / cut_suffix CutPrefix / CutSuffix (rest, ok)
split_n / split_after / split_after_n SplitN / SplitAfter* n <= 0 splits all
fields_fn FieldsFunc fn(int) -> bool rune predicate
replace_n Replace n < 0 means all
concat / join_parts Join
clone / compare / equal_fold Clone / Compare / EqualFold
trim_prefix / trim_suffix TrimPrefix / TrimSuffix

pull "bytes" adds []byte index_bytes / contains_bytes / compare_bytes / clone / count_bytes / has_prefix_bytes / trim_prefix_bytes on top of the existing Buffer.

Usage examples

fn main() {
    // Split and join
    let parts = str_split("alice,bob,carol", ",")
    print_int(len(parts))                           // 3
    let joined = str_join(parts, " | ")
    print(joined)                                    // alice | bob | carol

    // Search and check
    print_int(str_contains("hello mako", "mako"))    // 1
    print_int(str_has_prefix("/api/users", "/api"))   // 1
    print_int(str_index("abcdef", "cd"))              // 2

    // Region ops without allocating a substring
    let row = "id,name,score"
    print_int(str_slice_eq(row, 0, 2, "id"))         // 1
    print_int(str_slice_index(row, 0, len(row), ",")) // 2
    print_int(str_byte_at(row, 0))                   // 105 ('i')
    let path = "/var/log/app.log"
    print_int(str_at_eq(path, 0, "/var/"))           // 1
    print_int(str_slice_eq(path, len(path) - 4, 4, ".log")) // 1

    // Trim and case
    let trimmed = str_trim_space("  hello  ")
    print(trimmed)                                   // hello
    print(str_to_upper("mako"))                      // MAKO

    // Builder for efficient concatenation
    let b = str_builder()
    builder_write(b, "hello")
    builder_write(b, " ")
    builder_write(b, "world")
    print(builder_string(b))                         // hello world

    // String <-> bytes
    let raw = bytes("mako")
    print_int(len(raw))                              // 4
    print(string(raw))                               // mako
}

strconv / fmt / print

String conversion and formatted output.

import "strconv"
import "fmt"
Builtin Role
parse_intResult[int,string] base-10 int
parse_float float (0.0 on failure)
parse_boolResult[int,string] true/false/1/0
format_int / int_to_string int → string
format_float(v, prec) / format_bool format
fmt_sprintf4 / fmt_sprintf_d / fmt_sprintf_f multi-arg sprintf (%s%v%d%q%x)
fmt_sprint* / fmt_print* / fmt_printf* Sprint / Print / Printf
fmt_eprint* / fmt_errorf* stderr + error strings
print / print_raw / eprint / eprintln stdout/stderr
print_int* / print_float / print_bool typed stdout

Packs: std/fmt, std/print.

Usage examples

fn main() {
    match parse_int("42") {
        Ok(n) => print_int(n)
        Err(e) => print(e)
    }

    let msg = fmt_sprintf2("hello, %s — n=%s", "mako", format_int(42))
    fmt_println(msg)

    fmt_printf("done %s\n", "ok")
    let err = fmt_errorf("open: %s", "/tmp/x")
    fmt_eprintln(err)
}

path / fs / io / os

File system operations, path manipulation, environment, and process control.

import "path"
import "os"
Builtin Role
path_join / path_clean / path_base / path_dir / path_ext / path_is_abs path
read_file / write_file / append_file / atomic_write_file / remove_file file I/O
mkdir / mkdir_all / rmdir / remove_all / rename / copy_file FS
is_file / path_size / file_mtime / chmod / temp_dir / temp_file FS metadata
symlink / readlink / realpath links / resolve
file_exists / is_dir / read_dir FS
getcwd / chdir working directory
env_get / env_set / env_unset / env_has / env_keys environment
argc / args / arg_get process args
exit process exit

Package extras: path.matches (Go path.Match; * / ?, no / across *). path/filepath adds rel / abs / to_slash / from_slash / volume_name / split_list / matches. os/env is the native-safe env pack (get / set / lookup / expand$VAR and ${VAR}). os/user.current returns uid/gid/username/home. io adds limit_reader / section_reader / copy_n / read_full. io/fs adds stat / valid_path / walk.

Cross-platform: Win/Mac/Linux separators and dir APIs in mako_stdlib.h / mako_platform.h.

Usage examples

fn main() {
    // Path manipulation
    let p = path_join("/usr", "local/bin")
    print(p)                                    // /usr/local/bin
    print(path_base("/home/user/file.mko"))     // file.mko
    print(path_dir("/home/user/file.mko"))      // /home/user
    print(path_ext("archive.tar.gz"))           // .gz

    // File I/O
    let _ = write_file("/tmp/demo.txt", "hello mako\n")
    match read_file("/tmp/demo.txt") {
        Ok(data) => print(data)
        Err(e) => print(e)
    }
    let _ = append_file("/tmp/demo.txt", "second line\n")
    let _ = remove_file("/tmp/demo.txt")

    // File system queries
    print_int(file_exists("/tmp"))              // 1
    print_int(is_dir("/tmp"))                   // 1

    // Environment
    let home = env_get("HOME")
    print(home)

    // Working directory
    let cwd = getcwd()
    print(cwd)

    // Process arguments
    print_int(argc())
    print(arg_get(0))
}

bufio

Buffered readers and writers for efficient I/O.

import "bufio"
Builtin Role
buf_reader_new(path) / buf_reader_from_string(s) buffered reader
buf_read_line / buf_read(n) read line / up to n bytes
buf_reader_close close
buf_writer_new(path) buffered writer
buf_write / buf_write_byte / buf_flush write
buf_writer_close flush + close

Tests: examples/testing/bufio_test.mko.

Usage examples

fn main() {
    // Buffered writer: batches writes for efficiency
    let w = buf_writer_new("/tmp/bufio_demo.txt")
    buf_write(w, "line one\n")
    buf_write(w, "line two\n")
    buf_write(w, "line three\n")
    buf_flush(w)
    buf_writer_close(w)

    // Buffered reader: read line by line
    let r = buf_reader_new("/tmp/bufio_demo.txt")
    let l1 = buf_read_line(r)
    print(l1)                           // line one
    let l2 = buf_read_line(r)
    print(l2)                           // line two
    buf_reader_close(r)

    // Reader from a string (useful for parsing)
    let sr = buf_reader_from_string("hello\nworld\n")
    print(buf_read_line(sr))            // hello
    print(buf_read_line(sr))            // world

    let _ = remove_file("/tmp/bufio_demo.txt")
}

net / http

TCP: tcp_listen / tcp_accept / tcp_connect / tcp_write / tcp_write_all / tcp_read / tcp_read_n / tcp_close, peer/local addr (tcp_peer_addr / tcp_local_addr), half-close (tcp_shutdown), tcp_linger / sock_error, session controls (tcp_set_timeout, tcp_keepalive, tcp_nodelay, tcp_listen_backlog / tcp_listen_reuseport, buffer sizing, tcp_accept4).

Safety / ops (overflow, shutdown, leak, trace)

Area Surface
Overflow checked_add / sub / mul (abort), would_overflow_*, --overflow trap
Shutdown signal_on_term, server_drain, register_listener, shutdown_requested
Leak leak_scope_enter / exit, leak_check (+ leak_mark / bytes_since)
Trace trace_id / set / current / begin / end / log / trace_export_json / trace_export_otlp_json / trace_span_id
Metrics metric_* / gauge_* / hist_* / metrics_export / metrics_export_prom / metrics_export_otlp_json
Profile profile_snapshot_json / stack_trace / crash_report_install / process_rss_bytes / process_cpu_*
Debug debug_break / debug_bp_* / debug_set_int / debug_locals_json / debug_set_loc / debug_frame_json
Task inspect task_done / task_joined / task_id / tasks_inspect_json
Closures fn_drop / fn_has_env (auto drop on scope; kick moves env)
Logs + trace log_* and slog_with print trace=<hex> when a trace is active

See BUILTINS.md §§71–75 and CLI.md (makori dev, --race).

Upstream pool & reverse proxy

Builtin Role
tcp_pool_open / acquire / release / close Per host:port pool; mutex-protected; nonblocking reuse probe
tcp_connect_nb / connect_check / connect_wait Nonblocking connect for slow/unhealthy backends
tcp_fd_copy / tcp_splice / tcp_proxy_pump Efficient stream copy (Linux splice when available)
http_forward Simple upstream forward → body only
http_forward_full / http_forward_fd Status + body + headers (HttpForwardResult); chunked OK
http_proxy_raw Raw request → backend → raw response → client
http_parse / http_parsed_* C hot-path request parse (HttpParsed)
http_decode_chunked Standalone chunked body decode

Edge cases (duplicate Host/CL, incomplete chunked, 204/304, bad args) are documented under Reverse-proxy notes in BUILTINS.md. Tests: examples/testing/proxy_pool_test.mko, proxy_edge_test.mko.

HTTP server

Builtin Role
http_bind / http_accept listen / accept
http_method / http_path / http_body / http_header request
http_req_method / http_req_path / http_req_body request helpers
http_respond / http_respond_ct / http_respond_json response
http_health_json / http_respond_health health/readiness JSON helpers
http_next / http_keepalive / http_close* / http_shutdown_* lifecycle and graceful shutdown
http_serve / http_echo / http_listen demos
http_header_ok header validation

HTTP client

Builtin Role
http_get / http_post / http_request client
http_get_timeout / http_post_timeout timeouts
http_last_status / http_last_header last response
https_request / https_get / https_post verified TLS 1.2+ HTTP/1.1 client; OpenSSL required
https_last_status / https_last_header last HTTPS response status and headers, separate from http_*
oidc_discovery / oidc_token OIDC discovery and form-token POST over verified HTTPS; never http_*

http_* is cleartext-only and accepts http:// URLs. https_* verifies the peer and hostname, bounds the HTTP/1.1 response, and uses platform trust paths when its CA argument is empty. See BUILTINS.md for signatures and the failure contract.

HTTPS/H2/H3/gRPC/WS: tls_* (including multi-certificate SNI), http2_* (64-stream mux, dual FC, HPACK, auto WU), h3_server_* / quiche_h3_* (HTTP/3 when quiche linked; 64 KiB body cap), nghttp2_*, ws_* (RFC 6455) — client/server frames, mask, fragmentation, auto-pong, close codes; loopback tests in ws_api_test.mko. WSS = tls_* + ws_* (compose in Makori). The supported H2 server path is tls_server_new + http2_conn_* (not the tls_serve_h2_routes demo helper).

GPU AI seed: gpu_* device/buffer + f32 AI kernels (matmul, relu, bias_add, saxpy, softmax_rows, plus add/mul/scale/fill). Backend OpenCL (NVIDIA / AMD / Intel / Apple) or host.

Local models: model_*safetensors + GGUF (F32/F16/Q4_0/Q8_0→f32), model_set_f32 / .makomodel, model_linear_f32. Kernels: MHA, attention, layernorm, GELU/SiLU. Text: tok_* vocab + BPE. Hosted chat: llm_*. See BUILTINS § GPU / Local models.

UDP/Unix: udp_bind / udp_bind_addr, udp_send_to, udp_recv / udp_recv_from + udp_last_sender*, udp_local_port, udp_close, unix_socket_pair, unix_socket_pair_peer, unix_listen, unix_accept, unix_connect, unix_unlink, unix_write, unix_read, unix_close.

Path-based Unix-domain stream sockets are POSIX-only checked-native builtins. They fail closed on empty or oversized paths, do not silently remove stale socket files, and return unsupported (-1) on Windows until named pipes are designed.

Typed HttpRequest

Builtin Role
http_request_parse(raw) parse HTTP/1.1 request bytes → HttpRequest
http_request_from_conn(conn) snapshot from accepted connection
http_request_method / path / body accessors
http_route_match(req, method, pattern) match HttpRequest against a method and Mako route pattern
http_route_param(req, pattern, name) extract {name} from a matched route pattern
router_new / router_group / router_add / router_match / router_param / router_count grouped router table and handler-name lookup
reqctx_* / middleware_* per-request context store and middleware chain/policy helpers

Same parse shape applies after TLS decrypt (feed plaintext to http_request_parse). Route patterns use Makoriri's compact {name} segment capture form: /users/{user}/posts/{post}. Example: examples/http_lib/request_type.mko · test: http_request_type_test.mko.

Examples: examples/http_lib/, examples/api_backend/. Smoke: ./scripts/http-lib-smoke.sh.

HTTP server usage example

fn main() {
    let fd = http_bind(8080)
    if fd < 0 {
        print("bind failed")
        return
    }
    print("listening on :8080")

    let mut n = 0
    while n < 3 {
        let c = http_accept(fd)
        if c < 0 {
            continue
        }
        let path = http_path(c)
        if str_eq(path, "/health") {
            let _ = http_respond_json(c, 200, "{\"ok\":true}\n")
        } else {
            let _ = http_respond(c, 404, "not found\n")
        }
        let _ = http_close(c)
        n = n + 1
    }
    let _ = http_close_listener(fd)
}

HTTP client usage example

fn main() {
    let body = http_get("http://example.com/api")
    print(body)
    let status = http_last_status()
    print_int(status)

    // POST with timeout
    let resp = http_post_timeout("http://example.com/data",
        "{\"key\":\"value\"}", 5000)
    print(resp)
}

URL parsing

fn main() {
    let raw = "https://example.com:8080/path?q=mako&page=1"
    print(url_scheme(raw))          // https
    print(url_host(raw))            // example.com:8080
    print(url_path(raw))            // /path
    print(url_query(raw))           // q=mako&page=1

    let encoded = query_escape("hello world & more")
    print(encoded)                  // hello+world+%26+more
}

encoding/json · base64 · hex

Data encoding and decoding in multiple formats.

import "encoding/json"
import "encoding/base64"
Builtin Role
json_* (object/array/path/merge/…) encode/decode into arenas
#[derive(json)] compile-time struct marshal/unmarshal codegen for scalar fields
yaml_* / toml_* get+encode encoding/yaml · encoding/toml (flat + section)
msgpack_* / cbor_* / avro_* encode·decode encoding/msgpack · cbor · avro
pb_* wire helpers encoding/protobuf
graphql_* request/response + parse graphql package
time_offset_named / time_format_offset fixed named TZ offsets (not IANA DB)
list_take/drop/zip/map_*/filter_*/fold_* collections combinators (int)
base64_encode / base64_decode base64
hex_encode / hex_decode hex

JSON usage examples

fn main() {
    // Build a JSON object
    let obj = json_new()
    let obj = json_set_string(obj, "name", "Ada")
    let obj = json_set_int(obj, "age", 36)
    print(obj)                              // {"name":"Ada","age":36}

    // Read fields back
    let name = json_get_string(obj, "name")
    let age = json_get_int(obj, "age")
    print(name)                             // Ada
    print_int(age)                          // 36

    // derive(json) for structs (see EXAMPLES.md for full example)
    // #[derive(json)]
    // struct Config { host: string, port: int }
    // let j = Config_to_json("localhost", 8080)
}

Base64 and hex usage examples

fn main() {
    // Base64 encode/decode
    let encoded = base64_encode("hello mako")
    print(encoded)                          // aGVsbG8gbWFrbw==
    let decoded = base64_decode(encoded)
    print(decoded)                          // hello mako

    // Hex encode/decode
    let h = hex_encode("AB")
    print(h)                                // 4142
    let raw = hex_decode(h)
    print(raw)                              // AB
}

CSV usage examples

fn main() {
    // Split a CSV line into fields
    let fields = csv_split_line("name,age,city")
    print(fields[0])                        // name
    print(fields[1])                        // age

    // Join fields into a CSV row
    let row = csv_join_row(["Alice", "30", "NYC"])
    print(row)                              // Alice,30,NYC
}

XML and HTML escaping

fn main() {
    let safe = xml_escape("<script>alert('xss')</script>")
    print(safe)         // &lt;script&gt;alert('xss')&lt;/script&gt;

    let html_safe = html_escape("5 > 3 & 2 < 4")
    print(html_safe)    // 5 &gt; 3 &amp; 2 &lt; 4
}

crypto

Cryptographic hashing, KDFs, password storage, AEAD, and SCRAM-SHA-256 core. Prefer pull "crypto" and the package wrappers; raw builtins (sha256_raw, pbkdf2_sha256, …) remain available. Full symbol table: BUILTINS.md § Crypto. Narrative + password/SCRAM recipes: book ch07-stdlib. Threat model notes: SECURITY.md.

pull "crypto"
Area API
Digests / MAC sha256 / hmac_sha256 (+ _raw), package crypto.digest_sha256 / crypto.hmac
CSPRNG random_bytes / random_int, package crypto.rand_bytes
Timing-safe compare const_eq / crypto_eq, package crypto.eq
Secrets secret_from_str / secret_drop / secret_eq_str
Password storage crypto.password_hash / password_verify (Argon2id PHC); crypto.bcrypt / bcrypt_check
KDF crypto.pbkdf2 / pbkdf2_sha256; hkdf_sha256
SCRAM-SHA-256 crypto.scram_* (salted password, keys, proof, verify — RFC 5802/7677)
AEAD crypto.aes_gcm_* / chacha_* when OpenSSL linked (crypto.aead_ok)

Digests, random, secrets

pull "crypto"

fn main() {
    let hash = crypto.digest_sha256("hello mako")   // hex
    let mac = crypto.hmac("secret-key", "message")
    let token = crypto.rand_bytes(16)
    print(hex_encode(token))
    print_int(crypto.eq(hash, crypto.digest_sha256("hello mako")))  // 1
    let s = secret_from_str("my-api-key")
    secret_drop(s)
}

Password hashing (prefer Argon2id)

pull "crypto"

fn main() {
    let stored = crypto.password_hash("correct horse battery staple")
    // $argon2id$v=19$m=…$…  — salt and params travel with the hash
    if crypto.password_verify(stored, "correct horse battery staple") == 1 {
        print("welcome")
    }
}

Never store plain or single-pass digests of passwords. Use crypto.password_hashing_ok() / crypto.bcrypt_ok() when probing the build.

SCRAM-SHA-256 (Postgres-style wire auth)

Core only — you assemble the wire/SASL AuthMessage and nonces. Salt is raw bytes (base64-decode values from the wire). Server-side proof check uses constant-time compare (const_eq inside scram_verify_proof).

pull "crypto"

// auth = client_first_bare + "," + server_first + "," + client_final_no_proof
let salted = crypto.scram_salted_password(password, salt, iterations)
let client_key = crypto.scram_client_key(salted)
let stored_key = crypto.scram_stored_key(client_key)
if crypto.scram_verify_proof(stored_key, auth, client_proof) == 1 {
    let server_key = crypto.scram_server_key(salted)
    let sig = crypto.scram_server_signature(server_key, auth)
    // send v=base64(sig) as AuthenticationSASLFinal
}
Helper Role
scram_salted_password PBKDF2-HMAC-SHA256, 32-byte salted password
scram_client_key / scram_server_key HMAC(salted, "Client Key"\|"Server Key")
scram_stored_key SHA256(client_key) — what you may persist
scram_client_proof / scram_verify_proof XOR proof + server check (1/0)
scram_client_signature / scram_server_signature HMAC(key, AuthMessage)
scram_gs2 / scram_cbind / scram_client_final_bare Channel-binding message fragments
scram_tls_unique_c / scram_plus_final_bare SCRAM-PLUS from live TlsConn (tls_unique)

RFC 7677 vector: examples/testing/scram_test.mko. Full Postgres wire (SASLInitialResponse / SASLContinue / SASLFinal) is intentionally application code — Makori is crypto core only, not a SASL state machine.

PEM + cert lab (pull "crypto"crypto.x509 / crypto.tls)

String-level PEM helpers (no OpenSSL required for parse) plus thin OpenSSL writers for self-signed / CSR / reload:

Helper Role
crypto.x509.count_blocks / has_block / extract_block / load_file PEM inspect + load
crypto.x509.make_self_signed / make_csr Write PEMs for lab / rotation workflows
crypto.tls.server_reload Hot-reload cert+key on an existing server ctx
crypto.tls.server_new_mtls / client_new_mtls / unique mTLS + tls-unique
crypto.tls.pool_open / pool_open_timeout / pool_open_mtls Pooled outbound TLS / mTLS handles
crypto.tls.pool_send / pool_recv / pool_fd / pool_close Pool I/O lifecycle

Not a CA product: no HSM, ACME, or full WebPKI store. Tests: security_product_test.mko, security_residuals_test.mko.

Key derivation

pull "crypto"

fn main() {
    let key = crypto.pbkdf2("password", "salt", 4096, 32)
    print_int(len(key))   // 32
}

dtls

DTLS 1.2 over UDP — the WebRTC DTLS-SRTP building block. Blocking handshake with RFC 6347 retransmit timers and stateless cookie exchange, SHA-256 cert fingerprints (SDP a=fingerprint), and RFC 5764 keying-material export for SRTP. Requires OpenSSL linked (dtls.available() == 1); otherwise every constructor fails cleanly. Runtime: runtime/mako_dtls.h. Full builtin table: BUILTINS.md § Crypto & Security → DTLS.

pull "dtls"

fn main() {
    let fd = udp_bind_addr("127.0.0.1", 19499)
    let ctx = dtls.ctx_new("cert.pem", "key.pem", 1)  // use_srtp=1
    print(dtls.local_fingerprint(ctx))                 // SDP a=fingerprint:sha-256
    let conn = dtls.accept(ctx, fd)                    // or dtls.connect(ctx, fd, host, port)
    let msg = dtls.recv(conn, 4096)
    let _ = dtls.send(conn, msg)
    let keys = dtls.export_srtp_keys(conn)             // client_key|client_salt|server_key|server_salt
    print(dtls.srtp_profile(conn))
    let _ = dtls.close(conn)
    let _ = udp_close(fd)
    let _ = dtls.ctx_free(ctx)
}
Area API
Context ctx_new (cert+key PEM paths, use_srtp) / ctx_free / available
Handshake connect (client) / accept (server, cookie exchange) — blocking
I/O send / recv / close (does not close the UDP fd) / conn_fd
Fingerprints local_fingerprint (SDP offer) / peer_fingerprintAA:BB:… SHA-256
SRTP export_srtp_keys (RFC 5764; 60 B AES128_CM, 88 B AEAD_AES_256_GCM) / srtp_profile / export_srtp_secret (Secret, wiped on drop)

v1 limits: DTLS 1.2 only, PEM-path certs, one peer per UDP socket (after accept the socket is connect()ed to that peer), POSIX only. Exported key material is a plain string — route it through export_srtp_secret (or secret_from_str + secret_drop) so it is wiped on drop. Tests: examples/testing/dtls_test.mko · interop: scripts/dtls-smoke.sh (openssl s_client -dtls1_2) · demo: examples/dtls_echo_server.mko.


llm (LLM programming)

OpenAI-compatible chat runtime for low-latency agent/tool loops in Makori.

Area Symbols
Messages llm_message, llm_messages_append, llm_system_user, llm_chat_body
Tools llm_body_with_tools, llm_tool_call_*
Stream llm_sse_data, llm_sse_delta, llm_stream_append
Structured out llm_json_extract, llm_content
Transport llm_chat, llm_ask, llm_https_post (needs OpenSSL)
Ops llm_estimate_tokens, llm_retry_delay_ms, llm_redact_key

Env: XAI_API_KEY (preferred), OPENAI_API_KEY, MAKO_LLM_BASE_URL, MAKO_LLM_MODEL.

fn main() {
    if llm_https_available() == 0 { return }
    let t0 = mono_ns()
    let resp = llm_ask("Be brief.", "Hello", 15000)
    print(llm_content(resp))
    print_int(elapsed_ns(t0))
}

Parallel tool handlers after parse: kick/fan over llm_tool_call_name indices (no async color). Tests: examples/testing/llm_test.mko.

Native backend: offline builders/parsers/retry helpers and transport entry points are wired through checked bridge shims. Live HTTPS calls still depend on OpenSSL availability and environment keys, so default safety claims cover the bridge ownership/bounds path, not the external service.


time

Clocks, timestamps, sleeping, and deadlines. Two clock domains:

Domain API Use for
Monotonic mono_ns / mono_us / mono_ms / now_ns Latency, budgets, timeouts, benchmarks
Wall wall_ns / wall_ms / now_ms / time_unix Logs, calendar, RFC3339

Monotonic prefers CLOCK_MONOTONIC_RAW (no NTP slew) when the OS provides it.

import "time"
Builtin Role
mono_ns / mono_us / mono_ms steady clock
wall_ns / wall_us / wall_ms calendar clock
now_ns / now_ms aliases: mono ns / wall ms
elapsed_ns / elapsed_us / elapsed_mono_ms mono deltas
deadline_ns / deadline_ms / deadline_remaining_ns / deadline_expired mono deadlines
sleep_ns / sleep_us / sleep_ms / sleep_until_ns / spin_until_ns waits
mono_res_ns / mono_overhead_ns resolution / calibration
time_unix / time_format wall seconds / RFC3339 UTC
time_date / time_yeartime_weekday build / extract UTC calendar
time_parse_rfc3339 / time_parse_date parse → unix ms
time_format_local / date / clock format variants
time_add_ms / sub / after / before / trunc_* arithmetic
duration_* / duration_string duration in ms + pretty print
time.parse_duration Go duration syntax → milliseconds (1h30m, -250ms)
syscall_* portable OS: pid/uid/host/uname/pipe/dup/access/…

Low-latency pattern

fn handle() {
    let t0 = mono_ns()
    // ... hot path work ...
    let took = elapsed_ns(t0)
    if took > 1000000 {               // > 1 ms budget
        // log or shed load
    }

    let dl = deadline_ms(5)           // 5 ms mono deadline
    while deadline_expired(dl) == 0 {
        // poll until deadline
        sleep_us(50)
    }
}

Usage examples

fn main() {
    // Wall timestamp (logs)
    let start = wall_ms()
    print(time_format(start))

    // Latency measurement (monotonic)
    let t0 = mono_ns()
    sleep_us(200)
    print_int(elapsed_ns(t0))

    // Precise short wait
    sleep_until_ns(deadline_ns(500000))  // 500 µs
}

Tests: examples/testing/time_latency_test.mko · time_full_test.mko · syscall_full_test.mko.


sync / conc

Concurrency primitives: mutexes, wait groups, channels, crews, and actors.

import "sync"
Builtin Role
mutex_new / mutex_lock / mutex_unlock mutex
rwmutex_new / rwmutex_rlock / runlock / lock / unlock RWMutex
wait_group_new / wait_group_add / done / wait WaitGroup
cmap_new / cmap_set / cmap_get / cmap_has / cmap_del / cmap_len / cmap_incr CMap (concurrent hashmap with linearizable operations)
chan_new / chan_open[T] / send / recv / chan_select* channels: int/bool/float/string/struct; select is int-ring
runtime_stats_json / runtime_stats_reset runtime scheduler/channel introspection
crew / kick / join / drain / cancel structured concurrency; join returns job type
fan parallel map over []int / []float / []string / []Struct
actor_spawn / actor_send / actor_recv / actor_stop actors
actor / receive syntax desugar (see GUIDE)

The compiler rejects unsynchronized mutable closure captures and unknown function environments across kick; fan mappers cannot capture locals. Race smoke: makori test --race (CI TSan job), which covers runtime and FFI edges that are outside the safe-language boundary.

Mutex usage example

fn main() {
    let m = mutex_new()
    let mut counter = 0

    mutex_lock(m)
    counter = counter + 1
    mutex_unlock(m)

    print_int(counter)                  // 1
}

Channel and crew usage example

fn worker(ch: chan[int], id: int) -> int {
    let _ = ch.send(id * 10)
    return id
}

fn main() {
    let ch = chan_new(4)

    crew t {
        let w1 = t.kick(worker(ch, 1))
        let w2 = t.kick(worker(ch, 2))
        let _ = w1.join()
        let _ = w2.join()
    }

    print_int(ch.recv())                // 10
    print_int(ch.recv())                // 20
}

WaitGroup usage example

fn main() {
    let wg = wait_group_new()
    wait_group_add(wg, 3)

    // Simulate 3 tasks finishing
    done(wg)
    done(wg)
    done(wg)

    wait(wg)                            // blocks until count reaches 0
    print("all done")
}

Concurrent map usage example

fn main() {
    let m = cmap_new()
    cmap_set(m, "hits", "0")
    cmap_incr(m, "hits", 1)
    cmap_incr(m, "hits", 1)
    print(cmap_get(m, "hits"))          // 2
    print_int(cmap_len(m))              // 1
    print_int(cmap_has(m, "hits"))      // 1
}

errors · testing · regexp · log · math · collections

Area Builtins
errors error / errorf / wrap_err / error_is / error_string / ?
testing makori test, assert / assert_eq / assert_eq_str, t_run, --race / --sanitize
regexp regex_match / regex_find / regex_capture
log Strong slog: slog_set_level / set_json / set_service / set_output / with* / log_* aliases
math abs / min / max / clamp, math_sqrt / pow / floor / ceil / sin / cos / log / exp / math_abs
collections sort_*, list push/pop/insert/remove, set union/intersect/diff, min-heap, lock-free ring, sum/min/max/concat/range/bsearch

Strong logging

fn main() {
    slog_set_level("info")          // filter debug
    slog_set_service("payments")
    slog_set_json(1)                // JSON lines for collectors
    slog_with2("info", "charge", "user", "u1", "amount", "9.99")
    slog_with_int("warn", "retry", "attempt", 3)
    slog_with_redacted("info", "auth", "password")
    slog_flush()
    // log_info / log_warn / log_error use the same backend
}

Default level is info. ISO-8601 ts; optional trace= when trace_id is active. slog_set_output("/var/log/app.log") appends; slog_set_output("") restores stderr. Tests: examples/testing/strong_log_test.mko.

Errors usage examples

fn load_config(path: string) -> Result[string, string] {
    if str_eq(path, "") {
        return error("empty path")
    }
    Ok("config_data")
}

fn main() {
    // The ? operator propagates errors up the call chain
    // wrap_err adds context
    let r = load_config("")
    let r = wrap_err(r, "startup")
    match r {
        Ok(data) => print(data)
        Err(e) => {
            print(error_string(r))          // startup: empty path
            print_int(error_is(r, "empty")) // 1
        }
    }
}

Regexp usage examples

fn main() {
    // Match: does the string match the pattern?
    print_int(regex_match("hello123", "\\d+"))       // 1

    // Find: extract the first match
    let found = regex_find("order-42-confirmed", "\\d+")
    print(found)                                      // 42

    // Capture: extract groups
    let caps = regex_capture("2026-07-10", "(\\d{4})-(\\d{2})-(\\d{2})")
    print(caps[1])                                    // 2026
    print(caps[2])                                    // 07
    print(caps[3])                                    // 10

    // Find all matches
    let all = regex_find_all("a1b2c3", "\\d")
    print_int(len(all))                               // 3
}

Log usage examples

fn main() {
    log_info("server started")
    log_warn("disk usage high")
    log_error("connection refused")
    log_debug("request payload received")

    // Structured key-value logging
    log_kv("request", "method", "GET", "path", "/api/users")
}

Math usage examples

fn main() {
    print_int(abs(-42))                     // 42
    print_int(min(3, 7))                    // 3
    print_int(max(3, 7))                    // 7
    print_int(clamp(15, 0, 10))             // 10

    print_float(math_sqrt(144.0))           // 12.0
    print_float(pow(2.0, 10.0))             // 1024.0
    print_float(floor(3.7))                 // 3.0
    print_float(ceil(3.2))                  // 4.0
}

Collections (slices / maps) usage examples

fn main() {
    // Sort
    let mut nums = [5, 3, 1, 4, 2]
    sort_ints(nums)
    // nums is now [1, 2, 3, 4, 5]
    print_int(nums[0])                      // 1

    let mut names = ["carol", "alice", "bob"]
    sort_strings(names)
    print(names[0])                         // alice

    // Search
    print_int(ints_contains([10, 20, 30], 20))      // 1
    print_int(strings_contains(["a", "b"], "c"))     // 0
    print_int(ints_index([10, 20, 30], 20))          // 1

    // Slice utilities
    let mut src = [1, 2, 3]
    let dst = ints_copy(src)
    print_int(len(dst))                     // 3

    // Reverse and unique
    let mut vals = [3, 1, 2, 1, 3]
    slices_reverse(vals)
    // vals is now [3, 1, 2, 1, 3] reversed

    // Maps
    let keys = maps_keys(m)
    let vals = maps_values(m)
}

Testing usage examples

// In a *_test.mko file:
fn TestExample() {
    assert(true)
    assert_eq(2 + 2, 4)
    assert_eq_str("hello", "hello")
}

fn TestSubtests() {
    t_run("case one", fn() {
        assert_eq(1 + 1, 2)
    })
    t_run("case two", fn() {
        assert_eq(2 * 3, 6)
    })
}

Run tests:

mako test .                     # run all tests
mako test . -v                  # verbose
mako test . -run TestExample    # run one test
mako test . --race              # with thread sanitizer

Context usage example

fn main() {
    // Create a context with a 5-second timeout
    let ctx = context_with_timeout(5000)

    // Check if expired
    if expired(ctx) == 0 {
        print("still active")
    }

    // Check remaining time
    let ms = remaining(ctx)
    print_int(ms)                   // ~5000
}

Reflect usage example

fn main() {
    // Reflect provides runtime type inspection
    let v = reflect_value_of(42)
    let cloned = reflect_clone(v)
    print_int(reflect_equal(v, cloned))     // 1
}

Image usage example

fn main() {
    // PNG encoding
    let data = png_encode_gray(pixels, width, height)
    let _ = write_file("/tmp/output.png", data)

    // JPEG encoding with DCT
    let jpg = jpeg_encode_gray_dct(pixels, width, height)
    let _ = write_file("/tmp/output.jpg", jpg)
}

Archive usage examples

fn main() {
    // Create a zip file
    let z = zip_create()
    zip_add(z, "hello.txt", "hello from mako\n")
    zip_add(z, "data.txt", "some data\n")
    zip_write_to(z, "/tmp/demo.zip")

    // List files in a zip
    let names = zip_list("/tmp/demo.zip")
    print(names[0])                         // hello.txt

    // Read a file from a zip
    let content = zip_read_file("/tmp/demo.zip", "hello.txt")
    print(content)                          // hello from mako

    let _ = remove_file("/tmp/demo.zip")
}

Flag (CLI argument parsing) usage example

fn main() {
    let host = flag_string("host", "localhost", "server hostname")
    let port = flag_int("port", 8080, "server port")
    let verbose = flag_bool("verbose", false, "enable verbose output")

    print(host)
    print_int(port)
}

Run: makori run server.mko -- --host 0.0.0.0 --port 9090 --verbose

Unicode/UTF-8 usage example

fn main() {
    print_int(utf8_valid("hello"))          // 1
    print_int(utf8_rune_len("hello"))       // 5 (ASCII: 1 byte per rune)
    print_int(rune_count("hello"))          // 5
}

database/sql -- unified facade

Same call shape for sqlite and postgres (? placeholders; postgres rewritten to $N):

Builtin Role
sql_open_sqlite(path) / sql_open_postgres(url) open → SqlDB
sql_ok / sql_close status / close
sql_query_int(db, sql, []int) parameterized query → int
sql_exec(db, sql, []int) parameterized exec (integer params)
sql_exec_plain(db, sql) exec with no parameters (DDL, simple statements); returns 0 on success
sql_exec_str4(db, sql, p1, p2, p3, p4) exec with up to 4 string params (? / $1..$4); bind count = SQL placeholder arity; empty "" is a real value
sql_query_str / sql_query_str2 / str3 / str4 first col of first row; multi-arg string binds (same arity rules)
sql_last_insert_id(db) last INSERT id (SQLite last_insert_rowid; Postgres lastval)
sql_rows_affected(db) rows changed by last mutating statement on this connection
sql_query_rows / sql_query_rows_str open multi-row result handle (int params / one string param)
sql_rows_next / sql_rows_int / sql_rows_str / sql_rows_cols / sql_rows_close cursor walk + column read
sql_query_col_int / sql_query_col_str bulk first-column collect ([]int / []string, capped)
sql_begin / sql_commit / sql_rollback transaction boundaries
sql_prepare / sql_stmt_query_int / sql_stmt_exec / sql_stmt_close prepared statement handles
sql_migration_applied / sql_migrate numeric-version migration table and transactional apply
sql_check_typed(schema, sql, params, result) static table/column/param/nullability/result checker
sql_pool_open_* / sql_pool_query_int / sql_pool_exec / sql_pool_close bounded lazy connection pools with round-robin slots
mysql_connect_url / mysql_ok / mysql_is_mariadb / mysql_driver_name MySQL/MariaDB DSN validation and driver metadata
redis_connect_url / redis_connect / redis_conn_* / redis_close Redis URL parsing and reusable RESP connection handles
mongo_connect_url / mongo_find_one_request MongoDB-compatible URL parsing and find-one command request construction
cassandra_connect_url / cassandra_select Cassandra-compatible URL parsing and CQL select construction
clickhouse_connect_url / clickhouse_select ClickHouse-compatible URL parsing and SQL select construction
elastic_connect_url / elastic_search_request Elasticsearch-compatible URL parsing and search request construction

Legacy drivers still available: sqlite_query_*, pg_connect / pg_exec*. Parameterized queries only for untrusted input -- SECURITY.md. Tests: examples/testing/sql_unify_test.mko, sql_pool_test.mko, sql_tx_stmt_test.mko, sql_migration_test.mko, sql_typed_check_test.mko, sql_programming_test.mko, sql_rows_test.mko, mysql_redis_polish_test.mko, multistore_compat_test.mko, derive_json_codegen_test.mko.

SQLite usage example

fn main() {
    let db = sql_open_sqlite("/tmp/app.db")
    if sql_ok(db) == 0 {
        print("open failed")
        return
    }
    defer sql_close(db)

    // Create a table
    let _ = sql_exec_plain(db,
        "CREATE TABLE IF NOT EXISTS notes (id INTEGER PRIMARY KEY, text TEXT)")

    // Insert with parameterized string values (use `?` on SQLite; `$1` also works)
    let _ = sql_exec_str4(db,
        "INSERT INTO notes (text) VALUES (?)", "buy groceries", "", "", "")
    print_int(sql_last_insert_id(db))   // 1
    print_int(sql_rows_affected(db))    // 1

    // Query
    let empty = make([]int, 0)
    let count = sql_query_int(db, "SELECT COUNT(*) FROM notes", empty)
    print_int(count)                    // 1

    let text = sql_query_str(db, "SELECT text FROM notes WHERE id = ?", "1")
    print(text)                         // buy groceries

    // Transactions
    sql_begin(db)
    let _ = sql_exec_str4(db,
        "INSERT INTO notes (text) VALUES (?)", "walk the dog", "", "", "")
    sql_commit(db)

    let _ = remove_file("/tmp/app.db")
}

Multi-row result sets

fn main() {
    let db = sql_open_sqlite("/tmp/rows.db")
    defer sql_close(db)

    let _ = sql_exec_plain(db,
        "CREATE TABLE items (id INTEGER PRIMARY KEY, name TEXT, qty INTEGER)")
    let _ = sql_exec_str4(db, "INSERT INTO items (name, qty) VALUES (?, ?)", "apple", "3", "", "")
    let _ = sql_exec_str4(db, "INSERT INTO items (name, qty) VALUES (?, ?)", "banana", "5", "", "")

    let empty = make([]int, 0)
    let rows = sql_query_rows(db, "SELECT id, name, qty FROM items ORDER BY id", empty)
    while sql_rows_next(rows) == 1 {
        print_int(sql_rows_int(rows, 0))
        print(sql_rows_str(rows, 1))
        print_int(sql_rows_int(rows, 2))
    }
    sql_rows_close(rows)

    // Bulk first column
    let names = sql_query_col_str(db, "SELECT name FROM items ORDER BY name", 100)
    print_int(len(names))   // 2

    let _ = remove_file("/tmp/rows.db")
}

sql_rows_next returns 1 (row), 0 (done), or -1 (error). Always sql_rows_close the handle. Max concurrent result sets: 32.

Prepared statements

fn main() {
    let db = sql_open_sqlite("/tmp/prep.db")
    defer sql_close(db)

    let _ = sql_exec_plain(db, "CREATE TABLE kv (k TEXT, v INTEGER)")

    // Prepare once, execute many times
    let stmt = sql_prepare(db, "INSERT INTO kv (k, v) VALUES (?, ?)")
    let _ = sql_stmt_exec(stmt, [1])    // execute with params
    sql_stmt_close(stmt)

    let _ = remove_file("/tmp/prep.db")
}

Migrations

fn main() {
    let db = sql_open_sqlite("/tmp/migrate.db")
    defer sql_close(db)

    // Apply migration version 1 if not already applied
    if sql_migration_applied(db, 1) == 0 {
        sql_migrate(db, 1,
            "CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)")
    }

    print("migration done")
    let _ = remove_file("/tmp/migrate.db")
}

General networking building blocks

These are protocol-agnostic. Any backend (HTTP, SIP, custom binary, Diameter, …) composes them; no pack invents timeouts or peer policy defaults.

Pack / builtins Role
tcp_pool_* / tls_pool_* Connection pools with caller-supplied timeouts; mTLS optional
dtls_* / std/dtls DTLS 1.2 over UDP + SRTP key export + cert fingerprints (WebRTC DTLS-SRTP building block)
sctp_* / std/sctp General SCTP (streams, PPID, HB, multihoming where kernel allows)
timer_heap_* / std/timer Protocol-agnostic deadline min-heap
peer_table_* / std/peer Protocol-agnostic named peers + string-key routing + scan helpers

Diameter (std/diameter) — optional protocol pack

RFC 6733 framing/AVP + optional managers. Not the general peer layer: diameter_tcm_* composes peer_table + timer_heap and only adds Diameter Origin/Tw/DWR. Prefer composing the general packs for multi-protocol services. Runtime: runtime/mako_diameter.h.

SIP proxy library (built-in)

This is the platform SIP library for proxies (also usable for UAs/registrars). Runtime: runtime/mako_sip.h. Pack: std/sip (import sip / pack exports).

Not a full softswitch. Is the first-class proxy data-path API: message parse/build, Via/RR hop, Digest challenges, TCP/TLS framing. You own timers, dialog maps, routing, and media (e.g. rtpengine). Out of scope: SIPREC, WebRTC, full B2BUA engine.

Capability map

Product concern Built-in library
Parse / build messages sip_header (compact forms), sip_request / sip_reply, sip_body
Proxy hop (RFC 3261 §16) sip_insert_via / sip_strip_via / sip_record_route / sip_prepend_header
NAT full (RFC 3261 §18.2 + RFC 3581) sip_via_value_rport (UAC) · sip_via_fix_source / sip_msg_fix_top_via (ingress) · sip_via_response_host/port/addr (symmetric reply)
Response To-tag sip_ensure_to_tag / sip_reply_with_to_tag
TCP/TLS framing sip_first_message_len / sip_msg_complete / sip_msg_needed
Digest (server HA1) sip_digest_response_ha1 · sip_www_authenticate / sip_proxy_authenticate
Txn / dialog keys sip_txn_key · sip_dialog_id · sip_branch (magic cookie)
REGISTER location parse + sql_* / maps (your store)
Timers T1…K mono_ns / deadline_* / crews (you drive)
SDP (RFC 4566) media parse · direction · sdp_replace_connection_addr / sdp_replace_media_port · build audio/av
RTP helpers rtp_* (media termination usually rtpengine)

Builtins (also as sip.* via pack)

Area Surface
Message sip_ok, sip_method, sip_header (+ compact i/v/f/t/…), sip_body
Build sip_request / sip_response / sip_reply / sip_reply_with_to_tag
Proxy sip_insert_via, sip_strip_via, sip_via_value_nat, sip_record_route
Framing sip_first_message_len, sip_msg_complete, sip_msg_needed
Auth sip_digest_response, sip_digest_response_ha1, sip_www_authenticate

Ownership / hot path: sip_header / builders return owned strings (malloc). For proxy hot paths use zero-copy APIs: sip_method_eq, sip_header_eq / sip_header_contains, or sip_header_view + sip_view_eq / sip_view_contains (views point into the message buffer; valid only while msg lives). Parse is length-bounded (buffer need not be NUL-terminated).

Name shadowing: app fn sip_* shadows platform builtins — use std/sip (sip.insert_via, sip.header, …) in application code; call free builtins only when you intentionally want the platform names. | SDP | sdp_media_* / formats / connection inheritance · sdp_replace_* · sdp_build_audio/av · direction | | RTP | rtp_pack, rtp_seq, rtp_timestamp, rtp_ssrc, rtp_payload, rtp_payload_type | | SRTP building blocks | aes_ctr, hmac_sha1 / hmac_sha1_raw, aes_gcm_*, random_bytes |

// Integration boundary: you own the transaction map + timers.
fn on_datagram(raw: string, peer_host: string, peer_port: int) {
    if sip_ok(raw) == 0 { return }
    if sip_is_request(raw) == 1 {
        let via = sip_header(raw, "Via")
        let key = sip_txn_key(sip_via_branch(via), sip_method(raw))
        // store key → state in map[string]…; schedule retransmit with mono_ns
        let _ = key
        let _ = sip_udp_send(sock, peer_host, peer_port, sip_reply(raw, 100, "Trying", "", ""))
    }
}

Package mirror: pull "std/sip" (std/sip/sip.mko).
Tests: examples/testing/sip_test.mko · demo: examples/sip_ua.mko.

Not shipped as product libraries: a complete softphone, SBCs, SRTP media encryption, or browser WebRTC. Those are Makori programs on top of this surface (the DTLS-SRTP handshake itself ships as std/dtls).


Local packages (mako.toml / makori pkg)

mako pkg init
mako pkg add util path=../util
mako pkg publish          # → .mako/registry (or $MAKO_REGISTRY)
mako pkg install         # resolve SemVer + write/verify mako.lock v2
mako pkg update          # accept changes / migrate a v1 lockfile

See howto/04-packages.md.


Performance principles

  1. No GC — backends stay predictable; ownership, shares, and arenas are explicit.
  2. Arena per request — allocate freely; free the region once.
  3. Dense values — less pointer chasing.
  4. Explicit buffers — fewer hidden copies (bytes_view, pools).
  5. Crew concurrency — ordinary kicked tasks are joined; cancellation and timeouts are explicit.
  6. Future I/O — io_uring / kqueue, pooling, HTTP/2–3 depth.

UUID / ULID (std/uuid, builtins)

16-byte Copy POD — no GC on the value; string form allocates only when asked.

Surface API
Random uuid_v4()
Time-ordered uuid_v7(), ulid_new()
Name-based uuid_v5(ns, name) · uuid_ns_dns() / url / oid / x500
Format uuid_string / uuid_string_upper / uuid_urn / ulid_string
Parse uuid_parse (canonical, braces, URN, 32-hex) · ulid_parse
Bytes uuid_bytes / uuid_from_bytes (exactly 16; hard fail otherwise)
Inspect uuid_version · uuid_variant · uuid_cmp · ulid_timestamp_ms

Pull: pull "uuid"std/uuid/uuid.mko re-exports. Prefer builtins on the hot path.

Known gaps (honest)

Area Mako today
strings / bytes / slices / maps / cmp / sort Done — Go-equivalent wave; OOB clamps, concatJoin
bufio scan + Reader/Writer Done (scan_lines / scan_words)
strconv quote/unquote Done (quote / unquote(text, err))
io / io/fs Done — Limit/Section/copy_n/FileInfo/valid_path
path / filepath glob Done — matchesMatch; rel/abs/volume_name
os/env / os/user Done — expand / lookup / current
net / net/netip Done — host/port, IPv4/prefix; IPv6 via parse_ip_ok
math/bits / cmplx / big Done — 64-bit bits, Complex pair, Int add/mul/cmp
hash/crc32 / adler32 / fnv Done — IEEE / FNV-1a vectors in tests
encoding/ascii85 / pem / quotedprintable Done
unicode/utf16 / text/tabwriter / scanner / suffixarray Done
time.parse_duration / load_location / sync.once Done — duration in ms; named offsets are a fixed table, not tzdb
crypto/rand / hkdf / pbkdf2 / context.with_value / image Point/Rect Done — CSPRNG + RFC 5869 vector; values are string pairs
net/http.Request typed Done (HttpRequest)
database/sql one API Done (sql_*; string params, last_insert/rows, multi-row cursor + bulk col; MySQL query still seed)
Full regexp engine RE2-ish (\d\w\s, {n,m}, \b, find_all/replace); not full RE2/PCRE
sync.WaitGroup / RWMutex / atomic Done (wrappers must not share builtin names)
Generics collections slices + maps + List[T] + set/heap/ring + take/drop/zip/map_add/filter/fold Done; full callback map/filter Later
zip multi-file · png/gif/jpeg · reflect · httptest · gob/mail/smtp/slog/binary Done (area-level; not every symbol)
unsafe / weak / go/* / debug/* Won't — memory-unsafe or Go toolchain
compress/{flate,zlib,bzip2,lzw} Done — C zlib/flate/LZW; bzip2 optional (MAKO_BZ2)
crypto/{rsa,ecdsa,md5,sha3,rand,hkdf,pbkdf2} Done — MD5/SHA3-256 C; ES256/RS256 via JWT/OpenSSL; no RSA keygen
Full stdlib symbol-for-symbol with Go Not claimed — capability equivalents, Mako names

Session Management, Authentication & Authorization

Cookies, sessions, CSRF, auth, signed tokens, and RBAC (runtime/mako_security.h).

Cookies

Builtin Purpose
cookie_get(header, name) -> string Parse a cookie value from a Cookie: header
cookie_make(name, value, max_age) -> string Create a Set-Cookie header (HttpOnly, SameSite=Lax, Path=/)

Sessions

Builtin Purpose
session_id_new() -> string Generate a 32-char random hex session ID (16 bytes of cryptographic randomness)
auth_session_cookie(cookie_header, cookie_name, expected) -> int Constant-time session cookie check (1=match, 0=no)

CSRF

Builtin Purpose
csrf_token() -> string Generate a random CSRF token
csrf_check(expected, submitted) -> int Constant-time comparison (1=match, 0=no)

Authentication

Builtin Purpose
auth_bearer(authorization) -> string Extract token from "Bearer \<token>" header
auth_check_bearer(authorization, expected_token) -> int Constant-time bearer token verification
auth_basic_header(user, pass) -> string Build a "Basic \<base64>" authorization header
auth_check_basic(authorization, user, pass) -> int Verify Basic auth credentials

Signed Tokens (HMAC-SHA256)

Builtin Purpose
auth_token_sign(subject, secret) -> string Sign a subject, returns "subject.hmac_signature"
auth_token_check(token, secret) -> int Verify a signed token (1=valid, 0=invalid)
auth_token_subject(token) -> string Extract subject from "subject.signature" token

Role-Based Access Control

Builtin Purpose
auth_role_has(roles_csv, role) -> int Check if a CSV roles string contains a role
authz_allow_role(user_roles_csv, required_roles_csv) -> int Check if user has any required role

Security

TLS for production listeners, parameterized DB, no ignored Results — SECURITY.md.