Week 1 · The Vault · Night 1 of 31
Night 1 · It's Alive!
📺 “Good evening, and welcome to the first night of Night School. Tonight we do what Victor Frankenstein did: assemble something from parts and shout when it moves. Our parts are a text editor, a terminal and the Go toolchain. Our shout will be quieter.”
Tonight you’ll learn
- What Go is and why it suits command-line tools
- How to install Go and check it works
- What a module is, and
go mod init - Your first program:
package main,func main, andfmt go runversusgo build
Where we are: an empty folder.
Why Go for a terminal program?
Go compiles to a single file with no dependencies. You build terminal-of-terror, hand it to a friend, and it runs: no runtime to install, no node_modules, no virtual environments. It builds for Windows, macOS and Linux from one machine, it starts in milliseconds, and its standard library already covers JSON, files, testing and time. Nearly every popular terminal tool of the last decade is written in it.
Go is also a small language. There are 25 keywords. You can learn all the syntax in a week and spend the rest of your life learning how to use it well, which is the right way round.
Install Go
Download the installer for your system from go.dev/dl and run it. Then open a new terminal and check:
go version
You should see go version go1.25.x or newer. If the command isn’t found, the installer didn’t put Go on your PATH; the install page has the fix for each system.
A place for the monsters
Make a folder and step into it:
mkdir terminal-of-terror
cd terminal-of-terror
Now tell Go this folder is a module, a unit of code with a name and a list of the libraries it uses:
go mod init github.com/hungovercoders/terminal-of-terror
This creates go.mod:
module github.com/hungovercoders/terminal-of-terror
go 1.25
The module name looks like a web address because Go modules are usually published on sites like GitHub, and the name is where other people would fetch them from. Nothing is being published tonight. Using this exact name means every import in the course matches your code; on Night 31 you’ll see how to rename it.
The first program
Create main.go:
package main
import "fmt"
func main() {
fmt.Println("🎃 It's alive!")
}
Three things to know:
package mainmarks this as a program rather than a library. Every Go file starts with apackageline.import "fmt"brings in the format package from the standard library, which does printing.func main()is where the program starts. Go looks for exactly this function inpackage main.
Go is fussy about formatting and has a tool that settles every argument: gofmt. Editors with a Go extension run it on save. Tabs for indentation, braces on the same line, no semicolons. You’ll never think about it again.
Run it:
go run .
🎃 It's alive!
go run . compiles the program in the current folder (.) and runs it in one step. It’s the command you’ll use most while developing.
Build a real binary
go build -o terminal-of-terror
./terminal-of-terror
On Windows, the file is terminal-of-terror.exe and you run .\terminal-of-terror.exe.
That file is the whole program. Copy it to another computer with the same operating system and it runs. It’s about two megabytes, most of which is the Go runtime (memory management, the scheduler) that every Go program carries.
Save your work
Tell Git to ignore the binary, then make your first commit:
git init
printf 'terminal-of-terror\nterminal-of-terror.exe\n' > .gitignore
git add .
git commit -m "feat: it's alive"
The commit message follows a convention called Conventional Commits: a type (feat, fix, docs, chore), a colon, and a short description. On Night 31 a tool will turn these messages into a changelog, so it pays to start now.
Try it
- Change the message. Run
go run .again. - Break something: delete the closing
}and run it. Read the error. Go’s compiler errors say the file, the line and what it expected; they’re your friend for the next 30 nights. - Add a second line:
fmt.Println("Tonight's feature:", "Dracula"). NoticePrintlnputs a space between its arguments.
💀 Terrifying fact
go run . doesn’t leave a binary behind, so where did the program go? Into a cache directory, along with every package you’ll ever compile. go env GOCACHE shows where. Go’s compiler is fast partly because it never compiles the same package twice.
🕯️ Before dawn
Make main.go print a three-line title card:
==========================
TERMINAL OF TERROR
==========================
Hint: a string can contain \n for a new line, and strings.Repeat("=", 26) from the strings package makes the rule. You’ll need to import "strings" as well as "fmt": group the imports in parentheses, one per line.
📺 “It moved. Dr Frankenstein would be proud, and possibly arrested. Tomorrow night we give it a skeleton.”