For the complete Mojo documentation index, see llms.txt. Markdown versions of all pages are available by appending .md to any URL (e.g. /docs/manual/basics.md).
Mojo types reference
Mojo is statically typed. Every value has a type that is known at compile time. This page catalogs built-in types that are available in every program without an import.
Built-in types and the prelude
Built-in types come from the standard library prelude, which the compiler
imports into every program. The prelude consists of the builtin package
(Int, Bool, Error, and core traits) plus selected types from
collections, memory, and math.
Although they feel like part of the language itself, built-in types are ordinary structs defined in the standard library, just like a type you might write yourself.
The prelude and compiler syntax are separate concerns. Some language
constructs have syntax without a corresponding name in scope. For example,
a set display doesn't require an import but the Set type does:
var primes = {2, 3, 5, 7} # set display: compiler syntax, no import
from std.collections import Set
var empty = Set[Int]() # the name Set must be imported
Numeric types
Mojo's numeric types are built on SIMD, a fixed-size, homogeneous vector
of primitive values. Int, UInt, the sized integer types (Int8 through
Int256 and UInt8 through UInt256), and the floating-point types
(Float16 through Float64, BFloat16, and the Float8_* formats) are
all available through the prelude.
For details on sizes, precision, overflow behavior, and conversions, see Numeric types.
String types
All string types hold UTF-8 encoded text. Their bytes are guaranteed to be
valid UTF-8. Construction enforces this. String(from_utf8_lossy=...)
replaces invalid bytes, and String(unsafe_from_utf8=...) requires the
caller to guarantee validity.
| Type | What it is |
|---|---|
String | Owned, mutable, heap-allocated UTF-8 string. |
StringSlice | Non-owning view into existing UTF-8 data. |
StaticString | A StringSlice over static, read-only data. |
StringLiteral | Compile-time string constant from source. |
Codepoint | A single Unicode codepoint. |
A string literal in source is a StringLiteral. It materializes to a
String at runtime, or to a StringSlice when the context requires a
view. For details, see String
literals.
Length has three measurements, and they disagree for non-ASCII text:
var wave = String("👋🏽") # waving hand + skin-tone modifier
print(wave.byte_length()) # 8
print(wave.count_codepoints()) # 2
print(wave.count_graphemes()) # 1
byte_length() counts UTF-8 bytes, count_codepoints() counts
Unicode codepoints, and count_graphemes() counts user-perceived
characters. Pick the count that matches the question being asked.
Collection types
Mojo includes a flexible set of collection types.
| Type | What it is |
|---|---|
List | Dynamically sized, growable sequence. |
Dict | Key-value mapping. |
Set | Unordered collection of unique values. Requires an import. |
Optional | A value that may or may not be present. |
Tuple | Fixed-size, heterogeneous group of values. |
InlineArray | Fixed-size array stored inline, with no heap allocation. |
Variant | Holds one value from a fixed set of types. Requires import. |
List, Dict, Set, and Tuple support display syntax, as described in
Expressions.
Set and Variant aren't in the prelude. Import Set from
std.collections and Variant from std.utils.
Optional
An Optional[T] holds a T or nothing. It's truthy when a value is
present:
var maybe: Optional[Int] = 5
if maybe:
print(maybe.value()) # 5
value() aborts on empty Optionals. Guard it with a truthiness check, or
call or_else() to supply a default:
var empty: Optional[Int] = None
# empty.value() # aborts: the Optional is empty
print(empty.or_else(0)) # 0
Variant
A Variant holds one value from a fixed set of types, tracked at
runtime. Test the active type with isa[T](), and read it by
indexing with that type:
from std.utils import Variant
var v = Variant[Int, String](5)
print(v[Int]) # 5
v.set[String]("text")
print(v[String]) # text
Memory types
Mojo memory types are pointers and views that provide non-owning access to
memory. They come in safe and unsafe forms, distinguished by the guarantees
the compiler enforces. A Pointer is non-nullable and refers to
initialized memory. UnsafePointer drops those guarantees, can refer to
uninitialized memory, and leaves allocation and deallocation to you.
| Type | What it is |
|---|---|
Pointer | Non-nullable safe pointer to a single value. |
UnsafePointer | Raw pointer. No nullability or safety guarantees. Manual memory management. |
Span | Non-owning view of contiguous data. |
AddressSpace | Identifies where memory lives, such as CPU or GPU. |
OpaquePointer, OptionalUnsafePointer, and the Mut and Immut
forms are aliases of UnsafePointer.
For allocation, pointer arithmetic, and lifetimes, see Pointers.
Other built-in types
Mojo includes several built-in types that don't fit into the above categories but are still fundamental to the language:
| Type | What it is |
|---|---|
Bool | Boolean value, True or False. Backed by a 1-bit type. |
Error | A runtime error raised by a raises function. |
Never | The type of an expression that never produces a value. |
NoneType | The type whose only value is None. |
Slice | The start:end:step descriptor a subscript produces. |
Bool
A Bool struct is backed by a 1-bit value, not a SIMD alias. Its
literals are True and False. Any type that conforms to Boolable
provides a Bool representation that can act as a condition:
var flag = True
if flag:
print("yes") # yes
Error
Error is Mojo's default error type. A function marked raises raises
Error unless it declares another type (raises T):
def parse(s: String) raises -> Int:
raise Error("invalid input")
Never
Never is the type of an expression that never produces a value, such as a
call that always aborts or a loop that never terminates. Values of type
Never can't exist. The compiler treats any code that follows as
unreachable. Never is a compiler type (!kgen.never), not a struct.
from std.os import abort
def fatal() -> Never:
abort() # never returns
None
None is the only value of type NoneType. A function with no
declared return type returns None:
def implicit_greet(name: String):
print("hello", name)
# returns None implicitly
def explicit_greet(name: String) -> None:
print("hello", name)
# returns None explicitly
Slice
A Slice holds start, end, and step, each an Optional[Int].
It's the descriptor that subscript syntax with colons produces; it
carries no data of its own.
What subscripting returns depends on the type being indexed. A
contiguous List slice yields a Span view; a strided slice yields a
new List.
var items = [0, 1, 2, 3, 4, 5]
var middle = items[1:4] # Span view, [1, 2, 3]
var strided = items[::2] # new List, [0, 2, 4]
For slice syntax, see Expressions.