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.
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
Public API should prefer short, concrete, action-oriented names.
Prefer:
- verbs such as
read,write,open,close,yield, andsleep - concrete nouns such as
path,clock,future,buffer,slice,reader, andwriter - small namespaces such as
io,os,net,mem,time,future, andarith
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
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(...).
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 uses0for EOF.io.write(writer, data)writes a borrowedbytes.Bytesview 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.
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.