Skip to content
Pre-Release: Fe is under active development. This documentation covers the upcoming release. Follow progress on GitHub

Built-in Types Reference

This appendix provides a complete reference for Fe’s built-in types.

Unsigned integers cannot be negative. Fe provides sizes matching EVM word boundaries:

TypeBitsBytesRange
u8810 to 255
u161620 to 65,535
u323240 to 4,294,967,295
u646480 to 18,446,744,073,709,551,615
u128128160 to 2¹²⁸ - 1
u256256320 to 2²⁵⁶ - 1
let small: u8 = 255
let balance: u256 = 1000000000000000000 // 1 ETH in wei
let max_supply: u256 = 21000000
  • u256 is the native EVM word size and most efficient for storage
  • Use smaller types when packing multiple values into storage slots
  • Arithmetic overflow causes a revert by default

Signed integers can be negative. They use two’s complement representation:

TypeBitsBytesRange
i881-128 to 127
i16162-32,768 to 32,767
i32324-2,147,483,648 to 2,147,483,647
i64648-2⁶³ to 2⁶³ - 1
i12812816-2¹²⁷ to 2¹²⁷ - 1
i25625632-2²⁵⁵ to 2²⁵⁵ - 1
let delta: i256 = -100
let temperature: i32 = -40
let positive: i256 = 1000
  • Use signed integers when negative values are meaningful
  • Most ERC standards use unsigned integers
  • Signed division and comparison use different EVM opcodes

The bool type represents true/false values:

TypeSizeValues
bool1 bit (stored as 1 byte)true, false
let is_active: bool = true
let paused: bool = false
if is_active && !paused {
// ...
}
OperationSyntaxDescription
ANDa && bTrue if both true
ORa || bTrue if either true
NOT!aInverts the value
Equalitya == bTrue if same value

Fixed-size strings with a maximum length:

TypeDescription
String<N>String with max length N bytes
let name: String<32> = "CoolCoin"
let symbol: String<8> = "COOL"
let message: String<64> = "Transfer failed"
  • String length is fixed at compile time
  • Shorter strings are padded
  • Used for token names, symbols, and error messages

Fixed-size collections of heterogeneous types:

TypeDescription
(T1, T2, ...)Tuple of types T1, T2, etc.
let pair: (u256, bool) = (100, true)
let triple: (u256, u256, u256) = (1, 2, 3)
// Destructuring
let (amount, success) = pair
// Access by index
let first = pair.0
let second = pair.1

Fixed-size collections of homogeneous types:

TypeDescription
[T; N]Array of N elements of type T
let numbers: [u256; 3] = [1, 2, 3]
let first = numbers[0]

The empty tuple, representing no value:

TypeDescription
()Unit type, no value
fn do_something() {
// Implicitly returns ()
}
fn explicit_unit() -> () {
()
}

Represents an optional value:

TypeDescription
Option<T>Either Some(T) or None
let maybe_value: Option<u256> = Option::Some(42)
let nothing: Option<u256> = Option::None
match maybe_value {
Option::Some(v) => v,
Option::None => 0,
}

Key-value storage mapping:

TypeDescription
Map<K, V>Maps keys of type K to values of type V
struct Storage {
balances: Map<Address, u256>,
allowances: Map<(Address, Address), u256>,
}
// Access
let balance = storage.balances[account]
// Update
storage.balances[account] = new_balance
  • Maps are storage-only types
  • Non-existent keys return the zero value
  • Tuples can be used as composite keys

Convert between numeric types with as:

let small: u8 = 100
let big: u256 = small as u256
let signed: i256 = -50
let unsigned: u256 = signed as u256 // Caution: reinterprets bits
FromToBehavior
Smaller unsignedLarger unsignedZero-extends
Larger unsignedSmaller unsignedTruncates
SignedUnsignedReinterprets bits
UnsignedSignedReinterprets bits
CategoryTypes
Unsigned integersu8, u16, u32, u64, u128, u256
Signed integersi8, i16, i32, i64, i128, i256
Booleanbool
StringString<N>
Tuple(T1, T2, ...)
Array[T; N]
Unit()
OptionalOption<T>
MapMap<K, V>
TypeEVM StorageNotes
u2561 slotNative word size
u1281/2 slotCan pack 2 per slot
u641/4 slotCan pack 4 per slot
bool1 slotUnless packed
MapDynamicUses keccak256 hashing