Go Formatter (gofmt)

Paste Go code and get the exact layout gofmt produces, from the real Go formatter compiled to WebAssembly. Syntax errors come back in the same line:column form the Go toolchain prints.

Input

Settings

History

Load from URL

One canonical layout, no settings

Go is unusual in that the language ships its own formatter and almost every Go project uses it unchanged. There is no style guide to argue about: gofmt decides, and code review tools, editors and CI all expect its output. That is why this page has no format-specific options. What you get here is byte-for-byte what gofmt writes, because the formatter is the Go standard library’s printer compiled to WebAssembly rather than a reimplementation.

The toolbar’s Indent choice is ignored on purpose. gofmt always indents with tabs and uses spaces only for alignment, so switching to 2 or 4 spaces would produce code that a gofmt -l check in CI would flag as unformatted.

What gofmt changes

  • Spacing by precedence. Operators get spaces according to how tightly they bind, so i*2+1 becomes i*2 + 1. That is intentional, not a bug.
  • Alignment. Consecutive struct fields, their tags, const and var blocks and trailing comments are lined up in columns.
  • Imports. Inside a parenthesised import (...) block, each run of lines is sorted alphabetically. Blank lines separate runs, so the common split between standard library and third-party packages survives.
  • Semicolons and commas. Statements separated by semicolons are put on their own lines, and a trailing comma before a closing brace on the same line is dropped. A brace on its own line is not something gofmt can fix: Go’s automatic semicolon insertion makes that a syntax error.

What it does not do matters just as much. There is no line length limit, so a long call stays long. A function body you wrote on one line, like func main() { run() }, may stay on one line. Unused imports are not removed and missing ones are not added; that is goimports, a separate tool.

Snippets without a package clause

You do not need a complete file. gofmt accepts a list of declarations, or even a few statements such as the body of a function, and formats them in place. That makes it practical for tidying code copied from a Slack thread, a GitHub comment or an answer on a forum before you drop it into an editor. Only the syntax is checked: undefined names, type mismatches and unused variables are compile errors, which gofmt never sees.

Using the page

Paste a file, or open one with the file button. A package line followed by a func, or a function using :=, is enough for automatic detection. Press Ctrl/Cmd+Enter to run gofmt, then Ctrl/Cmd+Shift+C to copy the output. If the input does not parse, the message starts with line:column, and the error is highlighted at that spot in the editor. Formatting happens on your own machine, so internal service names and credentials in the code stay private.

The output contains real tab characters. Editors display them at your configured width, but some web forms, chat tools and Markdown renderers show a tab as 8 columns, so deeply nested code can look wider after pasting than it does in your editor. The code itself is unchanged.

Examples

HTTP handler with unsorted imports

The import list is split one per line and sorted, struct tags line up in a column, and each statement gets its own line.

Input
package main
import ("net/http";"fmt";"encoding/json")
type Order struct{ID string `json:"id"`;Status string `json:"status"`;Total float64 `json:"total"`}
func getOrder(w http.ResponseWriter,r *http.Request){
o:=Order{ID:r.URL.Query().Get("id"),Status:"paid",Total:208.9}
w.Header().Set("Content-Type","application/json")
if err:=json.NewEncoder(w).Encode(o);err!=nil{http.Error(w,err.Error(),http.StatusInternalServerError)}}
func main(){http.HandleFunc("/order",getOrder);fmt.Println("listening on :8080");http.ListenAndServe(":8080",nil)}
Output
package main

import (
	"encoding/json"
	"fmt"
	"net/http"
)

type Order struct {
	ID     string  `json:"id"`
	Status string  `json:"status"`
	Total  float64 `json:"total"`
}

func getOrder(w http.ResponseWriter, r *http.Request) {
	o := Order{ID: r.URL.Query().Get("id"), Status: "paid", Total: 208.9}
	w.Header().Set("Content-Type", "application/json")
	if err := json.NewEncoder(w).Encode(o); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
}
func main() {
	http.HandleFunc("/order", getOrder)
	fmt.Println("listening on :8080")
	http.ListenAndServe(":8080", nil)
}
Open this example in the tool

Grouped imports and a generic helper

Each import group is sorted on its own and the blank line between them is kept, while the generic signature gets standard spacing.

Input
package collections
import (
"strings"
"fmt"

"github.com/acme/billing/zeta"
"github.com/acme/billing/alpha"
)
func Map[T,U any](xs []T,f func(T)U)[]U{out:=make([]U,0,len(xs));for _,x:=range xs{out=append(out,f(x))};return out}
Output
package collections

import (
	"fmt"
	"strings"

	"github.com/acme/billing/alpha"
	"github.com/acme/billing/zeta"
)

func Map[T, U any](xs []T, f func(T) U) []U {
	out := make([]U, 0, len(xs))
	for _, x := range xs {
		out = append(out, f(x))
	}
	return out
}
Open this example in the tool

Loop body pasted without a package

A bare statement list formats fine, and in the mixed expression the multiplication stays tight while the addition gets spaces.

Input
for i:=0;i<len(orders);i++ {
if orders[i].Total==0 {continue}
total+=orders[i].Qty*orders[i].Price+shipping
}
Output
for i := 0; i < len(orders); i++ {
	if orders[i].Total == 0 {
		continue
	}
	total += orders[i].Qty*orders[i].Price + shipping
}
Open this example in the tool

Common errors and how to fix them

ErrorCauseFix
2:14: expected '}', found 'EOF'A function, struct or block is missing its closing brace, so the file ended while gofmt was still inside it.Add the missing } at the end of the block. The line number points at the end of the input, so count braces from the top.
2:1: expected declaration, found xA short variable declaration such as x := 1 sits at package level, outside any function. := is only allowed inside function bodies.Move the statement into a function, or use var x = 1 at package level.
2:11: missing import pathAn import was written without quotes, as in import fmt.Quote the path: import “fmt”.
3:17: missing ',' before newline in argument list (and 1 more errors)A call that spans lines ends a line without a trailing comma or closing parenthesis. Go inserts a semicolon at that newline, which breaks the call.Close the parenthesis on that line, or add a trailing comma after the last argument when it continues onto the next line.
3:1: unexpected semicolon or newline before {An opening brace was put on its own line, C# or Allman style. Go inserts a semicolon at the end of the previous line, so the brace is left dangling.Move the { up to the end of the func, if or for line it belongs to.
3:7: string literal not terminatedA double-quoted string has no closing quote, or a multi-line string was written with double quotes.Close the quote, or use a backtick raw string for text that spans several lines.

Frequently asked questions

Is this the real gofmt?

Yes. It is the formatter from the Go standard library compiled to WebAssembly, so the output matches gofmt and go fmt on your machine.

Why are there no options for tabs or line length?

gofmt has none. Tabs for indentation and no maximum line length are part of the canonical Go style, and changing them would make the code fail gofmt checks in CI.

Does it add or remove imports like goimports?

No. It sorts the imports you have but never adds a missing package or deletes an unused one. Run goimports or gopls in your editor for that.

Will it tell me about compile errors?

Only syntax errors. gofmt parses the code but does not type-check it, so undefined variables, wrong types and unused imports pass without a message.

Can I format just a function or a few lines?

Yes. Declarations or statements without a package clause are accepted and formatted as a fragment.

Related tools