Menu

Go Hello World: Your First Golang Program Explained

The Go hello world program line by line: package main, the import block, func main, and fmt.Println, plus how to run it and the compile errors beginners hit first.

This page includes runnable editors - edit, run, and see output instantly.

Here is the whole program. Press Run.

None of these lines is optional. The rest of this page explains what each one does.

Line by Line

package main

Every Go file starts with a package clause naming the package it belongs to. The name main is special: it marks the package as an executable program. Any other name (package utils, package hello) makes a library that other code imports but that cannot run on its own.

import "fmt"

import brings in another package so you can use it. fmt is the standard library's formatting and printing package. After the import, its exported names are reached through the package name: fmt.Println, fmt.Printf, fmt.Sprintf.

To import several packages, use a parenthesized block with one path per line:

import (
	"fmt"
	"strings"
)

Go refuses to compile a file that imports a package it does not use. That keeps dependency lists honest, and it is the first error most people hit.

func main()

func declares a function. main in package main is the entry point: the program starts when main starts and ends when main returns. It takes no arguments and returns nothing. Command-line arguments come from os.Args, and exit codes from os.Exit.

fmt.Println("Hello, World!")

Println prints its arguments, puts a space between them, and adds a newline. The name starts with a capital letter because only capitalized names are exported from a package. fmt.println with a lowercase p is a compile error.

Printing More Than a String

Println takes any number of values of any type. Printf gives you control over the format:

%s is replaced by a string and %d by an integer. Printf and Print do not add a newline, so you write \n yourself. The full verb table is on the fmt.Printf page.

Run It on Your Machine

With Go installed, save the program as main.go in an empty folder and run it:

go run main.go
Hello, World!

go run compiles the file to a temporary binary and runs it. To produce a binary you can keep and copy elsewhere, use go build:

go mod init example.com/hello
go build
./hello
Hello, World!

go build needs a module (a go.mod file), which go mod init creates. The binary is named after the last part of the module path, hello here (hello.exe on Windows). The difference between run, build and install is covered in go run and go build.

Where Semicolons Went

Go's grammar uses semicolons, but you almost never type them. The compiler inserts one at the end of any line whose last token could end a statement: an identifier, a literal, ), }, and a few keywords like return. That rule is why this common style from other languages fails:

func main()
{
	fmt.Println("Hello, World!")
}
./main.go:6:1: syntax error: unexpected semicolon or newline before {

A semicolon was inserted after func main(), so the { on the next line is an error. The opening brace always goes on the same line. The same rule applies to if, for, switch and every other block.

First Errors, Explained

These are the messages beginners see in their first hour, exactly as Go 1.24 prints them.

An unused import or variable.

package main

import (
	"fmt"
	"os"
)

func main() {
	x := 5
	fmt.Println("hi")
}
./main.go:5:2: "os" imported and not used
./main.go:9:2: declared and not used: x

Both are compile errors, not warnings. Delete the import or the variable. If you need to keep a variable during debugging, assign it to the blank identifier: _ = x.

Lowercase function name.

./main.go:6:6: undefined: fmt.println

Unexported names are invisible outside their package. Use fmt.Println.

The wrong package name.

package example.com/hello is not a main package

The file says package hello (or anything other than main) and you tried to run it. Change it to package main.

Missing module.

go: go.mod file not found in current directory or any parent directory; see 'go help modules'

go build and go run . work on modules. Run go mod init example.com/hello once in the folder. go run main.go, which names a file, works without one.

Formatting

Go has one official code style, and gofmt applies it. Run it on every file you write:

go fmt ./...

It uses tabs for indentation, aligns comments and struct fields, and normalizes spacing. Editors with Go support run it on save. Go code everywhere looks the same, so there is nothing to configure and nothing to debate in code review.

Frequently Asked Questions

How do you write hello world in Go?

Save this as main.go:

package main

import "fmt"

func main() {
	fmt.Println("Hello, World!")
}

Then run go run main.go. It prints Hello, World!.

Why does a Go program need package main?

package main tells the compiler this package is an executable program rather than a library. The program starts at the main function of package main. Any other package name produces a library, and go run refuses it with "is not a main package".

Why is the opening brace on the same line in Go?

Go inserts semicolons automatically at the end of lines that could end a statement, including after func main(). A { on the next line would then start a separate block, so the compiler reports syntax error: unexpected semicolon or newline before {. The brace must go on the same line.

What does fmt mean in Go?

fmt is the standard library package for formatted input and output (the name is short for "format"). fmt.Println prints its arguments with spaces between them and a newline at the end; fmt.Printf prints using a format string.

Coddy programming languages illustration

Learn to code with Coddy

GET STARTED