Chapter 1: Odin and Me, Setup and a first console program
This chapter:
- See what we're building for the terminal.
- Install Odin and confirm it works.
- Set up your editor.
- Print your first line of output with
odin run.
1.1 What we're building
In this book, I'll quickly walk you through the Odin basics in a few short chapters. We'll build small, complete programs targeting the terminal, using text, colour, and cursor control to make that text feel like a real application.
Along the way, you'll build some utilities: the classic temperature converter, a word counter, nested loops that draw triangles and diamonds out of asterisks, and of course a number-guessing game. Each is a complete, runnable program in its own right, teaching one idea cleanly before moving on.
From Chapter 7 onward, those ideas start pointing at one destination: Muninn, a small console application named after one of Odin's ravens, Memory. It opens with a banner, shows a box-drawn menu, and lets you add, list, search for, and delete short notes that persist between runs. It features a coloured, framed, keyboard-driven interface built entirely from characters printed to standard output, and a note store that persists to a plain text file.
Every visual effect in Muninn: colour, a cleared screen, a box drawn with clean corners, a banner centred just so, is a short sequence of bytes any terminal from the last four decades knows how to interpret.
1.2 What you need
- A computer running Windows, macOS, or Linux.
- A terminal.
- A text editor.
That's the whole list. If you can open a terminal and type, you're fully equipped. Internet access is a bonus for extra research, but it's optional.
1.3 Installing Odin
Follow the official installation guide: https://odin-lang.org/docs/install/. There are prebuilt releases for each platform, and instructions for building from source if you prefer. Work through the guide there rather than trusting a summary here that might drift out of date.
Once it's installed and on your PATH, confirm it:
odin version
You should see something like dev-2026-07:... (I wrote and verified these chapters against a dev-2026-07 build).
1.4 Setting up your editor
Two things make Odin pleasant to write:
- Syntax highlighting. Most editors have an Odin extension; the Odin site links the current ones.
- The language server,
ols.olsgives you go-to-definition, autocomplete, and inline errors. Install it and point your editor's LSP client at it. It isn't required (the compiler is the source of truth), but it makes exploring the standard library far more pleasant.
The command you'll lean on most doesn't need an editor at all:
odin check .
This type-checks a whole package directory without producing a binary: it's fast, and the quickest way to catch a mistake. For the single-file programs we start with, the equivalent is:
odin check hello.odin -file
The -file flag tells Odin to treat one .odin file as a self-contained package, rather than expecting a directory of them. You'll use -file throughout the early chapters, and drop it once Chapter 9 grows the project into a proper multi-file directory.
1.5 Hello, terminal
Make a directory for our exercises and create one file in it:
mkdir odin-and-me
cd odin-and-me
// hello.odin
package main
import "core:fmt"
main :: proc() {
fmt.println("Hello, Odin!")
}
Run it:
odin run hello.odin -file
You should see:
Hello, Odin!
That's the goal: getting your toolchain to compile and run a program. Let's quickly see what this program does and how it works:
package main: a directory is a package (or, with-file, a single file stands in for one); the package containing amainprocedure is a program's entry point. Every program we write here ispackage main.import "core:fmt": pull in Odin's formatted-printing package from the standard library'score:collection. You'll meet several morecore:packages over the coming chapters: Odin's standard library is generous, and it's all we'll need.main :: proc() { ... }: a procedure declaration.::binds a name to a value at compile time; here the value is a procedure. Every Odin program needs exactly onemain.fmt.println("Hello, Odin!"): print a string followed by a newline. You'll usefmt.printlnand its formatted cousinfmt.printfconstantly from here on.
Odin note:
odin runvsodin build.odin runcompiles a temporary binary and immediately executes it: the everyday loop while you're working.odin buildcompiles and stops, leaving you a binary to run yourself (or ship): the tool for Chapter 12, when Muninn becomes something you hand to someone else.
Gotcha: the
-fileflag isn't optional for a lone file.odin run hello.odinon its own fails with an error telling you to add-file. Odin's run/build/check commands expect a package (a directory) by default. Once Chapter 9 gives Muninn several files in one directory, you'll drop-fileand simply runodin run .instead.
1.6 The journey ahead
Here's the road from that one line of output to a working application:
- Ch. 2: a fast tour of the parts of Odin we'll use throughout our programs: types, variables, control flow, procedures.
- Ch. 3: reading a line from the keyboard and parsing it into a number: your first interactive program.
- Ch. 4: strings, runes and UTF-8, building a word-counting tool.
- Ch. 5: nested loops, drawing triangles, diamonds and pyramids out of text.
- Ch. 6: structs, enums and a first taste of randomness, in a number-guessing game.
- Ch. 7: clearing the screen, colour, box-drawing characters, and a menu loop: the DOS-style look, from first principles.
- Ch. 8: reading and writing a file, so a program's data survives being closed and reopened.
- Ch. 9: designing Muninn's note store: a struct, a dynamic array, and the operations over it.
- Ch. 10: wiring the menu and the store together: Muninn, usable end to end.
- Ch. 11: making it robust: validated input, and a save file that survives being corrupted.
- Ch. 12: a release build, and shipping Muninn as a single binary.
Chapters 1 to 8 are one complete, standalone program apiece; each is shown to you in full, start to finish, so you can follow along. From Chapter 9 the project grows into one directory (all one package main):
odin-and-me/
โโโ main.odin # entry point: init, the menu loop, teardown
โโโ screen.odin # ANSI helpers: clear, cursor, colour, box-drawing, banner
โโโ menu.odin # the menu state machine + rendering
โโโ note.odin # the Note struct
โโโ store.odin # add/find/delete/list over the note store
โโโ persist.odin # save/load notes to a file
โโโ input.odin # line-reading + validated-input helpers
โโโ build.sh # makes it easier to build the project
โโโ run.sh # handy for building then running the project
Checkpoint
odin run hello.odin -file prints Hello, Odin! and exits. Your compiler works and your editor is set up.
Exercises
- Change the greeting to print your own name, and add a second
fmt.printlncall that prints a second line. Rebuild and confirm both lines appear in order. - Run
odin check hello.odin -file, then deliberately misspellfmt.printlnasfmt.Println. Read the error message Odin gives you, then fix it. (Solution sketch: Odin is case-sensitive, and the compiler names the exact identifier it couldn't find: get comfortable reading that error, you'll see its shape again.) - Try
fmt.printinstead offmt.printlnfor your two lines. What's different about the output, and why? (Solution sketch:printlnappends a newline after its arguments;printdoesn't: watch your two lines run together.) - What happens if you delete the
main :: proc() { ... }wrapper entirely and leave just thefmt.printlncall at the top level? Try it, read the error, and putmainback. (Solution sketch: Odin has no implicit top-level statements: every executable line has to live inside a procedure, and every program needs exactly onemain.)
Further reading
- Odin install guide: https://odin-lang.org/docs/install/
- Odin language overview: https://odin-lang.org/docs/overview/
olslanguage server: https://github.com/DanielGavin/ols- Understanding the Odin Programming Language: https://odinbook.com/