docs/developer-guide.md
By the end of this guide, you will be able to:
This guide covers the local development workflow. For user documentation, see docs.ipfs.tech.
Before you begin, ensure you have:
go.mod for the minimum required versionCGO_ENABLED=0git clone https://github.com/ipfs/kubo.git
cd kubo
make build
./cmd/ipfs/ipfs version
You should see output like:
ipfs version 0.34.0-dev
The binary is built to cmd/ipfs/ipfs. To install it system-wide:
make install
This installs the binary to $GOPATH/bin.
| Command | Description |
|---|---|
make build | build the ipfs binary to cmd/ipfs/ipfs |
make install | install to $GOPATH/bin |
make nofuse | build without FUSE support |
make build CGO_ENABLED=0 | build without CGO (no C compiler needed) |
For Windows-specific instructions, see windows.md.
Kubo has two types of tests:
ipfs nodes, run actual CLI commands, and test the full system. Slower but catch integration issues.Note that go test ./... runs both unit and end-to-end tests. Use make test to run all tests. CI runs unit and end-to-end tests in separate jobs for faster feedback.
For end-to-end tests, Kubo has two suites:
test/cli - modern Go-based test harness that spawns real ipfs nodes and runs actual CLI commands. All new tests should be added here.test/sharness - legacy bash-based tests. We are slowly migrating these to test/cli.When modifying tests: cosmetic changes to test/sharness are fine, but if significant rewrites are needed, remove the outdated sharness test and add a modern one to test/cli instead.
Environment requirements: some legacy tests expect default ports (8080, 5001, 4001) to be free and no mDNS (local network discovery) Kubo service on the LAN. Tests may fail if you have a local Kubo instance running. Before running the full test suite, stop any running ipfs daemon.
Two critical setup steps:
Rebuild after code changes: if you modify any .go files outside of test/, you must run make build before running integration tests.
Set environment variables: integration tests use the ipfs binary from PATH and need an isolated IPFS_PATH. Run these commands from the repository root:
export PATH="$PWD/cmd/ipfs:$PATH"
export IPFS_PATH="$(mktemp -d)"
go test ./...
test/cli)These are Go-based integration tests that invoke the ipfs CLI.
Instead of running the entire test suite, you can run a specific test to get faster feedback during development.
Run a specific test (recommended during development):
go test ./test/cli/... -run TestAdd -v
Run all CLI tests:
go test ./test/cli/...
Run a specific test:
go test ./test/cli/... -run TestAdd
Run with verbose output:
go test ./test/cli/... -v
Common error: "version (16) is lower than repos (17)" means your PATH points to an old binary. Check which ipfs and rebuild with make build.
test/sharness)Shell-based integration tests using sharness (a portable shell testing framework).
cd test/sharness
Run a specific test:
timeout 60s ./t0080-repo.sh
Run with verbose output (this disables automatic cleanup):
./t0080-repo.sh -v
Cleanup: the -v flag disables automatic cleanup. Before re-running tests, kill any dangling ipfs daemon processes:
pkill -f "ipfs daemon"
make test # run all tests
make test_short # run shorter test suite
Run the linter using the Makefile target (not golangci-lint directly):
make -O test_go_lint
After editing help text in core/commands/, verify the output width:
go test ./test/cli/... -run TestCommandDocsWidth
Use the Makefile target (not go mod tidy directly):
make mod_tidy
When modifying docs/changelogs/:
Always run the daemon with a timeout or shut it down promptly.
With timeout:
timeout 60s ipfs daemon
Or shut down via API:
ipfs shutdown
For multi-step experiments, store IPFS_PATH in a file to ensure consistency.
| Directory | Description |
|---|---|
cmd/ipfs/ | CLI entry point and binary |
core/ | core IPFS node implementation |
core/commands/ | CLI command definitions |
core/coreapi/ | Go API implementation |
client/rpc/ | HTTP RPC client |
plugin/ | plugin system |
repo/ | repository management |
test/cli/ | Go-based CLI integration tests |
test/sharness/ | legacy shell-based integration tests |
docs/ | documentation |
Key external dependencies:
For a deep dive into how code flows through Kubo, see The Add command demystified.
Map of Implemented Subsystems (editable source):
CLI, HTTP-API, Core Diagram:
This means the ipfs binary in your PATH is older than expected.
Check which binary is being used:
which ipfs
Rebuild and verify PATH:
make build
export PATH="$PWD/cmd/ipfs:$PATH"
./cmd/ipfs/ipfs version
If you don't need FUSE support, build without it:
make nofuse
Or set the TEST_FUSE=0 environment variable when running tests.
You're missing a C compiler. Either install GCC or build without CGO:
make build CGO_ENABLED=0
If you make changes to the protocol buffers, you will need to install the protoc compiler.
Add command demystified - deep dive into code flowThe complete source code is at github.com/ipfs/kubo.