π¦ Go Dependency Management: Your Package Library Adventure
Imagine youβre building with LEGO blocks, but you can borrow amazing blocks from friends all over the world!
π― What Youβll Learn
Think of your Go project like a recipe book. Sometimes you need ingredients (packages) from the store (internet). Goβs dependency management helps you:
- Get the right ingredients
- Make sure theyβre fresh (correct versions)
- Keep a backup in your kitchen (vendoring)
π Managing Dependencies
The Story
Imagine youβre making a super sandwich. You need:
- Bread from Baker Bob
- Cheese from Farmer Frank
- Lettuce from Garden Gina
Your go.mod file is like your shopping list. It tells Go exactly what you need!
How It Works
// go.mod - Your shopping list
module mysandwich
go 1.21
require (
bob.com/bread v1.2.0
frank.com/cheese v2.0.1
gina.com/lettuce v1.0.0
)
Key Commands
| Command | What It Does |
|---|---|
go mod init |
Start a new shopping list |
go get |
Add something to your list |
go mod tidy |
Clean up unused items |
Example
# Start your project
go mod init myproject
# Add a package
go get github.com/gin-gonic/gin
# Clean up
go mod tidy
graph TD A["Your Project"] --> B["go.mod"] B --> C["Package 1"] B --> D["Package 2"] B --> E["Package 3"]
π’ Semantic Versioning
The Story
Versions are like birthday numbers for packages!
- v1 = First birthday (big kid now!)
- v1.2 = Got a new skill (minor update)
- v1.2.3 = Fixed a small boo-boo (patch)
The Magic Formula
vMAJOR.MINOR.PATCH
| Part | Meaning | Example |
|---|---|---|
| MAJOR | Big changes (might break things) | v1 β v2 |
| MINOR | New features (safe to update) | v1.1 β v1.2 |
| PATCH | Bug fixes (always safe) | v1.2.0 β v1.2.1 |
Real Example
require (
// Exact version
example.com/pkg v1.2.3
// At least this version
example.com/other v1.2.0
)
π― Quick Tips
- v0.x.x = βIβm still learning!β (unstable)
- v1.0.0+ = βIβm ready!β (stable)
- v2.0.0 = βI changed a lot!β (breaking)
π Module Versioning
The Story
What happens when a package grows up and changes a lot? It gets a new room number!
In Go, when a module hits v2 or higher, it needs a new path. Itβs like moving to a bigger apartment!
The Rule
v0, v1 β same path
v2+ β add /v2, /v3, etc.
Example
// Version 1
import "github.com/user/pkg"
// Version 2 (new path!)
import "github.com/user/pkg/v2"
// Version 3
import "github.com/user/pkg/v3"
In go.mod
module myapp
require (
github.com/user/pkg v1.5.0
github.com/user/pkg/v2 v2.1.0
)
Why This Matters
You can use both versions at once! Old code keeps working while you upgrade piece by piece.
graph TD A["Your App"] --> B["pkg v1.5.0"] A --> C["pkg/v2 v2.1.0"] B --> D["Old Features"] C --> E["New Features"]
π The Replace Directive
The Story
Sometimes you want to:
- Use your own copy of a package
- Test local changes before sharing
- Fix a bug while waiting for the official fix
The replace directive is like saying: βInstead of that, use THIS!β
How To Use It
// go.mod
module myproject
require (
github.com/broken/pkg v1.0.0
)
replace github.com/broken/pkg => ../my-fixed-pkg
Common Uses
1. Local Development
replace example.com/pkg => ../local-pkg
2. Fork a Package
replace (
old.com/pkg => github.com/me/pkg v1.0.1
)
3. Specific Version
replace example.com/pkg v1.2.0 => v1.2.1
β οΈ Important!
replaceonly works in your main module- Others who import your code ignore your replaces
- Great for testing, not for publishing
π¦ Vendoring
The Story
Imagine youβre going camping. Do you want to:
- A) Hope thereβs a store nearby?
- B) Pack everything you need?
Vendoring is Option B! You copy all dependencies into a vendor folder. Now your project works anywhere, even without internet!
How To Vendor
# Copy all dependencies to vendor/
go mod vendor
# Build using vendor folder
go build -mod=vendor
What It Creates
myproject/
βββ go.mod
βββ go.sum
βββ main.go
βββ vendor/
βββ modules.txt
βββ github.com/
βββ awesome/
βββ pkg/
When To Use It
| Situation | Vendor? |
|---|---|
| CI/CD builds | β Yes |
| Offline development | β Yes |
| Security audits | β Yes |
| Quick experiments | β No |
π― Pro Tip
Always commit vendor/ to git for reproducible builds!
graph TD A["go mod vendor"] --> B["vendor/ folder"] B --> C["Package 1 copy"] B --> D["Package 2 copy"] B --> E["Package 3 copy"] F["go build"] --> B
π’ Go Workspaces
The Story
What if youβre building multiple LEGO sets that share pieces? You donβt want to rebuild the same pieces for each set!
Go Workspaces let you work on multiple modules together. Perfect for:
- Big projects with multiple apps
- Testing changes across modules
- Monorepo development
Setting Up
# Create workspace file
go work init
# Add modules to workspace
go work use ./app1
go work use ./app2
go work use ./shared-lib
The go.work File
go 1.21
use (
./app1
./app2
./shared-lib
)
Project Structure
myworkspace/
βββ go.work
βββ app1/
β βββ go.mod
β βββ main.go
βββ app2/
β βββ go.mod
β βββ main.go
βββ shared-lib/
βββ go.mod
βββ lib.go
Key Commands
| Command | What It Does |
|---|---|
go work init |
Create workspace |
go work use ./path |
Add a module |
go work sync |
Sync dependencies |
π― The Magic
Changes in shared-lib are instantly available to app1 and app2 β no publishing needed!
graph TD A["go.work"] --> B["app1"] A --> C["app2"] A --> D["shared-lib"] B --> D C --> D
π You Did It!
You now understand Goβs dependency management:
| Tool | Purpose |
|---|---|
| go.mod | Track dependencies |
| Semantic Versioning | Understand version numbers |
| Module Versioning | Handle major versions |
| replace | Use alternative packages |
| vendor | Bundle dependencies |
| go.work | Multi-module development |
π Quick Reference
# Start a project
go mod init myproject
# Add dependency
go get github.com/pkg/name
# Update all
go get -u ./...
# Clean up
go mod tidy
# Vendor
go mod vendor
# Workspace
go work init
go work use ./mymodule
Remember: Great Go code is built on well-managed dependencies. Youβve got this! π―
