Hello World
Let’s build a simple status bar to understand the basics of Guido. By the end of this tutorial, you’ll have a working application like this:

Creating the Project
Start with a new Rust project:
cargo new hello-guido
cd hello-guido
cargo add guido
The Complete Code
Replace src/main.rs with:
use guido::prelude::*;
fn main() {
App::new().run(|app| {
app.add_surface(
SurfaceConfig::new()
.height(32)
.anchor(Anchor::TOP | Anchor::LEFT | Anchor::RIGHT)
.background_color(Color::rgb(0.1, 0.1, 0.15)),
|| {
container()
.height(fill())
.layout(
Flex::row()
.spacing(8.0)
.main_alignment(MainAlignment::SpaceBetween)
.cross_alignment(CrossAlignment::Center),
)
.child(
container()
.padding(8.0)
.background(Color::rgb(0.2, 0.2, 0.3))
.corner_radius(4.0)
.child(text("Guido")),
)
.child(container().padding(8.0).child(text("Hello World!")))
.child(
container()
.padding(8.0)
.background(Color::rgb(0.3, 0.2, 0.2))
.corner_radius(4.0)
.child(text("Status Bar")),
)
},
);
});
}
Run it with cargo run.
Understanding the Code
Let’s break down each part:
The Prelude
#![allow(unused)]
fn main() {
use guido::prelude::*;
}
The prelude imports everything you need: widgets, colors, layout types, and reactive primitives.
Surface Configuration
#![allow(unused)]
fn main() {
App::new().run(|app| {
let _surface_id = app.add_surface(
SurfaceConfig::new()
.height(32)
.anchor(Anchor::TOP | Anchor::LEFT | Anchor::RIGHT)
.background_color(Color::rgb(0.1, 0.1, 0.15)),
|| { /* widget tree */ },
);
});
}
The SurfaceConfig defines how the window appears:
- Height - 32 pixels tall
- Anchor - Attached to top, left, and right edges (full width)
- Background color - Dark background for the bar
Note: run() takes a setup closure where you add surfaces. add_surface() returns a SurfaceId that can be used to get a SurfaceHandle for modifying surface properties dynamically.
Building the View
The view is built using containers - the primary building block in Guido:
#![allow(unused)]
fn main() {
container()
.height(fill())
.layout(
Flex::row()
.spacing(8.0)
.main_alignment(MainAlignment::SpaceBetween)
.cross_alignment(CrossAlignment::Center),
)
}
This creates a container that:
- Fills the available height with
fill() - Uses a horizontal flex layout
- Centers children vertically with
cross_alignment - Spreads children across the space with
SpaceBetween
Adding Children
Each section of the status bar is a child container:
#![allow(unused)]
fn main() {
.child(
container()
.padding(8.0)
.background(Color::rgb(0.2, 0.2, 0.3))
.corner_radius(4.0)
.child(text("Guido")),
)
}
The container has:
- Padding - 8 pixels of space around the content
- Background - A dark purple-gray color
- Corner radius - Rounded corners
- Child - A text widget
Text Widgets
#![allow(unused)]
fn main() {
text("Hello World!")
}
The text() function creates a text widget. Text inherits styling from its container by default, with white text color.
Adding Interactivity
Let’s make it interactive with a click counter. Update your code:
use guido::prelude::*;
fn main() {
App::new().run(|app| {
let count = create_signal(0);
app.add_surface(
SurfaceConfig::new()
.height(32)
.anchor(Anchor::TOP | Anchor::LEFT | Anchor::RIGHT)
.background_color(Color::rgb(0.1, 0.1, 0.15)),
move || {
container()
.height(fill())
.layout(
Flex::row()
.spacing(8.0)
.main_alignment(MainAlignment::SpaceBetween)
.cross_alignment(CrossAlignment::Center),
)
.child(
container()
.padding(8.0)
.background(Color::rgb(0.2, 0.2, 0.3))
.corner_radius(4.0)
.hover_state(|s| s.lighter(0.1))
.pressed_state(|s| s.ripple())
.on_click(move || count.update(|c| *c += 1))
.child(text(move || format!("Clicks: {}", count.get()))),
)
.child(container().padding(8.0).child(text("Hello World!")))
.child(
container()
.padding(8.0)
.background(Color::rgb(0.3, 0.2, 0.2))
.corner_radius(4.0)
.child(text("Status Bar")),
)
},
);
});
}
What Changed?
- Signal -
create_signal(0)creates a reactive value - Hover state -
.hover_state(|s| s.lighter(0.1))lightens on hover - Pressed state -
.pressed_state(|s| s.ripple())adds a ripple effect - Click handler -
.on_click(...)increments the counter - Reactive text -
text(move || format!(...))updates when the signal changes
Next Steps
You’ve built your first Guido application. Continue learning:
- Running Examples - Explore more complex examples
- Core Concepts - Understand the reactive system
- Building UI - Learn styling and layout