The basics
What is a Go file?
A .go file holds source code written in Go, a programming language designed at Google from 2007 and released as open source in 2009. It's built for servers, networked services and command-line tools, and much cloud infrastructure is written in it, including Docker, Kubernetes and Terraform.
The file is plain UTF-8 text. The go command compiles it, together with the other files of its package and its dependencies, into one executable with no runtime or interpreter to install, which is why Go programs are easy to ship as a single file.
Three things that clear up common confusion:
- The folder is the unit, not the file. All
.gofiles in one folder belong to one package and are compiled together. A function defined ina.gocan be used inb.gowithout importing anything. - Go and Golang are the same. The language is called Go; "golang" comes from its original website, golang.org, and is still handy as a search term.
- A
.gofile isn't a script.go run file.gofeels like running a script, but it compiles the program to a temporary executable first, then runs that.
Anatomy
What's inside a Go file
Every Go file has the same shape: a package clause, then imports, then declarations of types, variables, constants and functions in any order. Here is a small command-line program, part by part.
// Command greet prints a greeting for each name given.
package main
import (
"errors"
"flag"
"fmt"
"os"
"strings"
)
var shout = flag.Bool("shout", false, "print in capitals")
type greeter struct {
greeting string
}
func (g greeter) greet(name string) (string, error) {
if name == "" {
return "", errors.New("empty name")
}
msg := g.greeting + ", " + name + "!"
if *shout {
msg = strings.ToUpper(msg)
}
return msg, nil
}
func main() {
flag.Parse()
g := greeter{greeting: "Hello"}
for _, name := range flag.Args() {
msg, err := g.greet(name)
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
fmt.Println(msg)
}
}- 1
// Command greet prints …A doc comment
A comment directly above a declaration documents it;
go docand pkg.go.dev show it. Abovepackage main, it describes the whole program. - 2
package mainThe package clause
Always the first statement. Every
.gofile in a folder must name the same package.mainis special: together with afunc main, it makes an executable program. Any other name makes a library. - 3
import ( "errors" … )Imports
Packages this file uses, from the standard library here. An import that isn't used is a compile error, not a warning;
goimportsand editors add and remove them for you. - 4
var shout = flag.Bool("shout", …)A package-level variable
Declared outside any function and visible in every file of the package. This one defines a
-shoutcommand-line flag. - 5
type greeter struct { greeting string }A struct type
Go has no classes: types are structs, and behaviour comes from methods. Lower-case names are private to the package; capitalised names are exported.
- 6
func (g greeter) greet(name string) (string, error)A method with two results
(g greeter)is the receiver: it attachesgreetto the type. Functions can return several values, and a function that can fail returns anerrorlast. - 7
errors.New("empty name")An error value
Go has no exceptions for ordinary failures. Errors are values that the caller checks, usually with
if err != nil. - 8
msg := g.greeting + …A short variable declaration
:=declares a variable and infers its type from the value. A variable that's declared and never used is a compile error. - 9
for _, name := range flag.Args()A range loop
foris Go's only loop.rangegives the index and the value;_, the blank identifier, discards the index. - 10
os.Exit(1)The exit status
Ends the program with status 1, failure. Returning from
mainnormally means 0, success. - 11
if err != nil {gofmt's layout
Tabs for indentation and the opening brace on the same line. The brace isn't style: Go inserts semicolons at line ends, so a brace on its own line is a syntax error.
Under the hood
How to run and build a Go file
Install Go from the official installers at go.dev/dl (an .msi for Windows, a .pkg for macOS, an archive for Linux) or from a package manager. The same commands then work on every system:
| Command | What it does |
|---|---|
go run file.go | Compiles the named files to a temporary program and runs it. Handy for a single file |
go run . | Compiles and runs the package in the current folder; needs a go.mod file |
go build | Makes an executable in the current folder: name on Linux and macOS, name.exe on Windows |
go install | Builds and puts the executable in Go's bin folder, usually ~/go/bin |
go test | Compiles and runs the package's tests, from its _test.go files |
go vet | Reports likely mistakes that compile fine, such as Printf formats that don't match their arguments |
gofmt -w file.go | Rewrites the file in Go's standard layout |
Go cross-compiles without extra tools: GOOS=windows GOARCH=amd64 go build on a Mac or Linux machine produces a Windows .exe (on Windows, set the variables with set or $env: first). The output only runs on the system it was built for, but the .go files build anywhere.
Projects
Packages, modules and the go.mod file
A package is a folder of .go files. A module is a tree of packages with a go.mod file at its root, which names the module, the minimum Go version and the modules it depends on. go.sum sits next to it with a cryptographic hash of each dependency, so a build fails if downloaded code changes.
# start a module in an empty folder
go mod init example.com/greet
# go.mod, for example:
module example.com/greet
go 1.24
require example.com/othermodule v1.2.3
# everyday commands
go run . # compile and run the package in this folder
go build # make an executable: greet, or greet.exe on Windows
go test ./... # run every _test.go file in the module
go mod tidy # add missing requirements, remove unused ones- The
goline is a requirement. Since Go 1.21, a toolchain refuses to build a module that declares a newer Go version. With the default settings it downloads the newer toolchain automatically; withGOTOOLCHAIN=localit stops with an error. - One package per folder. All files in a folder must use the same
packagename; the only exception is a test file in packagename_test, which tests the package from outside. - The import path is the folder.
import "example.com/greet/internal/names"refers to theinternal/namesfolder of the moduleexample.com/greet.
Conventions
File names, build constraints and gofmt
The go command reads meaning into file names, so they matter more than in most languages:
| File name | What the go command does with it |
|---|---|
name_test.go | A test file: compiled only by go test, never into the program |
name_linux.go, name_windows.go | Compiled only when building for that operating system (any GOOS value) |
name_arm64.go, name_windows_amd64.go | Compiled only for that processor, or that system and processor (GOARCH, GOOS_GOARCH) |
_name.go, .name.go | Ignored, along with folders named testdata |
name.go | Compiled on every system, unless a //go:build line says otherwise |
A build constraint does the same job in the file itself. //go:build linux || darwin or //go:build unix must come before the package clause, with only blank lines and comments above it. //go:build ignore keeps a file out of every build. Build constraints apply to packages: when you name files on the command line (go run file.go), they're ignored.
- gofmt is the style guide. It sets indentation (tabs), spacing and alignment, and almost all published Go code has been run through it. Editors run it on save.
gofmt -l .lists files that need formatting, which makes a common CI check. - UTF-8, LF, no BOM. The specification requires UTF-8 and lets compilers ignore a byte order mark at the start. gofmt removes a BOM and converts Windows CRLF line endings to LF.
- Directives are comments. Lines like
//go:build,//go:embed(files built into the program) and//go:generate(a command forgo generateto run) are written with no space after//.
Testing
_test.go files and go test
Go's testing tools are built in. Tests sit next to the code they test, in files ending _test.go, and go test finds the functions in them by name:
| Function | Run by | Purpose |
|---|---|---|
func TestXxx(t *testing.T) | go test | A test: calls t.Error or t.Fatal to fail |
func ExampleXxx() | go test | Runs and compares its printed output with an // Output: comment; also shown in the documentation |
func BenchmarkXxx(b *testing.B) | go test -bench=. | Measures how long the code takes |
func FuzzXxx(f *testing.F) | go test -fuzz=FuzzXxx | Feeds generated inputs to find crashes (since Go 1.18) |
go test also runs a subset of go vet's checks before the tests, and go test ./... tests every package in the module. The sample-wordcount_test.go file below has a table-driven test with Unicode cases, an example and a benchmark.
Versions
Go versions and the compatibility promise
Go has stayed at version 1 since 2012, under a compatibility promise: code written for an older Go 1 release keeps compiling with newer ones. A new release comes out every six months, in February and August, and each one is supported with security fixes until two newer releases are out.
| Version | Released | Notable for |
|---|---|---|
| Go 1.18 | March 2022 | Generics (type parameters) and fuzz testing |
| Go 1.21 | August 2023 | min and max, the slices, maps and cmp packages, and the go line in go.mod becoming a requirement |
| Go 1.22 | February 2024 | Each loop iteration gets its own variable, ending a classic goroutine bug; for i := range 10 |
| Go 1.23 | August 2024 | Range over functions, the basis of iterators |
| Go 1.24 | February 2025 | Generic type aliases, and testing.B.Loop for benchmarks |
| Go 1.27 | August 2026 | Methods can have their own type parameters; requires macOS 13 or later |
Which version a file is compiled as comes from the go line of its module's go.mod, not from the toolchain. A //go:build go1.22 line can limit one file to newer versions.
Related formats
Go compared with C, Rust, Java and Python files
| Go (.go) | C (.c) | Rust (.rs) | Java (.java) | Python (.py) | |
|---|---|---|---|---|---|
| Compiled to | A native executable | A native executable | A native executable | Bytecode for the Java virtual machine | Usually interpreted |
| Memory | Garbage collected | Managed by hand | Ownership rules, checked at compile time | Garbage collected | Garbage collected |
| Official formatter | gofmt | None | rustfmt | None | None |
| Project file | go.mod | Makefile, CMakeLists.txt | Cargo.toml | pom.xml, build.gradle | pyproject.toml |
| Unused import | Compile error | Allowed | Warning | Allowed | Allowed |
See the C, Rust, Java and Python explainers for those formats.
Troubleshooting
Go errors people hit most, and what they mean
| Message | Usual cause | Fix |
|---|---|---|
| "os" imported and not used | An import left over after editing | Remove it, or let goimports or your editor manage imports |
| declared and not used: x | A variable that's assigned but never read | Use it, remove it, or assign it to _ while debugging |
| syntax error: unexpected semicolon or newline before { | An opening brace on its own line | Put { at the end of the line before; gofmt can't fix this one for you |
| go: go.mod file not found in current directory or any parent directory | go run . or go build outside a module | Run go mod init example.com/name, or name the file: go run file.go |
| found packages main (a.go) and foo (b.go) in … | Files with different package names in one folder | Move one into its own folder |
| no required module provides package … | A new import that go.mod doesn't list yet | Run go get with the package path, or go mod tidy |
| build constraints exclude all Go files in … | Every file is limited to other systems, by name suffix or //go:build | Build for the right GOOS/GOARCH, or check the constraints |
| go.mod requires go >= 1.27 (running go 1.24…) | The module needs a newer Go than the one installed, and automatic toolchain downloads are off | Update Go, or allow GOTOOLCHAIN=auto |
How to
How to open and edit a Go file, and is it safe?
- Read it: any text editor or a browser shows it as text. Go code is easy to read without tools, partly because gofmt makes all of it look the same.
- Edit it: VS Code with the Go extension, GoLand, and Vim, Neovim or Emacs with
gopls, Go's language server, give completion, errors as you type and formatting on save. - Try it online: the Go Playground at go.dev/play runs small programs in the browser and gives each one a shareable link.
Opening a .go file is safe: it's text. Running it with go run compiles and runs it with your permissions, like any program. Go's tooling is careful about the step in between: fetching and building modules doesn't run code from them, there are no install scripts, and go.sum with Go's checksum database makes sure everyone downloads the same code for a given version. Code generators only run when you ask with go generate, and govulncheck reports known vulnerabilities in the dependencies a program actually uses.
Free downloads
Sample Go files to download
Free sample Go files for testing editors, syntax highlighting, code viewers, CI and upload filters. Each one is gofmt-formatted, passes go vet and runs; the tests pass with go test. They need Go 1.21 or later, and Go 1.24 or later for the benchmark.
Loading…What's inside sample-program.go
The file is commented: open it in a text editor and each numbered comment marks one of these parts. Run it with go run sample-program.go to see a stock report.
Comments 1 and 2: the package clause and imports
package main, which makes a program, and five standard library packages, each of which must be used.Comments 3 to 5: a constant, a struct and a method
A package-level constant, an
itemstruct with unexported fields, and avaluemethod attached to it.Comment 6: an interface, satisfied implicitly
A
Stringmethod makesitemafmt.Stringerwithout declaring it, sofmt.Printlnprints items with it.Comment 7: errors as values
findreturns an item and an error, wrapping a sentinel error with%wso callers can test it witherrors.Is.Comments 8 and 9: slices and sorting
A slice of fictional shop items, sorted largest value first with
slices.SortFuncandcmp.Compare.Comments 10 and 11: goroutines and defer
One goroutine per item, a
sync.WaitGroupto wait for them and a mutex around the shared total;defer wg.Done()runs when each goroutine finishes.Comment 12: checking errors
One lookup that succeeds and one that fails, recognised with
errors.Is.
All sample Go files
Commented sample program
sample-program.go · 3.0 KB (3,076 bytes)
A complete program that prints a sorted stock report: a struct with methods, an implicit interface, error values, slices, sorting, goroutines with a WaitGroup and mutex, and
defer, with numbered comments explaining each part.- Checking editors, linters and syntax highlighters on Go
- Teaching the parts of a Go program
Hello world
sample-hello.go · 214 bytes
The classic first Go program:
package main, one import andfunc main.- A minimal build test
- Checking a new Go installation
Word counter with Unicode text
sample-wordcount.go · 1.8 KB (1,887 bytes)
Counts words in English, French, German and Japanese text with
unicode.IsLetter, and prints each word's length in bytes and in runes (characters).- Encoding tests with non-ASCII string literals
- The code that `sample-wordcount_test.go` tests
Test file (_test.go)
sample-wordcount_test.go · 2.1 KB (2,165 bytes)
Tests for
sample-wordcount.go: a table-driven test with subtests and Unicode cases, a tie-breaking test, anExamplefunction with checked output and a benchmark. Run withgo test -v sample-wordcount.go sample-wordcount_test.go.- Checking CI runs and reports Go tests
- Testing tools that treat `_test.go` files specially
Build constraint (//go:build unix)
sample-unix.go · 1.4 KB (1,473 bytes)
Prints the open-file limits with
syscall.Getrlimit, which Windows doesn't have, so the file carries//go:build unix. In a module,GOOS=windows go build .reports "build constraints exclude all Go files".- Testing how tools handle build constraints
- Cross-compilation checks in CI
100 KB Go file
sample-100kb.go · 100 KB (102,400 bytes)
A table of the first 13,860 prime numbers and a program that checks every one, padded with a comment to exactly 102,400 bytes. gofmt-clean and runs.
- Upload and size-limit tests
- Editor, highlighter and compile-time benchmarks
Ways to test with them
- CI checks:
gofmt -lon the samples should list nothing, andgo vetandgo runshould pass on each file by name. Each sample is its own program with its ownmain, so give each one its own folder before building them as packages. - Build constraints: build
sample-unix.goin a module withGOOS=windows,GOOS=linuxandGOOS=darwinto check your pipeline's cross-compilation. - Encoding:
sample-wordcount.goshould printcaféas 5 bytes and 4 runes; anything else means the file's encoding changed on the way. - Upload limits:
sample-100kb.gois exactly 102,400 bytes, for testing a limit at the boundary.
Free to use for testing, teaching and demos, commercially or not, with no attribution needed. A link back to this page is always appreciated.
Put it online
Have a Go file? Give it a link.
Drop a .go file on 99helpers and it gets its own web address. Anyone who opens the link reads the code as plain text in their browser: it is never compiled or run, which makes it a simple way to share code for review, teaching or a bug report.
Questions
Go files, frequently asked
What is a .go file?
A source code file written in Go, a programming language created at Google. It's plain text that the go command compiles into an executable program.
How do I open a GO file?
Open it in any text editor or code editor, such as VS Code (with the Go extension), GoLand or Notepad. To run it, install Go and use go run.
How do I run a .go file?
Install Go from go.dev/dl, then run go run file.go in a terminal. To make a program you can run again without Go installed, use go build file.go.
Do I need a go.mod file?
Not to run a single file with go run file.go. You need one for anything bigger: go run ., go build in a folder, go test ./... and third-party packages all work through modules. Create it with go mod init.
What is a _test.go file?
A file of tests. The go command only compiles files ending in _test.go when you run go test, never into the program itself.
What do file names like main_linux.go mean?
A suffix naming an operating system or processor is a build constraint: main_linux.go is only compiled when building for Linux, main_windows_amd64.go only for 64-bit Windows.
Is it Go or Golang?
The language is called Go. "Golang" comes from its original website, golang.org, and is used as a search term and hashtag.
What is the latest version of Go?
Go 1.27, released in August 2026, with point releases for fixes since. New versions come out every February and August.
Related formats
Other file types explained
Keep going
Related
Sources
- The Go Programming Language Specification
- Go release history
- Go 1.27 release notes
- go.mod file reference
- The go command: build constraints
- The Go Blog: How Go mitigates supply chain attacks
Last reviewed 27 October 2026.