Skip to content

Standard library

The standard library is the set of packages you reach with import std.*. It covers files, text formatting, math, collections helpers, encoding, networking, processes, threads, time, randomness, and low-level machine access.

You import a package by its dotted name and then call into it by its last name:

import std.io
import std.encoding.json
fn main() {
io.println("hello")
let value: json.Value = json.parse("[1, 2, 3]").expect("parse")
}

The library comes in two layers.

  • Beans-source packages. These are written in Beans and ship with the compiler under stdlib/std/<pkg>/<pkg>.b. You can read their code. Examples: std.fmt at stdlib/std/fmt/fmt.b, std.collections, std.math, std.path, std.fs, and the encoding packages.
  • Native modules. These are built into the compiler and runtime, not into stdlib/std/. They are the parts that must talk to the operating system or the CPU directly: std.io, std.os, std.thread, std.time, std.random, std.target, std.cpu, std.intrinsic, and std.asm.

You do not need to think about which layer a package is in while you write code. It only matters when you go looking for the source.

Beans has no free “constructor functions” in modules. Anything that produces an object is either a new on that object’s class or a named static on the class, never a plain module function.

import std.net
fn main() {
// a class instance: use new
let addr: net.Address = new net.Address("localhost", 8080)
// fallible construction: a named static returning Result
let stream: Result<net.TcpStream> = net.TcpStream.connect("localhost", 8080)
}

So new process.Command("ls") builds a command, and File.open(path, "r") opens a file (it can fail, so it is a named static that returns a Result).

The compiler finds the standard library on its own. If you need to override where it looks, set the BEANS_STDLIB environment variable to another root directory and the loader will read packages from there instead.

There is a compiler-internal package named std.async$rt that backs the async runtime. You cannot import it. Its directory name contains a $, which is not a legal character in an import path, so the name can never be written in your code. Ignore it.

PackageWhat it covers
std.io and std.osprinting, reading input, program arguments, environment, exit
std.collectionsgeneric helpers over List and Map
std.fmtnumber and text formatting
std.mathsmall numeric helpers
std.bytesCRC-32 and varint helpers over Bytes
std.pathpath string math, no filesystem
std.fsread and write whole files
std.readerbuffered line reading over a File
std.reflectruntime types, members, annotations, checked field access and calls
std.encoding.jsonJSON parsing and building
std.encoding.xmlXML parsing and building
std.encoding.base64Base64 encode and decode
std.encoding.binaryfixed-width integers and varints over Bytes
std.netTCP and UDP sockets
std.processrun other programs, no shell
std.pollwait on many descriptors at once
std.signalreceive OS signals as data
std.dylibopen dynamic libraries at run time
std.threadrun closures on OS threads
std.time and std.randomclocks, sleeping, and secure random
std.targetfacts about the selected target, at compile time
std.cpu and std.intrinsicask the CPU, and low-level intrinsics
std.asmconstrained inline assembly
  • Builtins, the types the compiler gives you without an import.
  • The language guide for how Option, Result, and ? work.