# gofmt & goimports - Small Tools, Big Difference

If you’re in Go more than hour, you’ve probably noticed the mention about the `gofmt`. It’s one of those tools that cleans up your mess - without a redundant style discussion.

Next to it there’s a little bit more clever sibling - `goimports`. At first glance it’s doing the same, but in practice it’s saving you a lot of time and frustration.

# gofmt - The Classic That Keeps Things Tidy

`gofmt` it’s an official Go tool for the code formatting according to the language’s standards.

There’s no configuration, there’s no `Google` or `Uber` style, there’s just a Go *style.*

```bash
# One file formatting
gofmt -w main.go

# Directory formatting (recursively)
gofmt -w .
```

The `-w` flag means that the file will be overwritten with the `gofmt`'s version if its styling is different.

To see the list of files that do not follow fhe `gofmt`'s formatting you use the `-l` flag:

```bash
gofmt -l .
```

# goimports - Formatting + Imports Management

`goimports` is a tool from the `golang.org/x/tools/cmd/goimports` package that can do everything what `gofmt` does and as a bonus **automatically manages package imports**.

> Command goimports updates your Go import lines, adding missing ones and removing unreferenced ones.
> 
> Source: [https://pkg.go.dev/golang.org/x/tools/cmd/goimports](https://pkg.go.dev/golang.org/x/tools/cmd/goimports)

Installation:

```bash
go install golang.org/x/tools/cmd/goimports@latest
```

Usage:

```bash
# Same as in the gofmt -> overwrite files with formatted version
goimports -w .

# List files whose formatting differs from goimport's
goimports -l .
```

What’s the difference from `gofmt`?

* Will add the missing imports, f.e. if you used the `fmt.Println` but forgot to import the `fmt` package
    
* Will remove the unused imports automatically
    

Example:

Before:

```go
package main

import (
    "fmt"
    "os"
)

func main() {
    fmt.Println("Keep Is Simple, Stupid!")
}
```

After:

```go
package main

import "fmt"

func main() {
    fmt.Println("Keep Is Simple, Stupid!")
}
```

# How to Use Them on a Daily Basis

The best tool is a one that you don’t have to remember about.

You can set up them in the IDE or CI, so they’re executed automatically.

My JetBrains GoLand’s code style is as follows:

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1759575884159/8e925a87-20e6-4ae0-80a0-8407b2320776.png align="center")

For the VS Code it should look like this:

The `settings.json` file:

```json
{
  "go.formatTool": "goimports",
  "editor.formatOnSave": true
}
```

For the GitHub’s CI / GitHub Actions:

```yaml
- name: Install goimports
  run: go install golang.org/x/tools/cmd/goimports@latest
- name: Verify formatting & imports
  run: test -z "$(goimports -l .)"
```

If you have to choose one, use `goimports`. It's like `gofmt` on steroids, and it also saves you a few *seconds* per file.

Finally, *Keep It Simple, Stupid!*

# Sources

* gofmt: [https://pkg.go.dev/cmd/gofmt](https://pkg.go.dev/cmd/gofmt)
    
* goimports: [https://pkg.go.dev/golang.org/x/tools/cmd/goimports](https://pkg.go.dev/golang.org/x/tools/cmd/goimports)
    
* Go tools: [https://cs.opensource.google/go/x/tools](https://cs.opensource.google/go/x/tools)
    
* go fmt your code: [https://go.dev/blog/gofmt](https://go.dev/blog/gofmt)
    
* The Go Programming Language: [https://cs.opensource.google/go/go](https://cs.opensource.google/go/go)
