How to Use go doc and godoc for Documentation

Cli
Use the go doc command to instantly view documentation for Go packages, symbols, and files directly in your terminal.

The terminal is your documentation browser

You are debugging a timeout in an HTTP client. The standard library function http.Get is hanging, and you need to know exactly what it does with redirects and TLS handshakes. You do not open a browser. You do not search a third-party wiki. You open your terminal and type go doc net/http.Get. The answer appears in plain text, formatted exactly like the source code comments. This is the default documentation workflow in Go.

Documentation lives in the source

Go documentation is not a separate artifact. It is not a generated PDF or a precompiled HTML site. The documentation lives inside the .go files alongside the code. The go doc command is a lightweight parser that reads those comments, applies visibility rules, and prints them to your screen. When you read documentation on the official package site, you are literally looking at go doc output that has been wrapped in HTML. The system treats comments as first-class citizens. If you write the comment, you write the documentation.

Think of it like a library where every book has a summary sticker on the spine. You do not need to check out the book to read the summary. You just glance at the spine. The go doc tool is the librarian who reads the sticker for you. It skips the private notes, highlights the public API, and hands you exactly what you asked for.

The tool reads directly from your module cache. It does not compile your code. It does not run tests. It parses the Abstract Syntax Tree, extracts comments attached to exported identifiers, and formats them. This design keeps the workflow fast and offline-capable. You can document a package on a plane, run go doc, and get the exact same output you would see on a connected machine.

Reading docs from the command line

Here is the simplest way to read documentation for a standard library package or a local file.

# Shows the package overview and all exported symbols
go doc net/http

# Drills down into a single function signature and comment
go doc net/http.Get

# Reads documentation for a local file without building it
go doc ./internal/client.go

# Strips formatting and shows only the raw comment text
go doc -short net/http.ListenAndServe

The command works by matching your input against the module cache. If you pass a full import path, it resolves the package. If you pass a file path, it parses that file directly. The -short flag is useful when you want to pipe the output into a script or grep for a specific keyword. You can also use -all to force the tool to show unexported symbols, though the output becomes dense and harder to scan.

go doc is fast because it reads from the module cache. It does not compile your code. It does not run tests. It just reads text.

How the parser reads your comments

Understanding how go doc reads your code changes how you write it. The tool expects a specific structure. Every exported identifier needs a comment block immediately above it. The first sentence must be a complete sentence that starts with the identifier name. This is not a style preference. It is a parsing requirement. The go doc tool uses that first sentence as the one-line summary in search results and index pages.

Go convention dictates that receiver names are one or two letters matching the type. The documentation parser does not care about the name, but the community expects (s *Store) or (c *Cache). Using (this *Store) or (self *Store) breaks the convention and makes code reviews slower. Stick to the short name.

The parser also looks for example functions. If you name a function ExampleStore_Get, go doc treats it as a runnable example and attaches it to the Get method documentation. The example function must return no values and accept no arguments. It can print to standard output, and the tool captures that output to verify it matches the expected result. This turns your documentation into executable tests.

Writing comments that survive the toolchain

Here is a realistic package structure that plays nicely with the documentation tool.

// Package cache provides a simple in-memory key-value store.
// It uses a sync.RWMutex to handle concurrent reads safely.
package cache

import "sync"

// Store holds the cached entries and protects them with a mutex.
// The zero value is ready to use and starts with an empty map.
type Store struct {
    mu    sync.RWMutex
    items map[string]string
}

// NewStore creates a Store with preallocated map capacity.
// Pass a capacity hint if you know the approximate number of entries.
func NewStore(capacity int) *Store {
    // Preallocate to avoid resizing during the first batch of inserts
    return &Store{
        items: make(map[string]string, capacity),
    }
}

// Get retrieves a value by key.
// It returns the value and true if the key exists.
// It returns an empty string and false if the key is missing.
func (s *Store) Get(key string) (string, bool) {
    // Lock for reading to allow concurrent access without blocking
    s.mu.RLock()
    defer s.mu.RUnlock()
    val, ok := s.items[key]
    return val, ok
}

Run go doc ./cache and the tool extracts the package comment, the Store struct comment, and the Get method comment. It ignores the private mu field and the internal map implementation. The output is clean, focused, and ready for terminal reading.

Go convention also expects you to document parameters and return values when they are not obvious. The Get method above explains the boolean return value explicitly. This saves readers from guessing whether false means "not found" or "error occurred". The community accepts verbose error handling by design, so document the error path clearly. If a function returns an error, explain what conditions trigger it.

When the tool fights back

The documentation tool will silently drop comments that do not follow the rules. If you place a blank line between the comment and the identifier, go doc treats the comment as regular code documentation and ignores it for the public API. You will see your function in the source, but it will vanish from go doc output. The fix is simple: remove the blank line.

If you forget to capitalize an identifier, it becomes private to the package. go doc respects Go visibility rules and hides unexported symbols by default. You can force it to show everything with go doc -all, but the output becomes noisy and hard to scan. Capitalization is the visibility switch. Public names start with a capital letter. Private names start lowercase. There are no public or private keywords.

The tool also complains when your first sentence breaks the naming rule. If you write // Retrieves a value by key. instead of // Get retrieves a value by key., the go doc command prints a warning like comment on exported function Get should be of the form "Get ...". The warning does not stop compilation, but it breaks the documentation index. Fix the first sentence and the warning disappears.

Another common trap is relying on godoc.org. That site was shut down years ago. The official replacement is pkg.go.dev. Both sites use the same underlying parser, but pkg.go.dev pulls directly from the Go module proxy and supports versioned documentation. Point your browser there for the web experience. Use go doc for the terminal experience.

Documentation is code. Treat it with the same rigor.

Picking your documentation tool

Use go doc when you are already in the terminal and need a quick answer without context switching. Use pkg.go.dev when you need to browse versioned releases, compare changes across tags, or read documentation on a mobile device. Use your IDE tooltips when you want inline documentation while writing code, but verify the output against go doc if the tooltip looks truncated. Use the raw source code when the documentation is outdated or missing, because the comments are always one step behind the implementation.

Where to go next