Understanding Go modules and packages through the lens of Node.js
When I first started learning Go, Node.js naturally came to my mind.
Maybe it’s because both languages use the ideas of modules and packages to organize code.
This structure is actually common across many modern languages but the way Go and Node.js approach it is unique in their own ways.
In this blog, I’ll share the similarities and differences I found, for anyone who might feel the same connection.
What is a Package?
In Node.js
- A package is any reusable library or project you install through
npm
oryarn
. - Example:
express
,lodash
, or even your own project is considered a package.
In Go
- A package is a group of
.go
files in the same folder that declare the samepackage
name at the top. - Every Go file must start with something like
package main
orpackage utils
.
What is a Module?
In Node.js
- The term module originally meant a
.js
file you can import usingrequire()
orimport
. - Today, a Node.js project (with a
package.json
) is often considered a module too.
In Go
- A module is a collection of Go packages that are versioned together.
- It’s created with a
go.mod
file at the root of your project.
Node.js module ≈ Go module — in the project sense (but Go modules are stricter and more formalized).
Concept Comparison: Packages and Modules
Setting Up a Simple Project
Node.js setup:
mkdir my-node-app
cd my-node-app
npm init -y
npm install express
Creates:
package.json
node_modules/
(stores all dependencies locally)- Your code in
index.js
Go setup:
mkdir my-go-app
cd my-go-app
go mod init github.com/username/my-go-app
go get github.com/gorilla/mux
Creates:
go.mod
(declares your module and dependencies)go.sum
(tracks versions and security hashes)- Your code in
main.go
How Dependencies Are Stored
- In Node.js, all third-party packages are installed locally inside a huge
node_modules/
directory under each project. - In Go, third-party packages are downloaded once and cached globally (typically under
$GOPATH/pkg/mod
or Go’s internal module cache).
Your project only tracks which dependencies it uses (go.mod
andgo.sum
), not the actual source code.
This design makes Go projects much lighter compared to Node.js projects, where node_modules
can often be larger than your own code!