Go Tutorials — Module, Package, Function, Method & Interface

These five concepts become much easier once you see how they fit together:

flowchart TD
    M["Module<br/>Whole Go project"]
    P1["Package main"]
    P2["Package fmt"]
    F["Function<br/>add()"]
    T["Type<br/>Person"]
    ME["Method<br/>person.Greet()"]
    I["Interface<br/>Speaker"]

    M --> P1
    P1 --> F
    P1 --> T
    T --> ME
    I -. "method satisfies" .-> ME
    P1 -->|"imports"| P2

The simplest mental model is:

Module = Project
Package = Folder / code group
Function = Standalone action
Method = Action belonging to a type
Interface = Required behavior


1. Module

What is a Module?

A module is your Go project.

It is normally a directory containing a file called:

go.mod

Example:

myapp/
├── go.mod
└── main.go

Think:

Module = entire project


Why do we need a Module?

Go uses the module to know:

  • the name of your project
  • which external dependencies your project uses
  • which versions of dependencies should be downloaded

When do we use it?

Normally when starting a new Go project:

mkdir myapp
cd myapp

go mod init myapp

Go creates:

go.mod

Complete Example

Run:

mkdir module-demo
cd module-demo

go mod init module-demo

You’ll see:

go: creating new go.mod: module module-demo

Now create:

main.go

package main

import "fmt"

func main() {
	// This is our program.
	fmt.Println("Hello from my Go module!")
}

Run:

go run .

Output:

Hello from my Go module!

Your directory now looks like:

module-demo/
├── go.mod
└── main.go

And go.mod will look approximately like:

module module-demo

go 1.26

What does this mean?

module module-demo

means:

The name/path of this module is module-demo.

And:

go 1.26

tells Go which Go language/module version this project targets.


Where does Module sit?

flowchart TD
    A["module-demo<br/>MODULE"]
    B["go.mod"]
    C["main.go"]
    D["package main"]

    A --> B
    A --> C
    C --> D

Remember

One project usually has one go.mod.


2. Package

What is a Package?

A package is a group of related Go code.

Every .go file must declare which package it belongs to.

For example:

package main

Why do we need Packages?

Packages help organize code.

Imagine a large application:

shopping-app/
├── main.go
├── users/
├── payments/
├── orders/
└── products/

You could have packages such as:

main
users
payments
orders
products

Instead of putting everything into one huge file.


When do we use Packages?

Always.

Every Go file belongs to a package.

Even the smallest Go program has:

package main

Complete Example

Create main.go:

package main

// ↑ This file belongs to the "main" package.

import "fmt"

// ↑ We are using another package called "fmt".
// fmt is part of Go's standard library.

func main() {

	// Println is a function inside the fmt package.
	fmt.Println("Hello Go!")

}

Run:

go run main.go

Output:

Hello Go!

Look carefully at this

fmt.Println("Hello Go!")

Here:

fmt

is the package.

And:

Println

is a function inside the package.

So:

fmt.Println()
│   │
│   └── Function
│
└────── Package

What is special about package main?

This is important.

package main

means:

This package is intended to build an executable program.

For an executable Go program, you normally need:

package main

func main() {

}

So:

package main
     +
func main()
     =
executable Go program

Package relationship

flowchart LR
    A["package main"] -->|"uses"| B["package fmt"]
    B --> C["Println()"]

Remember

Module contains packages.


3. Function

What is a Function?

A function is a named block of code that performs a task.

Example:

func add(a int, b int) int {
	return a + b
}

Think:

Function = reusable action

Examples:

add()
login()
sendEmail()
calculateSalary()
printReport()

Why use Functions?

Without functions, you would repeat the same code again and again.

Instead of:

result := 10 + 20

everywhere, you can create:

add(10, 20)

Complete Example

package main

import "fmt"

// add is a FUNCTION.
//
// a int  -> first input
// b int  -> second input
// int    -> function returns an integer
func add(a int, b int) int {

	result := a + b

	return result
}

func main() {

	// Calling the function
	answer := add(10, 20)

	fmt.Println("Answer:", answer)
}

Run:

go run main.go

Output:

Answer: 30

Understand the function

func add(a int, b int) int {
	return a + b
}

Break it down:

func add(a int, b int) int
│    │   │             │
│    │   │             └── return type
│    │   │
│    │   └──────────────── parameters
│    │
│    └──────────────────── function name
│
└───────────────────────── function keyword

How do we call it?

answer := add(10, 20)

Flow:

flowchart LR
    A["main()"] --> B["add(10,20)"]
    B --> C["10 + 20"]
    C --> D["return 30"]
    D --> A

Where can a function exist?

A normal function belongs to a package.

For example:

package main

func add() {
}

add() belongs to package main.

Remember

Function = standalone behavior.


4. Method

This is where many Go learners get confused.

A method is almost the same as a function.

The difference is:

A method belongs to a type.


Function vs Method

Function:

func greet() {

}

Method:

func (p Person) greet() {

}

Notice this:

(p Person)

That is called the receiver.

It connects the function to Person.


Why use Methods?

Suppose we have:

type Person struct {
	Name string
}

A person may perform actions:

Person
 ├── Greet()
 ├── Walk()
 ├── Sleep()
 └── Work()

These actions naturally belong to Person.

So methods make sense.


Complete Example

package main

import "fmt"

// Person is a custom type.
type Person struct {
	Name string
}

// Greet is a METHOD belonging to Person.
//
// (p Person) is called the RECEIVER.
//
// It means:
// "This method belongs to Person."
func (p Person) Greet() {

	fmt.Println("Hello, my name is", p.Name)
}

func main() {

	// Create a Person value
	person := Person{
		Name: "Rajesh",
	}

	// Call the method using the Person value
	person.Greet()
}

Run:

go run main.go

Output:

Hello, my name is Rajesh

Understand this line

func (p Person) Greet()

Break it down:

func (p Person) Greet()
│     │        │
│     │        └── method name
│     │
│     └────────── receiver
│
└──────────────── keyword

The receiver:

(p Person)

means:

Greet() belongs to Person.


Therefore we can write

person.Greet()

Think:

person.Greet()
│      │
│      └── Method
│
└───────── Person object/value

Function vs Method

Normal function:

Greet(person)

Method:

person.Greet()

Conceptually:

flowchart LR
    A["Person"] --> B["Greet()"]
    A --> C["Walk()"]
    A --> D["Work()"]

Remember

Function = standalone action

Method = action attached to a type


5. Interface

This is usually the most confusing one.

But there is a very simple way to think about it.

Interface = a list of behaviors/methods that something must have.

Suppose we create:

type Speaker interface {
	Speak()
}

This means:

Anything that has a Speak() method can be considered a Speaker.

That’s the core idea.


Why use an Interface?

Imagine:

Dog can Speak()
Person can Speak()
Robot can Speak()

All three are completely different types.

But they have one thing in common:

Speak()

So we could create:

type Speaker interface {
	Speak()
}

Now functions can work with anything that knows how to Speak.


Complete Interface Example

package main

import "fmt"

// Speaker is an INTERFACE.
//
// Anything that has:
//
// Speak()
//
// automatically satisfies this interface.
type Speaker interface {
	Speak()
}

// Person is a custom type.
type Person struct {
	Name string
}

// Person has a Speak method.
//
// Therefore Person automatically satisfies
// the Speaker interface.
func (p Person) Speak() {

	fmt.Println(p.Name, "says hello!")
}

// This function accepts ANYTHING
// that satisfies the Speaker interface.
func makeItSpeak(s Speaker) {

	s.Speak()
}

func main() {

	person := Person{
		Name: "Rajesh",
	}

	// Person has Speak()
	// therefore Person can be passed as Speaker.
	makeItSpeak(person)
}

Run:

go run main.go

Output:

Rajesh says hello!

The important part

We created:

type Speaker interface {
	Speak()
}

And Person has:

func (p Person) Speak() {
}

Therefore:

Speaker requires Speak()
           ↑
           │
Person has Speak()
           │
           ↓
Person satisfies Speaker

You do NOT write something like:

Person implements Speaker

Go figures it out automatically.

This is called implicit interface implementation.


Visualize it

flowchart TD
    I["Speaker Interface<br/>requires Speak()"]

    P["Person"]
    D["Dog"]
    R["Robot"]

    PM["Speak()"]
    DM["Speak()"]
    RM["Speak()"]

    P --> PM
    D --> DM
    R --> RM

    PM --> I
    DM --> I
    RM --> I

If all three types have:

Speak()

then all three satisfy:

Speaker

The Complete Mental Model

Now connect everything together.

Imagine this project:

shop/
├── go.mod
└── main.go

Module

shop

The entire project.


Package

Inside main.go:

package main

Code organization.


Function

func calculatePrice() {

}

Standalone behavior.


Type

type Customer struct {
	Name string
}

Represents something.


Method

func (c Customer) Buy() {

}

Behavior attached to Customer.


Interface

type Buyer interface {
	Buy()
}

Defines the behavior something must have.


How Everything Fits Together

flowchart TD
    M["MODULE<br/>shopping-app"]

    P["PACKAGE<br/>main"]

    F["FUNCTION<br/>calculatePrice()"]

    T["TYPE<br/>Customer"]

    ME["METHOD<br/>customer.Buy()"]

    I["INTERFACE<br/>Buyer<br/>requires Buy()"]

    M --> P

    P --> F
    P --> T
    P --> I

    T --> ME

    ME -. "satisfies" .-> I

That one diagram is worth remembering.


Master Comparison

ConceptSimple MeaningExampleBelongs To / ContainsMain Purpose
ModuleEntire Go projectmodule shoppingContains packagesProject/dependency management
PackageGroup of Go codepackage mainBelongs to moduleOrganize code
FunctionStandalone actionadd()Belongs to packagePerform reusable work
MethodFunction attached to a typeperson.Greet()Belongs to a typeGive behavior to types
InterfaceRequired methods/behaviorSpeakerDefined in a packageAllow different types to share behavior

Module vs Package

ModulePackage
Entire projectPart of project
Defined by go.modDefined by package xxx
Can contain many packagesContains Go files/types/functions
Handles dependenciesOrganizes code
Example shopping-appExample payment

Think:

Company
  ↓
Departments

similar to:

Module
  ↓
Packages

Package vs Function

PackageFunction
Groups codePerforms an action
Contains functionsLives inside package
fmtPrintln()
mathSqrt()

Example:

fmt.Println()
fmt       = package
Println   = function

Function vs Method

This distinction is extremely important.

FunctionMethod
StandaloneAttached to a type
No receiverHas receiver
add(10,20)person.Greet()
func add()func (p Person) Greet()

Function:

func greet() {
}

Method:

func (p Person) greet() {
}

The magic difference is:

(p Person)

Method vs Interface

MethodInterface
Actual behavior/codeRequired behavior
Contains implementationUsually only method signatures
Speak() prints somethingSays “Speak() must exist”
Attached to a typeCan be satisfied by many types

Example:

Interface says:

type Speaker interface {
	Speak()
}

Person provides:

func (p Person) Speak() {
	fmt.Println("Hello")
}

Therefore:

Person → satisfies → Speaker

Function vs Interface

FunctionInterface
Performs actual workDescribes required behavior
Contains codeContains method signatures
add()Speaker
Called directlyUsed as a type/contract

For example:

func makeItSpeak(s Speaker) {
	s.Speak()
}

Here:

makeItSpeak = function
Speaker     = interface
Speak       = required method

Module vs Everything Else

This hierarchy makes it easier:

MODULE
│
├── PACKAGE
│    │
│    ├── Function
│    │
│    ├── Type
│    │     │
│    │     └── Method
│    │
│    └── Interface
│
└── PACKAGE
     │
     ├── Function
     ├── Type
     └── Interface

Or visually:

flowchart TD
    M["MODULE"]

    P1["PACKAGE"]
    P2["PACKAGE"]

    F["FUNCTION"]
    T["TYPE"]
    ME["METHOD"]
    I["INTERFACE"]

    M --> P1
    M --> P2

    P1 --> F
    P1 --> T
    P1 --> I

    T --> ME

One-Line Definitions You Should Memorize

ConceptMemorize This
ModuleA Go project containing one or more packages
PackageA group of related Go files/code
FunctionA reusable standalone block of code
MethodA function attached to a type
InterfaceA set of methods describing behavior

The 5 Questions to Ask Yourself

Whenever you see Go code, identify these things.

1. What is the module?

Look at:

go.mod

2. What package am I in?

Look at the first line:

package main

3. Is this a function?

Look for:

func add() {
}

No receiver → function.


4. Is this a method?

Look for:

func (p Person) Greet() {
}

Receiver exists:

(p Person)

method


5. Is this an interface?

Look for:

type Speaker interface {
	Speak()
}

interface


Final Example to Test Your Understanding

Don’t run this yet. Just identify each part:

package main

import "fmt"

type Person struct {
	Name string
}

type Speaker interface {
	Speak()
}

func add(a int, b int) int {
	return a + b
}

func (p Person) Speak() {
	fmt.Println(p.Name, "is speaking")
}

func main() {

	p := Person{Name: "Rajesh"}

	p.Speak()

	fmt.Println(add(10, 20))
}

The answer is:

package main
      ↓
PACKAGE


type Person struct
      ↓
TYPE


type Speaker interface
      ↓
INTERFACE


func add(...)
      ↓
FUNCTION


func (p Person) Speak()
      ↓
METHOD


func main()
      ↓
FUNCTION

And if the directory has:

go.mod

then the entire directory/project is the:

MODULE

The Most Important Picture

Keep this mental picture:

flowchart LR
    M["Module<br/>PROJECT"] --> P["Package<br/>CODE GROUP"]

    P --> F["Function<br/>DO SOMETHING"]

    P --> T["Type<br/>REPRESENT SOMETHING"]

    T --> ME["Method<br/>TYPE CAN DO SOMETHING"]

    P --> I["Interface<br/>MUST BE ABLE TO DO SOMETHING"]

    ME -. "can satisfy" .-> I

In plain English

Module: This is my project.
Package: This is how I organize my project’s code.
Function: Do this work.
Method: This particular type can do this work.
Interface: I don’t care what the type is, as long as it can do this work.

If you get these five sentences clear, Go functions, methods, and interfaces become much easier to understand.

Related Posts

Go Tutorials: Go Methods

Go methods become much easier once you understand one idea: A method is simply a function attached to a type. And the important rule is: A receiver…

Read More

Go Tutorials: Modules, Packages, Subpackages, Submodules, and Workspaces

This tutorial gives you one complete mental model for: The most important idea is: And sometimes: These two designs are very different. 1. What is a Go…

Read More

Go Tutorials: Numeric Types Beginner Tutorial

Go has four main families of numeric types: The simplest way to remember them is: Type family Stores Example int Whole numbers, positive or negative -10, 0,…

Read More

Go Tutorials: Go Testing, Benchmarking, and Profiling

These three topics become much easier once you separate the questions they answer: Topic Main question Main Go tool Result Testing Does my code work correctly? go…

Read More

Go Tutorials: Generics

1. What are Generics? Generics let you write one piece of code that works with multiple types while keeping Go’s compile-time type safety. Suppose you want a…

Read More

Go Concurrency Management Made Simple

This tutorial covers: The goal is: One concept → one purpose → one complete runnable example. Every example is independent. Save any example as: and run: 0….

Read More