Skip to content

Hello, World — Your First Rust Program

Writing “Hello, world!” is the first ritual in any new language. In TypeScript you reach for console.log. In Rust you reach for println!. They look similar but work very differently under the hood.

TypeScript
// TypeScript hello world
const greeting: string = "Hello, world!";
console.log(greeting);
// Template literals
const name = "TypeScript developer";
console.log(`Welcome, ${name}!`);
Rust
fn main() {
let greeting: &str = "Hello, world!";
println!("{greeting}");
// Named argument in format string
let name = "TypeScript developer";
println!("Welcome, {name}!");
}

There are several things to notice immediately:

  • fn main() — every Rust binary starts here. There is no module system or top-level execution like Node.js; main is the required entry point.
  • println! — the exclamation mark means this is a macro, not a function. The format string is checked at compile time: {greeting} is replaced with the value of the variable greeting. This is similar to a template literal, but the checking happens at compile time, not runtime.
  • let greeting: &str&str is a string slice, a reference to a sequence of UTF-8 bytes. Think of it as an immutable view into a string. The owned, heap-allocated string type is String.
  • Semicolons — Rust uses semicolons to end statements, just like TypeScript.

println! is more powerful than console.log. The format string uses {} as the placeholder, and you can reference variables by name ({name}) or use positional placeholders:

println!("{}", value); // positional
println!("{value}"); // named (Rust 1.58+)
println!("{:?}", value); // debug format — works on most types
println!("{:#?}", value); // pretty debug format
println!("{:.2}", 3.14159); // 3.14 — two decimal places

After scaffolding with cargo new hello-world, the src/main.rs file contains:

fn main() {
println!("Hello, world!");
}

Run it:

Terminal window
cargo run

You will see:

Compiling hello-world v0.1.0
Finished dev [unoptimized + debuginfo] target(s) in 0.42s
Running `target/debug/hello-world`
Hello, world!

The first run compiles, subsequent runs recompile only changed files — similar to incremental TypeScript compilation.

Run a Rust program in your browser right now. No installation needed.

fn main() {
println!("Hello, world!");
let name = "TypeScript developer";
println!("Welcome, {name}!");
// Debug formatting with {:?}
let numbers = [1, 2, 3, 4, 5];
println!("numbers = {numbers:?}");
// Formatted floats
let pi = 3.14159;
println!("pi = {pi:.2}");
}
What does the `!` after `println` indicate?
What is the entry point function in a Rust binary program?
Which format specifier prints a value using debug formatting in println!?
What command compiles and immediately runs a Rust project?