Home / Alt manpages / go-fmt(1)

  • go-fmt(1)
  • User command
  • linux

Reformat Go Packages Safely with go fmt

go fmt rewrites source files in place, so knowing what it will touch before it touches them is worth the extra thirty seconds. This guide previews the command, formats a package, and checks which files changed. Allow about ten minutes. You need a Go installation and a package directory you can edit, plus a clean working tree or a backup so you can review the change separately.

The local command used for this guide is Go 1.26.1, found at /home/linuxbrew/.linuxbrew/bin/go. The Debian database also reports golang-go 2:1.22~2build1, but that package is not the executable this shell actually selects. Check your own path and version before relying on version-specific output.

1. Check the command you will run

Run these read-only checks from the project directory; they need no elevated privileges:

$ command -v go
/home/linuxbrew/.linuxbrew/bin/go
$ go version
go version go1.26.1 linux/amd64
$ go help fmt

The installed help defines go fmt as running gofmt -l -w on the named packages, printing the names of files it modifies. If command -v go points somewhere unexpected, stop and resolve your PATH before formatting a project.

Checkpoint

You know which Go toolchain is about to rewrite the files.

2. Choose the package pattern

Change to the directory containing the package or module. A dot means the package in the current directory; ./... means packages below the current module, subject to Go's package matching rules. Start with the narrowest pattern that covers your intended files:

$ cd /path/to/your/module
$ go list .
example.test/formatdemo
$ go fmt .

Replace /path/to/your/module and the example import path with real values. Do not type ./... out of habit: it can format more packages than you meant to touch. Review the package list first in a large repository:

$ go list ./...
example.test/formatdemo
example.test/formatdemo/internal/config

go fmt accepts package import paths; it is not the same as passing arbitrary filenames. For one file, use gofmt directly in the next step.

3. Preview the command with -n

Before changing anything, ask Go to print the command it would execute:

$ go fmt -n .
/path/to/go/bin/gofmt -l -w main.go

The tool path and file list depend on your installation. What matters is gofmt -l -w and the files the package selected. -n previews commands; it does not format the source.

For a more verbose dry run, -x prints commands as they run instead. It is not a dry-run flag:

$ go fmt -x .
/path/to/go/bin/gofmt -l -w main.go
main.go

Here main.go is printed because it was actually changed. If the package is already formatted, no filename is printed at all.

4. Apply the formatting and inspect the result

Once the package pattern and preview look right, run the ordinary formatting command:

$ go fmt .
main.go
$ git diff -- main.go

The command writes the gofmt result back to each source file and reports modified filenames. It does not build, test, commit or push your project. Formatting is usually reversible through version control, but it can produce a large diff if the toolchain or package selection differs from the one the project normally uses.

Warning

Do not run this across a dirty tree when unrelated edits are hard to separate. Save or commit the work first, then format. If the diff is wrong, undo only the formatting change with your normal version-control workflow, for example git restore --source=HEAD -- path/to/file.go, which discards all uncommitted edits in that file, so inspect git diff before using it.

5. Use gofmt directly for one file or a diff

The manual page points you at gofmt when you need specific formatting options. Useful read-only and controlled operations include:

$ gofmt -d path/to/file.go
$ gofmt -l path/to/file.go
$ gofmt -w path/to/file.go

-d prints a diff instead of rewriting the file. -l lists files whose formatting differs from gofmt. -w writes the formatted result back; use it only after checking the path, since it changes the file in place. Run gofmt -h for the complete flag list on the installed tool.

Do not confuse formatting with correctness. A successful go fmt run does not replace go test, go vet or a project-specific lint command. Run the checks the repository expects after reviewing the diff.

6. Understand module mode before a wider run

The installed go fmt help also exposes -mod=readonly and -mod=vendor. These select the module download mode used while resolving packages, and they do not change the formatting style:

$ go fmt -mod=readonly ./...
$ go fmt -mod=vendor ./...

Choose the mode that matches the repository's dependency policy. readonly prevents automatic module-file updates; vendor uses the repository's vendor directory. If package resolution fails, read the error and fix the project's dependency state rather than adding random flags or using sudo. No example here needs elevated privileges.

Done means

  • Executable confirmed: you verified the active Go executable and version.
  • Pattern previewed: you selected an intentional package pattern and previewed it with go fmt -n.
  • Behaviour understood: you know go fmt runs gofmt -l -w and rewrites files in place.
  • Diff reviewed: you checked the resulting diff and have a safe way to undo it.
  • Fallback known: you can use gofmt -d, -l or -w when package-level formatting is too broad.
  • Checks run: you ran the project's tests or other checks after formatting.