ScreenshotNeo

BlogGuides

What Is Go? A Tutorial

Learn what Go is, install it, build your first module, understand packages and concurrency, and choose the next official tutorials.

By the ScreenshotNeo team1 October 20267 min read

Go (also 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 package-based module system. The official beginner path takes you from installation to a Hello World command, then introduces packages, modules, dependencies, and larger tutorials.

You need a text editor and a terminal. Previous programming experience, especially with functions, makes the first lessons easier. Go’s official tutorial supports Linux, macOS, and Windows workflows. Start with the official getting-started tutorial.

What Go is used for

Go is designed for programs that need clear structure, compiled executables, networking, and concurrent work. The language specification describes Go as strongly typed and garbage-collected, with explicit concurrency support. Read the Go Language Specification.

  • Strong typing: values have declared or inferred types, and the compiler catches many mistakes before execution.
  • Garbage collection: the runtime reclaims memory that a program no longer uses.
  • Concurrency primitives: goroutines and channels provide built-in ways to coordinate independent work.
  • Packages and modules: packages organize source files; modules group related packages and record dependencies in go.mod.

Install Go and verify it

  1. Open the current official installation instructions.
  2. Choose the installer or archive for Linux, macOS, or Windows and follow that page’s steps.
  3. Open a new terminal and verify the installation:
go version

If the command is not found, reopen the terminal so your PATH changes are loaded. If it still fails, check that the Go installation directory and its bin directory are on PATH according to the platform instructions.

Your first Go program

Create a project directory, initialize a module, add a main package, and run it.

mkdir hello
cd hello
go mod init example.com/hello

Create main.go:

package main

import "fmt"

func main() {
    fmt.Println("Hello, World!")
}

Run the program from the module directory:

go run .

The output is:

Hello, World!

package main identifies an executable command. The main function is where that command starts. fmt is a standard-library package, and Println writes a line to standard output. The go run command compiles and runs the package for you.

Packages, modules, and the go tool

Packages

A package is a group of Go source files in one directory that share a package name. Packages expose identifiers whose names begin with an uppercase letter. For example, fmt.Println is exported and can be called from another package.

Modules

A module is a versioned collection of related packages. Its root contains go.mod, created by go mod init. The file declares the module path and records required modules. Keep it in version control with your source code.

Useful module commands

# Add a dependency after importing it
go get example.com/some/module

# Reconcile required and unused dependencies
go mod tidy

# List packages in the current module
go list ./...

# Build the current command
go build .

# Install a command from a module
go install example.com/tool@latest

Use go mod tidy after changing imports. It adds missing requirements and removes unused ones. Review the resulting go.mod and go.sum changes before committing.

A small multi-package example

Create this layout:

greet/
  go.mod
  main.go
  message/
    message.go

Initialize it:

mkdir -p greet/message
cd greet
go mod init example.com/greet

Write message/message.go:

package message

func Hello(name string) string {
    return "Hello, " + name + "!"
}

Write main.go:

package main

import (
    "fmt"
    "example.com/greet/message"
)

func main() {
    fmt.Println(message.Hello("Go"))
}

Run it with:

go run .

The import path combines the module path from go.mod with the package directory. A package name and an import path are related but are not the same thing.

Core Go concepts to learn next

Functions and errors

package main

import "fmt"

func divide(a, b float64) (float64, error) {
    if b == 0 {
        return 0, fmt.Errorf("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)
}

Go commonly returns a value and an error. Check the error immediately and handle it explicitly.

Structs and methods

type User struct {
    Name string
    ID   int
}

func (u User) Label() string {
    return fmt.Sprintf("%s (#%d)", u.Name, u.ID)
}

Interfaces

An interface describes behavior through methods. A type satisfies an interface implicitly when it implements those methods; there is no separate declaration.

Goroutines and channels

package main

import "fmt"

func main() {
    done := make(chan string)
    go func() {
        done <- "finished"
    }()
    fmt.Println(<-done)
}

A goroutine runs a function concurrently. A channel lets goroutines exchange values. For more syntax, data structures, methods, interfaces, generics, and concurrency exercises, use the interactive Tour of Go.

Testing, formatting, and documentation

Go includes tools for common project tasks:

# Format source files
gofmt -w .

# Run package tests
go test ./...

# Run tests with the race detector
go test -race ./...

# Inspect documentation for a package
go doc fmt

Put tests in files ending with _test.go and functions named TestXxx. Keep tests close to the package they exercise. Run formatting before review so diffs stay consistent.

Calling a website screenshot API from Go

Once you know modules and HTTP requests, you can call a JSON or image API from Go’s standard library. This example saves a screenshot response to a file:

package main

import (
    "fmt"
    "io"
    "net/http"
    "net/url"
    "os"
)

func main() {
    endpoint, err := url.Parse("https://api.screenshotneo.com/v1/shot")
    if err != nil {
        panic(err)
    }
    values := endpoint.Query()
    values.Set("access_key", "YOUR_API_KEY")
    values.Set("url", "https://go.dev")
    endpoint.RawQuery = values.Encode()

    resp, err := http.Get(endpoint.String())
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()

    if resp.StatusCode < 200 || resp.StatusCode >= 300 {
        body, _ := io.ReadAll(resp.Body)
        panic(fmt.Sprintf("HTTP %s: %s", resp.Status, body))
    }

    file, err := os.Create("shot.webp")
    if err != nil {
        panic(err)
    }
    defer file.Close()
    if _, err := io.Copy(file, resp.Body); err != nil {
        panic(err)
    }
}

See the ScreenshotNeo documentation for request options and response headers.

Or skip the browser setup

ScreenshotNeo provides a website screenshot API and MCP server. One GET request returns PNG, JPEG, WebP, or PDF output. Cookie and consent banners, newsletter popups, and chat widgets are removed before capture. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and the response identifies the page verdict and billing status in X-Page-Verdict and X-Billed headers.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://go.dev -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://go.dev"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://go.dev' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

The service also supports full-page and element captures, dark mode, device presets, retina scale, PDF settings, custom CSS and JavaScript, clicks, waits, blocked resources, headers, cookies, user agents, timezone and geolocation, transparent backgrounds, resizing, caching, signed links, asynchronous jobs, webhooks, bulk capture, usage information, and an OpenAPI specification. Its MCP server exposes take_screenshot, get_page_info, and capture_pdf to Claude, Cursor, and other MCP clients.

The Free plan includes 1,000 screenshots each month with no card. Paid plans start at $5 for 3,000 screenshots; every feature is available on every plan. Create a free ScreenshotNeo account.

Common errors and fixes

Error Cause Fix
go: command not found Go is not installed or PATH was not refreshed. Follow the official install page, open a new terminal, and run go version.
go: cannot find main module The command ran outside a directory containing go.mod. cd to the module root or initialize one with go mod init.
no required module provides package An import is missing from module requirements or has an incorrect path. Correct the import, run go get when needed, then run go mod tidy.
imported and not used Go requires every imported package to be used. Remove the import or use it in the file.
undefined: Name The identifier is misspelled, out of scope, or not exported across packages. Check spelling and scope; capitalize an identifier that another package must access.
Screenshot response is an error The API key, URL, or target page failed. Check the key and URL, inspect the HTTP status and X-Page-Verdict/X-Billed headers, and retry transient failures with a timeout.

Performance, reliability, and cost considerations

  • Build a binary with go build when you need repeatable startup instead of compiling on every run.
  • Use bounded worker counts when launching goroutines; unbounded concurrency can exhaust memory or downstream capacity.
  • Pass context.Context values to network calls so cancellation and deadlines propagate.
  • Run go test -race while developing concurrent code to find data races.
  • For screenshot capture, choose the smallest viewport and output format that meets your need, use caching when the page can be reused, and treat timeout or bot-check verdicts separately from successful captures.
  • ScreenshotNeo bills only clean shots; cache hits and failed or blank captures are not billed. Review response headers and usage data when reconciling costs.

A practical learning path

  1. Complete the installation and Hello World steps.
  2. Work through the Tour of Go sections on syntax, data structures, methods, interfaces, generics, and concurrency.
  3. Build a small module with two packages and tests.
  4. Choose an official focused tutorial: modules, JSON, relational databases, REST APIs, generics, fuzzing, or vulnerability checking.
  5. Read the specification when you need exact language behavior.

FAQ

Is Go the same as Golang?

Yes. “Go” is the language’s official name; “Golang” is a common search term and nickname.

Do I need an IDE?

No. A text editor and terminal are enough. The official tutorial lists VS Code, GoLand, and Vim as possible editors.

Should I learn concurrency first?

No. Learn functions, types, packages, and error handling first, then use the Tour’s concurrency exercises.

Where should dependencies be recorded?

In the module’s go.mod file, with checksums commonly recorded in go.sum.

What should I build after Hello World?

Build a small command with multiple packages, tests, and one network request, then continue with the official tutorial that matches your goal.