In the previous tutorial, you learned what Go is and why it is a great language to learn. Now it is time to install Go and write your first program.

This tutorial covers installation on all three major platforms. You will also set up VS Code and learn the basic Go commands.

Try Go Online First

Before installing anything, you can try Go in your browser. The Go Playground lets you write and run Go code online:

Go Playground — play.go.dev

This is great for quick experiments. But for real development, you need Go installed on your computer.

Installing Go

macOS

The easiest way to install Go on macOS is with Homebrew:

# Install Go with Homebrew
brew install go

# Verify the installation
go version

You should see something like:

go version go1.24.1 darwin/arm64

If you don’t use Homebrew, download the installer from go.dev/dl. Download the .pkg file and run it.

Linux

On Ubuntu or Debian:

# Download Go (check go.dev/dl for the latest version)
wget https://go.dev/dl/go1.24.1.linux-amd64.tar.gz

# Remove any old installation and extract
sudo rm -rf /usr/local/go
sudo tar -C /usr/local -xzf go1.24.1.linux-amd64.tar.gz

# Add Go to your PATH (add this to ~/.bashrc or ~/.zshrc)
export PATH=$PATH:/usr/local/go/bin

# Verify
go version

Windows

  1. Download the .msi installer from go.dev/dl
  2. Run the installer
  3. Open a new Command Prompt or PowerShell
  4. Run go version to verify

The installer adds Go to your PATH automatically.

Setting Up VS Code

VS Code is the most popular editor for Go development. Here is how to set it up:

  1. Install VS Code if you don’t have it
  2. Open VS Code
  3. Go to Extensions (Ctrl+Shift+X or Cmd+Shift+X)
  4. Search for “Go” by the Go team at Google
  5. Click Install

The Go extension gives you:

  • Code completion (IntelliSense)
  • Automatic imports
  • Error checking as you type
  • Formatting on save
  • Debugging support
  • Test runner

After installing the extension, open the command palette (Ctrl+Shift+P or Cmd+Shift+P) and run Go: Install/Update Tools. Click “Select All” and then “OK”. This installs the Go tools that the extension needs.

Your First Go Module

Every Go project starts with a module. A module is a collection of Go packages. Think of it as a project folder with a name.

Create a new folder and initialize a Go module:

# Create a project folder
mkdir hello-go
cd hello-go

# Initialize a Go module
go mod init hello-go

This creates a go.mod file:

module hello-go

go 1.24.1

The go.mod file tracks your module name and Go version. It will also track your dependencies later.

Hello World

Create a file called main.go:

package main

import "fmt"

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

Run it:

go run main.go

Output:

Hello, World!

Let me explain what go run does. It compiles your code and runs it in one step. It does not create a permanent binary file. For that, you use go build:

# Build a binary
go build -o hello main.go

# Run the binary
./hello

Now you have a compiled binary called hello. You can copy this file to any computer with the same operating system and run it. No Go installation needed on that machine.

Understanding the Code

Let me break down the Hello World program:

package main

Every Go file starts with a package declaration. The main package is special. It tells Go “this is an executable program, not a library.”

import "fmt"

The import statement loads packages you need. The fmt package provides formatting and printing functions. It is part of Go’s standard library.

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

The main function is where your program starts. Every executable Go program must have a main function in the main package.

fmt.Println prints a line of text. The Println starts with a capital letter. In Go, this means the function is exported (public). Functions that start with a lowercase letter are private to their package.

Printing and Formatting

The fmt package has several printing functions. Let me show you the most useful ones:

package main

import "fmt"

func main() {
    name := "Alex"
    age := 25
    height := 1.75

    // Println — print with a newline at the end
    fmt.Println("Hello,", name)

    // Printf — formatted printing (like C's printf)
    fmt.Printf("Name: %s, Age: %d, Height: %.2f\n", name, age, height)

    // Sprintf — format a string without printing it
    message := fmt.Sprintf("%s is %d years old", name, age)
    fmt.Println(message)

    // Print — print without a newline
    fmt.Print("First ")
    fmt.Print("Second ")
    fmt.Println("Third")
}

Output:

Hello, Alex
Name: Alex, Age: 25, Height: 1.75
Alex is 25 years old
First Second Third

The most common format verbs are:

VerbDescriptionExample
%sString"Alex"
%dInteger25
%fFloat1.750000
%.2fFloat with 2 decimals1.75
%vAny value (default format)Works with any type
%TType of a valuestring, int
%tBooleantrue
\nNewline

The %v verb is very useful. It works with any type and prints a reasonable default:

package main

import "fmt"

func main() {
    fmt.Printf("String: %v\n", "hello")
    fmt.Printf("Number: %v\n", 42)
    fmt.Printf("Boolean: %v\n", true)
    fmt.Printf("Float: %v\n", 3.14)
}

Output:

String: hello
Number: 42
Boolean: true
Float: 3.14

Reading User Input

You can read input from the user with fmt.Scan or fmt.Scanf:

package main

import "fmt"

func main() {
    var name string
    var age int

    fmt.Print("What is your name? ")
    fmt.Scan(&name)

    fmt.Print("How old are you? ")
    fmt.Scan(&age)

    fmt.Printf("Hello, %s! You are %d years old.\n", name, age)
}

The & before name and age is the address operator. It gives Scan the memory location where it should store the input. Don’t worry about this detail now. We will cover pointers later in this series.

For reading a full line (with spaces), use bufio.Scanner:

package main

import (
    "bufio"
    "fmt"
    "os"
)

func main() {
    scanner := bufio.NewScanner(os.Stdin)

    fmt.Print("Enter a sentence: ")
    scanner.Scan()
    text := scanner.Text()

    fmt.Printf("You typed: %s\n", text)
    fmt.Printf("Length: %d characters\n", len(text))
}

A Complete Example

Let me put everything together in a small program:

package main

import (
    "bufio"
    "fmt"
    "os"
    "strings"
)

func main() {
    scanner := bufio.NewScanner(os.Stdin)

    fmt.Println("=== GO-2: Your First Go Program ===")
    fmt.Println()

    // Get user input
    fmt.Print("What is your name? ")
    scanner.Scan()
    name := scanner.Text()

    // Greet the user
    greeting := fmt.Sprintf("Hello, %s!", strings.Title(name))
    fmt.Println(greeting)

    // Print some info
    fmt.Printf("Your name has %d characters\n", len(name))
    fmt.Printf("Uppercase: %s\n", strings.ToUpper(name))
    fmt.Printf("Lowercase: %s\n", strings.ToLower(name))

    // Multiple values
    first, last := splitName(name)
    fmt.Printf("First: %s, Last: %s\n", first, last)
}

// splitName splits a full name into first and last name
func splitName(fullName string) (string, string) {
    parts := strings.Fields(fullName)
    if len(parts) < 2 {
        return fullName, ""
    }
    return parts[0], parts[len(parts)-1]
}

Run it:

go run main.go

This example uses:

  • fmt for printing and formatting
  • bufio for reading user input
  • strings for string manipulation
  • A custom function with multiple return values
  • The := short variable declaration

Essential Go Commands

Here are the Go commands you will use every day:

# Run a Go file (compile + execute in one step)
go run main.go

# Build a binary
go build -o myapp main.go

# Initialize a new module
go mod init myproject

# Download dependencies
go mod tidy

# Format your code (Go has one official style)
go fmt ./...

# Run tests
go test ./...

# Check for common mistakes
go vet ./...

The go fmt command is important. Go has one official code style. Every Go developer uses the same formatting. No arguments about tabs vs spaces. No config files. Just run go fmt and your code looks like everyone else’s.

Project Structure

Your project now looks like this:

hello-go/
  go.mod
  main.go

This is a valid Go project. For small programs, this is all you need. As your projects grow, you will add more files and packages. We will cover project structure later in the series.

Common Mistakes

1. Unused imports are errors in Go.

import "fmt"
import "os" // Error: "os" imported and not used

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

Go does not allow unused imports. Remove them, or use the blank identifier _:

import _ "os" // This tells Go: "I imported this on purpose"

In practice, VS Code removes unused imports automatically when you save.

2. Unused variables are errors too.

func main() {
    name := "Alex" // Error: name declared and not used
}

Go forces you to use every variable you declare. This keeps your code clean.

3. Exported names start with a capital letter.

fmt.Println("Hello") // Works — Println is exported (capital P)
fmt.println("Hello") // Error — println is not exported (lowercase p)

This is how Go does public vs private. Capital letter = public. Lowercase = private.

Source Code

You can find the complete source code for this tutorial on GitHub:

GO-2 Source Code on GitHub

What’s Next?

In the next tutorial, Go Tutorial #3: Variables, Types, and Constants, you will learn:

  • How to declare variables with var and :=
  • All the basic types in Go
  • Zero values — why Go has no null for basic types
  • Constants and iota
  • Type conversions

This is part 2 of the Go Tutorial series. Follow along to learn Go from scratch.