Project Layout
A Flint project is simple by design.
my_project/
flint.toml ← manifest
src/
main.fl ← entry point
drivers/
display.fl ← local module
sensor.fl ← local module
build/ ← generated by flint build (git-ignore this)
The Manifest (flint.toml)
flint.toml is TOML and lives at the project root. The minimal required fields are:
name = "my_project"
version = "0.1.0"
edition = "2026"
target = "rp2040"
board = "pico"
| Field | Description |
|---|---|
name | Project name. Used as the artifact filename. |
version | Semver project version. |
edition | Source compatibility year. Use 2026. |
target | The chip to compile for (e.g., rp2040). |
board | The board package (e.g., pico). |
Optional Manifest Fields
# Allow recursive function calls on MCU targets.
# Disabled by default on MCU targets to catch stack-risk bugs.
allow-recursion = true
Source Files
All source lives under src/. Files use the .fl extension. Each file is exactly one module.
The entry point is always src/main.fl. Modules are imported with use using their path relative to src/:
// src/main.fl
use drivers/display
use drivers/sensor
fn main() -> never {
display.init()
let temp = sensor.read_celsius()
display.show_temp(temp)
loop {}
}
// src/drivers/display.fl
pub fn init() -> () {
// ...
}
pub fn show_temp(temp_c: i32) -> () {
// ...
}
The file src/drivers/display.fl maps to the module path drivers/display. Its exported functions are accessed as display.init(), display.show_temp(...).
Module Rules
- One file, one module. No
moduledeclarations in source. - Import paths use
/, not.or::. - The last path segment is the default module name:
use drivers/displayimports asdisplay. - Use
asto rename:use drivers/display as screen. - No wildcard imports (
use foo/*is not supported). - No relative imports (
./fooor../fooare not supported).
Build Output
flint build writes artifacts into build/ inside your project:
build/
my_project.uf2
my_project.elf
my_project.bin
The build/ directory is generated. Add it to your .gitignore.
PIO Files
RP2040 PIO programs live anywhere under src/ with a .pio extension:
src/
main.fl
drivers/
blink.pio
Reference them at compile time through micro/pio:
use micro/pio
let program = pio.program_file("drivers/blink.pio")?
The compiler assembles the PIO program during the build.
Manifestless Builds
You can build a single file or directory without a flint.toml, but you must specify the target explicitly:
flint build src/main.fl --target rp2040
flint build src/ --target rp2040
Manifestless builds are useful for quick experiments. For real projects, always use a manifest.