Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Your First Program

Let’s write a complete Flint program: an LED blink on a Raspberry Pi Pico.

Create a New Project

flint new blink

This creates:

blink/
  flint.toml
  src/
    main.fl

The Manifest

Open blink/flint.toml:

name = "blink"
version = "0.1.0"
edition = "2026"
target = "rp2040"
board = "pico"

The manifest tells the compiler what chip to target (rp2040) and which board package to use (pico). The board package knows the default pin layout for your Pico.

The Source

Open blink/src/main.fl:

use std/time
use micro/gpio

const LED_PIN: u32 = 25

fn main() -> never {
    let mut led = gpio.pin(LED_PIN).into_output()

    loop {
        led.toggle()
        time.sleep_ms(1000)
    }
}

Let’s walk through it.

Imports

use std/time
use micro/gpio

Imports are namespaces, not wildcard includes. use micro/gpio gives you the gpio namespace, so you call gpio.pin(...) rather than a bare pin(...). Only the functions your program calls end up in the binary.

Constants

const LED_PIN: u32 = 25

A compile-time constant for the Pico’s onboard LED pin. Constants always require an explicit type.

Entry point

fn main() -> never {

-> never means this function never returns. On MCU firmware, main runs forever. The compiler enforces this: a main that could return is an error on embedded targets.

Pin setup

let mut led = gpio.pin(LED_PIN).into_output()

Configures GPIO pin 25 as a digital output and binds it to led. mut is required because led.toggle() takes a mutable receiver. Mutability is explicit and tracked by the compiler.

The loop

loop {
    led.toggle()
    time.sleep_ms(1000)
}

loop is an infinite loop. led.toggle() flips the pin state. time.sleep_ms(1000) blocks for one second. That is the whole program.

Build

cd blink
flint build --output-format uf2

You will see output like:

compiling project `blink` (rp2040-thumb-pico)
compiled successfully in 0.01s
binary image: 1,108 bytes (1.08KB)
output: `build/blink.uf2` 2,560 bytes (2.5KB)

Flash

Hold BOOTSEL on your Pico while connecting USB. It appears as a USB drive. Copy the UF2:

cp build/blink.uf2 /Volumes/RPI-RP2/   # macOS
# or drag-and-drop in your file manager

The LED blinks. You just wrote and deployed your first Flint program.

Build Outputs

flint build writes artifacts into build/:

FormatFlagDescription
UF2--output-format uf2For drag-and-drop flashing
ELF--output-format elfFor debugging with probe-rs or OpenOCD
BIN--output-format binRaw binary image

Next Steps