File types · Explainer

The Go source file (.go)

A Go file is a plain-text file of source code in the Go programming language, which the go command compiles into a single executable program. This guide explains what's inside one, how to run, build and test it, the file-naming rules Go relies on, and has free sample Go files to download for testing.

At a glance

Full name
Go source file (the language is also called Golang)
Extensions
.go; tests end in _test.go
MIME type
None registered; Linux desktops use text/x-go
Kind
Plain text (source code), compiled before it runs
Encoding
UTF-8, required by the language specification
Standard
The Go Programming Language Specification, maintained by the Go project at Google
First released
Designed at Google from 2007 by Robert Griesemer, Rob Pike and Ken Thompson; open source since November 2009; Go 1.0 in 2012
Current version
Go 1.27, released August 2026; a new release comes out every February and August
Formatting
One official style, applied by gofmt: tabs for indentation
Comments
// line and /* block */
Magic number
None; every file starts with comments or a package clause

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 .go files in one folder belong to one package and are compiled together. A function defined in a.go can be used in b.go without 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 .go file isn't a script. go run file.go feels 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.

greet.go
// 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. 1// Command greet prints …

    A doc comment

    A comment directly above a declaration documents it; go doc and pkg.go.dev show it. Above package main, it describes the whole program.

  2. 2package main

    The package clause

    Always the first statement. Every .go file in a folder must name the same package. main is special: together with a func main, it makes an executable program. Any other name makes a library.

  3. 3import ( "errors" … )

    Imports

    Packages this file uses, from the standard library here. An import that isn't used is a compile error, not a warning; goimports and editors add and remove them for you.

  4. 4var shout = flag.Bool("shout", …)

    A package-level variable

    Declared outside any function and visible in every file of the package. This one defines a -shout command-line flag.

  5. 5type 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. 6func (g greeter) greet(name string) (string, error)

    A method with two results

    (g greeter) is the receiver: it attaches greet to the type. Functions can return several values, and a function that can fail returns an error last.

  7. 7errors.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. 8msg := 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. 9for _, name := range flag.Args()

    A range loop

    for is Go's only loop. range gives the index and the value; _, the blank identifier, discards the index.

  10. 10os.Exit(1)

    The exit status

    Ends the program with status 1, failure. Returning from main normally means 0, success.

  11. 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:

CommandWhat it does
go run file.goCompiles 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 buildMakes an executable in the current folder: name on Linux and macOS, name.exe on Windows
go installBuilds and puts the executable in Go's bin folder, usually ~/go/bin
go testCompiles and runs the package's tests, from its _test.go files
go vetReports likely mistakes that compile fine, such as Printf formats that don't match their arguments
gofmt -w file.goRewrites 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.

Terminal and go.mod
# 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 go line 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; with GOTOOLCHAIN=local it stops with an error.
  • One package per folder. All files in a folder must use the same package name; the only exception is a test file in package name_test, which tests the package from outside.
  • The import path is the folder. import "example.com/greet/internal/names" refers to the internal/names folder of the module example.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 nameWhat the go command does with it
name_test.goA test file: compiled only by go test, never into the program
name_linux.go, name_windows.goCompiled only when building for that operating system (any GOOS value)
name_arm64.go, name_windows_amd64.goCompiled only for that processor, or that system and processor (GOARCH, GOOS_GOARCH)
_name.go, .name.goIgnored, along with folders named testdata
name.goCompiled 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 for go generate to 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:

FunctionRun byPurpose
func TestXxx(t *testing.T)go testA test: calls t.Error or t.Fatal to fail
func ExampleXxx()go testRuns 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=FuzzXxxFeeds 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.

VersionReleasedNotable for
Go 1.18March 2022Generics (type parameters) and fuzz testing
Go 1.21August 2023min and max, the slices, maps and cmp packages, and the go line in go.mod becoming a requirement
Go 1.22February 2024Each loop iteration gets its own variable, ending a classic goroutine bug; for i := range 10
Go 1.23August 2024Range over functions, the basis of iterators
Go 1.24February 2025Generic type aliases, and testing.B.Loop for benchmarks
Go 1.27August 2026Methods 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 toA native executableA native executableA native executableBytecode for the Java virtual machineUsually interpreted
MemoryGarbage collectedManaged by handOwnership rules, checked at compile timeGarbage collectedGarbage collected
Official formattergofmtNonerustfmtNoneNone
Project filego.modMakefile, CMakeLists.txtCargo.tomlpom.xml, build.gradlepyproject.toml
Unused importCompile errorAllowedWarningAllowedAllowed

See the C, Rust, Java and Python explainers for those formats.

Troubleshooting

Go errors people hit most, and what they mean

MessageUsual causeFix
"os" imported and not usedAn import left over after editingRemove it, or let goimports or your editor manage imports
declared and not used: xA variable that's assigned but never readUse it, remove it, or assign it to _ while debugging
syntax error: unexpected semicolon or newline before {An opening brace on its own linePut { 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 directorygo run . or go build outside a moduleRun 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 folderMove one into its own folder
no required module provides package …A new import that go.mod doesn't list yetRun 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:buildBuild 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 offUpdate 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.

sample-program.go · 3.0 KBDownloadOpen
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.

  1. 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.

  2. Comments 3 to 5: a constant, a struct and a method

    A package-level constant, an item struct with unexported fields, and a value method attached to it.

  3. Comment 6: an interface, satisfied implicitly

    A String method makes item a fmt.Stringer without declaring it, so fmt.Println prints items with it.

  4. Comment 7: errors as values

    find returns an item and an error, wrapping a sentinel error with %w so callers can test it with errors.Is.

  5. Comments 8 and 9: slices and sorting

    A slice of fictional shop items, sorted largest value first with slices.SortFunc and cmp.Compare.

  6. Comments 10 and 11: goroutines and defer

    One goroutine per item, a sync.WaitGroup to wait for them and a mutex around the shared total; defer wg.Done() runs when each goroutine finishes.

  7. 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 and func 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, an Example function with checked output and a benchmark. Run with go 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 -l on the samples should list nothing, and go vet and go run should pass on each file by name. Each sample is its own program with its own main, so give each one its own folder before building them as packages.
  • Build constraints: build sample-unix.go in a module with GOOS=windows, GOOS=linux and GOOS=darwin to check your pipeline's cross-compilation.
  • Encoding: sample-wordcount.go should print café as 5 bytes and 4 runes; anything else means the file's encoding changed on the way.
  • Upload limits: sample-100kb.go is 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

Last reviewed 27 October 2026.