Reformat Go Packages Safely with go fmt
You will finish with a repeatable way to format a Go package, preview what go fmt will run, and check which files changed. Allow about ten minutes. You need a Go installation and a package directory you can edit. The examples modify source files, so use a clean working tree or make a backup if you need to review the change separately.
The route
Jump straight to the step you need, or tick off Done means at the end.
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 selected by this shell. 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. It prints the names of files that are modified. If command -v go points somewhere unexpected, stop and resolve your PATH before formatting a project.
Checkpoint
You know which Go toolchain will 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 ./... merely because it is familiar: it can format more packages than you meant to touch. Review the package list first when the repository is large:
$ 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. The important parts are gofmt -l -w and the files selected by the package. -n previews commands; it does not format the source.
For a more verbose dry run, -x prints commands as they are executed. It is not a dry-run flag:
$ go fmt -x .
/path/to/go/bin/gofmt -l -w main.go
main.go
In this example main.go is printed because it was changed. If the package is already formatted, no filename is printed.
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 create a large diff if the toolchain or package selection differs from the one used by the project.
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. That 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 directs you to 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 -w only after checking the path; it changes the file in place. For a complete list of flags on the installed tool, run gofmt -h.
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 expected by the repository 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. 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
- You confirmed the active Go executable and version.
- You selected an intentional package pattern and previewed it with
go fmt -n. - You know that
go fmtrunsgofmt -l -wand rewrites files in place. - You reviewed the resulting diff and have a safe undo path.
- You can use
gofmt -d,-lor-wwhen package-level formatting is too broad. - You ran the project's tests or other checks after formatting.