Skip to main content

Get Started in Three Steps

Go from zero to running a real web server with routing in under 5 minutes.
1

Install Go

Download and install Go from the official website:
brew install go
Verify your installation:
go version
# Should output: go version go1.25.5 (or similar)
2

Clone the Repository

Clone the Go Journey repository to get all the example projects:
git clone https://github.com/priyanshu-samal/Go.git
cd Go/Intro
The Intro directory contains a complete project demonstrating proper Go project structure with cmd/ and internal/ directories.
3

Run Your First Server

Start the web server:
go run cmd/intro/main.go
You should see:
Server started. Listening on http://localhost:8080
Open your browser to http://localhost:8080 and you’ll see:
Welcome to the Intro Application!
Try the API endpoint at http://localhost:8080/api/data to see sample data.
Success! You’ve just run your first Go web server with routing.

Understanding the Code

Let’s break down what you just ran. The Intro project demonstrates Go’s standard project layout.

Project Structure

Intro/
├── cmd/
│   └── intro/
│       └── main.go      # Application entry point
├── internal/
│   └── routes/
│       └── routes.go    # HTTP routing logic
└── go.mod               # Module definition
Why this structure?
  • cmd/ contains application entry points (main packages)
  • internal/ contains private application code that can’t be imported by external projects
  • This is the Go community’s preferred layout for production applications

The Entry Point

The cmd/intro/main.go file is where your application starts:
cmd/intro/main.go
package main

import (
    "fmt"
    "net/http"
    "github.com/priyanshu-samal/Intro/internal/routes"
)

func main() {
    router := routes.NewRouter()  // Create router from internal package

    port := ":8080"
    addr := fmt.Sprintf("Listening on http://localhost%s", port)
    fmt.Printf(`Server started. %s`, addr)
    
    if err := http.ListenAndServe(port, router); err != nil {
        fmt.Printf("Failed to start server: %v", err)
    }
}
  • package main: Tells Go this is an executable program (not a library)
  • routes.NewRouter(): Gets a router from our internal package
  • http.ListenAndServe(): Starts the HTTP server on port 8080
  • Error handling: Go returns errors as values, not exceptions

The Router Logic

The internal/routes/routes.go file handles HTTP routing:
internal/routes/routes.go
package routes

import (
    "net/http"
    "fmt"
)

func NewRouter() *http.ServeMux {
    mux := http.NewServeMux()
    mux.HandleFunc("/", indexHandler)
    mux.HandleFunc("/api/data", apiDataHandler)
    return mux
}

func indexHandler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintln(w, "Welcome to the Intro Application!")
}

func apiDataHandler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Sample Data: %v", "Hello from API")
}
  • http.ServeMux: Go’s built-in HTTP request router
  • HandleFunc: Registers a handler function for a specific URL pattern
  • Handler signature: All handlers take (w http.ResponseWriter, r *http.Request)
  • Response writing: Use fmt.Fprintln(w, ...) to send data back to the client

What You Just Learned

The go.mod file defines your module path and Go version:
module github.com/priyanshu-samal/intro

go 1.25.5
This enables dependency management and allows other projects to import your code.
  • Every folder in Go is a package
  • All files in a folder must declare the same package name
  • package main creates an executable
  • Other package names create libraries
When you import code, you use the full module path:
import "github.com/priyanshu-samal/Intro/internal/routes"
Go’s toolchain enforces that internal/ packages can’t be imported by external modules.
Go’s standard library includes a production-ready HTTP server:
  • No external dependencies required
  • Fast and concurrent by default (each request in its own goroutine)
  • Simple handler interface: just a function taking ResponseWriter and Request

Try These Experiments

Now that you have a working server, try making some changes:

Add a New Route

Open internal/routes/routes.go and add:
mux.HandleFunc("/hello", helloHandler)
Then create the handler:
func helloHandler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintln(w, "Hello, Go Journey!")
}
Restart the server and visit http://localhost:8080/hello

Return JSON

Add JSON support to your API:
import "encoding/json"

func apiDataHandler(w http.ResponseWriter, r *http.Request) {
    data := map[string]string{"message": "Hello", "status": "ok"}
    w.Header().Set("Content-Type", "application/json")
    json.NewEncoder(w).Encode(data)
}

Change the Port

In cmd/intro/main.go, change:
port := ":3000"  // Instead of :8080
Now your server runs on port 3000.

Build a Binary

Compile your code into an executable:
go build -o myserver cmd/intro/main.go
./myserver
You now have a standalone binary with no dependencies!

Next Steps

Now that you have Go running, it’s time to dive deeper:

Project Structure

Understand why we organize code with cmd/ and internal/ directories

The Go Runtime

Learn how Go manages memory, garbage collection, and escape analysis

Methods & Receivers

Master the difference between value and pointer receivers

Build a REST API

Create a full CRUD API with JSON, routing, and database integration
Pro Tip: Each chapter in the Go Journey repository is a complete, runnable project. Navigate to any chapter directory and run go run to see it in action.

Common Issues

If you see bind: address already in use, another process is using port 8080.Solution: Either kill that process or change the port in main.go:
port := ":3000"  // Use a different port
If go version doesn’t work, Go isn’t in your PATH.Solution: Add Go to your PATH (usually done automatically by the installer):
export PATH=$PATH:/usr/local/go/bin
Add this to your ~/.bashrc or ~/.zshrc to make it permanent.
If you see module import errors, make sure you’re in the correct directory:
cd Go/Intro  # Must be in the Intro directory
go run cmd/intro/main.go
Go doesn’t have built-in hot reload. You must restart after changes.Solution: Use a tool like air for automatic reloading:
go install github.com/cosmtrek/air@latest
air  # Watches files and rebuilds automatically
Need Help? Join the Go community on r/golang, Gophers Slack, or check out the official Go documentation.

Build docs developers (and LLMs) love