Go (often called Golang) is a general-purpose, strongly typed, garbage-collected programming language designed with systems programming in mind. It has explicit support for concurrent programming and a built-in toolchain for compiling, testing, formatting, running, and managing modules. You can begin with only a text editor and a terminal on Linux, macOS, or Windows.
This tutorial takes you from installation to a working module, then shows how packages, dependencies, concurrency, and the official learning resources fit together.
What Go is—and what it is not
The Go language specification describes Go as “a general-purpose language designed with systems programming in mind. It is strongly typed and garbage-collected and has explicit support for concurrent programming.” In practical terms, Go gives you compile-time type checking, automatic memory reclamation, and language and library features for running many tasks at once.
Go is used for command-line programs, network services, web back ends, infrastructure tooling, and other software that benefits from a small deployment artifact and a straightforward standard library. It is not a scripting language that silently converts values at runtime: most type mistakes are caught while compiling.
#1 Best Overall
The ideas to learn first
- Packages: directories of related Go source files that share a package name.
- Modules: versioned collections of related packages, declared by a
go.modfile. - Commands: executable programs use
package mainand contain amainfunction. - Concurrency: goroutines and channels are built into the language model and standard library.
- Tooling: the
gocommand handles running, building, testing, formatting, and dependency maintenance.
What you need before starting
Some programming experience—especially familiarity with functions, variables, and a command line—will make the first lessons easier, but the official beginner tutorial starts with a small program. You need:
- A supported Linux, macOS, or Windows computer.
- A terminal (such as Terminal, PowerShell, or Command Prompt).
- A text editor. The official tutorial gives Visual Studio Code, GoLand, and Vim as examples; any editor that saves plain text works.
Install Go by following the current instructions at go.dev/doc/install. Installation details and supported releases change, so use that page rather than copying an old operating-system-specific command.
After installation, verify the toolchain:
go version
The command should print the installed Go release. The language specification currently identifies version go1.28 and is dated September 24, 2026; check the release information when you install because versions change.
Create and run your first Go module
The following sequence works from a terminal. Replace hello with another directory name if you prefer.
-
Create a project directory
mkdir hello cd helloOn Windows PowerShell, the same commands work. In Command Prompt, use
mkdir hello, thencd hello. -
Initialize a module
go mod init example.com/helloThis creates
go.mod, which records the module path and the Go language version. The path is an identifier for your module; for a published project, use a path you control or the path used by your repository. -
Write
main.gopackage main import "fmt" func main() { fmt.Println("Hello, World!") }package mainmarks an executable command. Thefmtpackage supplies formatted input and output, andmainis the function that starts the program. -
Run the module
go run .Go compiles the packages needed for the command and runs the resulting program. You should see:
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.Hello, World!
Packages, modules, and dependencies
A package groups source files that provide related declarations. A module groups one or more packages and is described by go.mod. A small project may contain one package; a larger service commonly separates application code into several packages.
Discovering packages
Import a package by its module path, then let the toolchain resolve it. For example, the standard library’s strings package can be used without adding a third-party requirement:
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println(strings.ToUpper("go"))
}
Run it with go run .. Go reports an error at compile time if an import is missing, misspelled, or unused.
Keeping go.mod accurate
When your code imports a module outside the standard library, the requirement belongs in go.mod. Use:
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
go mod tidy
go mod tidy adds requirements needed by imports and removes requirements that are no longer used. Review the changes before committing them, especially when upgrading a project.
A small Go program with functions and errors
Functions make Go code easier to test and reuse. Go commonly returns an error as a second result instead of throwing an exception for expected failures.
package main
import (
"errors"
"fmt"
)
func divide(a, b float64) (float64, error) {
if b == 0 {
return 0, errors.New("cannot divide by zero")
}
return a / b, nil
}
func main() {
result, err := divide(10, 2)
if err != nil {
fmt.Println("error:", err)
return
}
fmt.Println(result)
}
The compiler checks the declared types. The explicit err != nil branch makes the failure path visible to the reader and to tests.
Concurrency basics
Go’s concurrency model starts with goroutines: lightweight functions scheduled by the runtime. Channels provide a typed way for goroutines to communicate.
Quick wins for a faster PC:
Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Repair Windows errors before they cause bigger problemsFix Now →package main
import (
"fmt"
"sync"
)
func main() {
var wg sync.WaitGroup
messages := make(chan string, 2)
wg.Add(2)
go func() {
defer wg.Done()
messages <- "first"
}()
go func() {
defer wg.Done()
messages <- "second"
}()
wg.Wait()
close(messages)
for message := range messages {
fmt.Println(message)
}
}
The output order is not guaranteed because the goroutines run concurrently. A WaitGroup waits for both senders, and the channel is closed only after they finish. In real programs, also plan cancellation, timeouts, ownership of channel closing, and protection for shared mutable state.
Use the official learning path
The official Tour of Go is interactive: it combines short explanations, runnable snippets, and exercises. It covers syntax and data structures, methods and interfaces, generics, and concurrency primitives.
Rank #4
After the first module, choose a focused tutorial based on your project:
| Resource | Best for | Format and access |
|---|---|---|
| A Tour of Go | Learning core syntax, data structures, methods, interfaces, generics, and concurrency | Interactive browser lessons and exercises; free online |
| Official tutorials | Applying Go to modules, JSON, relational databases, REST APIs, generics, fuzzing, and vulnerability checking | Task-focused written walkthroughs; free online |
| The Go Programming Language | A book-length reference and guided introduction | Optional physical book listed by the official learning page; edition and availability vary |
| Training providers listed by the Go learning directory | Structured instruction and support | Examples include Ardan Labs and Gopher Guides; formats and terms are set by each provider |
No paid book or course is required for the official path. Start with the getting-started tutorial, practice in the Tour, and use a focused tutorial when your project introduces a new concern.
Build, format, test, and inspect your program
Format source consistently
gofmt -w .
Go’s formatter rewrites Go files into the standard layout. Many editors can run it automatically when you save.
Compile without running
go build .
This produces an executable for the current platform. Use go install when you want to install a command into your Go binary directory.
Add a test
Create divide_test.go:
package main
import "testing"
func TestDivide(t *testing.T) {
got, err := divide(10, 2)
if err != nil || got != 5 {
t.Fatalf("divide(10, 2) = %v, %v; want 5, nil", got, err)
}
}
Run all package tests with:
go test ./...
Check dependencies for known vulnerabilities
The official tutorial sequence includes dependency vulnerability checking. Follow the current instructions in the Go documentation rather than relying on an old command, because the recommended tooling can change with the Go release.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Common problems and fixes
go: command not found or an unrecognized command
Go is not installed, or its binary directory is not on your PATH. Revisit the installation instructions, restart the terminal after changing environment variables, and run go version again.
Free tools Windows power users keep installed
One-click scans. No signup required.
Best Value
go.mod file not found
You ran a module-aware command outside a module. Change into the directory containing go.mod, or initialize the project with go mod init example.com/your-module.
no required module provides package
The import path is wrong, the dependency is missing, or the module has not been tidied. Confirm the import, run go get with the intended module path when appropriate, then run go mod tidy.
imported and not used
Go rejects unused imports. Remove the import or use it. This is a compile-time check, not a warning.
The program hangs
A goroutine may be waiting forever on a channel, mutex, or network operation. Add bounded timeouts to external calls, ensure channel ownership is clear, and use tests that exercise cancellation and shutdown paths.
The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Performance, portability, and reliability decisions
Measure before optimizing. First make the program correct, add tests, and profile the real workload. Go’s garbage collector means you do not manually free ordinary heap allocations, but allocation rates and object lifetimes still affect latency and memory use.
Build and test on every target operating system you support. Keep dependencies in go.mod, commit the corresponding module checksum file when created, run go test ./... in continuous integration, and review changes produced by go mod tidy. For concurrent code, test race-prone paths and define how shutdown propagates through goroutines.
Or skip the browser setup
If your Go project needs website images for documentation, previews, or automated checks, you can call ScreenshotNeo instead of maintaining a browser automation stack. It accepts a URL and returns PNG, JPEG, WebP, or PDF. Before capture it accepts cookie or consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each cleanup step can be disabled. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing status.
A direct Go request uses the standard HTTP client:
package main
import (
"fmt"
"io"
"net/http"
"os"
)
func main() {
key := os.Getenv("SCREENSHOTNEO_API_KEY")
if key == "" {
panic("set SCREENSHOTNEO_API_KEY")
}
req, err := http.NewRequest("GET", "https://api.screenshotneo.com/v1/shot", nil)
if err != nil {
panic(err)
}
query := req.URL.Query()
query.Set("access_key", key)
query.Set("url", "https://stripe.com")
req.URL.RawQuery = query.Encode()
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
if res.StatusCode < 200 || res.StatusCode >= 300 {
panic(fmt.Sprintf("ScreenshotNeo returned %s", res.Status))
}
out, err := os.Create("shot.webp")
if err != nil {
panic(err)
}
defer out.Close()
if _, err := io.Copy(out, res.Body); err != nil {
panic(err)
}
}
See the ScreenshotNeo API documentation for request options and response details. Equivalent calls are:
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Fix the driver behind crashes, sound loss and screen glitches3Clear out junk files and repair common Windows errorscurl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
ScreenshotNeo also provides an MCP server with take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. The Free plan includes 1,000 shots per month without a card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.
Where to go next
Finish the first official tutorial, repeat its examples without copying them, and then complete Tour exercises on the topics you find least familiar. Move to the modules, JSON, database, REST, generics, fuzzing, or vulnerability-checking tutorial that matches your project. Keep each experiment in a small module, run the formatter and tests frequently, and let compiler errors guide the next change.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




