Standard Library Policy

Module stability, API naming, and composability rules for std.

The standard library provides essential, composable building blocks that every project would otherwise reimplement. It is not meant to become the whole ecosystem.

The release-facing inventory of shipped modules lives in the Standard Library index. That index marks modules as mvp, internal, or experimental.

mvp means "documented current surface" for 0.0.0-dev. It does not mean the module is released, compatibility-frozen, or production-audited.

Scope

The standard library should include APIs that are:

  • core runtime or language adapters
  • primitive owned data types or borrowed views
  • basic collections and memory primitives
  • small cross-module capability interfaces
  • thin wrappers over platform primitives where safety or ownership matters
  • common operations needed for portability and consistent error handling

The standard library should avoid APIs that:

  • mainly save a short user-written loop
  • hide allocation behind broad convenience
  • duplicate another clear spelling
  • imply codec, protocol, framework, or application policy
  • create large abstractions that are hard to replace

Naming

Public API should prefer short, concrete, action-oriented names.

Prefer:

  • verbs such as read, write, open, close, yield, and sleep
  • concrete nouns such as path, clock, future, buffer, slice, reader, and writer
  • small namespaces such as io, os, net, mem, time, future, and arith

Avoid vague or inflated names such as manager, handler, executeOperation, utilize, file_open, or future_create.

Semantic modifiers should be explicit. Plain arithmetic operators are checked and trap on overflow; stdlib helpers that intentionally choose nullable, wrapping, saturating, or overflowing behavior say so in the module path:

arith.checked.add
arith.wrapping.add
arith.saturating.add
arith.overflowing.add

Conversions And Views

Use constructors when an API creates a destination typed value from existing data or a handle:

let stream = try io.MemoryStream(bytes.Bytes("abc"));
let key = try secretbox.Key(raw);
let addr = ipaddr.Ipv4Addr(127 as u8, 0 as u8, 0 as u8, 1 as u8);

Use noun methods for semantic views and checked typed accessors:

let text = try value.string();
let child = try value.object("metadata");
let raw = string.utf8();
let buffered = stream.bytes();

Reserve to_* for owned, copying, formatting, or transcoding output where the destination representation is the point of the operation, such as addr.to_string() or unicode.utf8.to_utf16le(...).

Composable Primitives

Modules should expose the smallest operation that composes naturally with the rest of std.

For byte streams:

  • reader.read(buffer) may return a short read and uses 0 for EOF.
  • io.write(writer, data) writes a borrowed bytes.Bytes view completely or returns an error.
  • io.read(reader, buffer) fills the whole buffer or returns an EOF error.
  • stream copying and read-to-end allocation stay explicit user loops.

Low-level modules keep low-level semantics. std.os.read and std.os.write are syscall-shaped and may complete partially. Higher-level std.io and std.aio wrappers provide stronger read/write behavior.

Stability Labels

mvp modules are the documented public std surface for current 0.0.0-dev source under their module contracts.

internal modules exist for stdlib/compiler implementation support. They may be physically importable in the tree, but they are not user APIs.

experimental modules require an explicit experimental boundary before normal source can use them. No current lib/std module is marked experimental.