Air — Dependencies#
Module info#
- Module: github.com/air-verse/air
- Go version: 1.25
- Direct dependencies: 9
- Indirect dependencies: 17 (listed in go.mod) + ~79 further transitives (go.sum has ~105 total module entries across 210 lines)
Dependency categories#
Core infrastructure#
github.com/pelletier/go-toml v1.9.5— TOML parsing for.air.tomlconfig files. Air uses v1 (not v2) directly; hugo pulls in v2 as an indirect dep.dario.cat/mergo v1.0.2— Struct deep-merge. Used inrunner/config.goto merge user-supplied config over default config values, respecting zero values via a custom transformer.github.com/joho/godotenv v1.5.1— Loads.envfiles into the process environment. Supports Air’senv_filesconfig option for injecting environment variables before the watched binary runs.github.com/fatih/color v1.18.0— Terminal color output for Air’s logger (colored prefixes for different log levels/statuses). Pulls inmattn/go-colorableandmattn/go-isattyas indirect deps for Windows compatibility.golang.org/x/sys v0.35.0— Low-level OS syscalls. Used in platform-specific files (util_linux.go,util_unix.go,util_windows.go) for process signaling and filesystem operations.
File watching#
github.com/fsnotify/fsnotify v1.9.0— Cross-platform filesystem event watching (inotify on Linux, FSEvents on macOS, ReadDirectoryChanges on Windows). The primary mechanism for detecting file changes.github.com/gohugoio/hugo v0.149.1— Used exclusively forgithub.com/gohugoio/hugo/watcher/filenotify, a package that provides poll-based file watching as a fallback when nativefsnotifyis unavailable or whenpollmode is configured. This is the most controversial dependency: importing all of Hugo (a full CMS framework) just to get a single sub-package’s polling abstraction.
Networking/HTTP#
github.com/andybalholm/brotli v1.2.0— Brotli decompression/recompression used in Air’s embedded HTTP proxy (runner/proxy.go) to handle Brotli-encoded upstream responses when injecting the live-reload WebSocket script.
Testing#
github.com/stretchr/testify v1.11.1— Test assertions (assert,requiresub-packages) used acrossrunner/*_test.gofiles. Pulls ingo-spew,go-difflib, andyaml.v3as indirect deps.
Other#
No CLI framework, no gRPC, no database drivers.
Stdlib reliance#
Air relies heavily on stdlib — arguably more than on third-party packages for its core logic:
| Package | Usage |
|---|---|
os / os/exec | Launching and managing the watched binary process |
net/http | Entire embedded reverse-proxy implementation |
context | Cancellation propagation through engine, watcher, proxy |
sync / sync/atomic | Mutex guards on internal state; atomic flags for shutdown |
path/filepath | Include/exclude path matching throughout watcher |
reflect | Reflection-based CLI flag generation in runner/flag.go |
compress/gzip | Gzip body decoding in the proxy (alongside brotli) |
encoding/json | Proxy response body inspection |
regexp | Exclude regex matching for file paths |
time | Rebuild delay, kill delay, timeout handling |
html | HTML entity escaping in proxy script injection |
embed | Embedding the live-reload JS snippet into the binary |
crypto/sha256 / encoding/hex | File checksum caching for unchanged-file detection |
The stdlib handles process management, HTTP proxying, and most I/O. Third-party deps fill specific gaps: TOML parsing, file watching, terminal colors, struct merging, and Brotli support.
Shared dependencies#
Dependencies that appear frequently across the 50-project research set:
github.com/fsnotify/fsnotify— Used by many Go tools and servers for file watching (e.g., Viper, Hugo, many test frameworks)github.com/fatih/color— Common in CLI tools for terminal output stylinggithub.com/stretchr/testify— Near-universal in Go projects as a test assertion librarygolang.org/x/sys— Used by any project doing low-level OS operationsgithub.com/pelletier/go-toml— Less common but appears in projects with TOML config (Hugo, etc.)dario.cat/mergo— Occasionally seen in config-heavy toolsgithub.com/joho/godotenv— Common in dev-tooling and twelve-factor app helpers
Vendoring#
No vendor directory. Air relies on the Go module cache. This is standard for a developer tool rather than a deployable service. The Docker image (cosmtrek/air) presumably uses go install or a pre-built binary, not vendored source.
Notable dependency decisions#
The Hugo problem: Air imports github.com/gohugoio/hugo — a full static site generator — solely for hugo/watcher/filenotify. This one sub-package provides a polling-based file notification abstraction. The consequence: Air’s go.sum balloons to ~105 module entries, pulling in Dart Sass bindings (bep/godartsass), WebP support (bep/gowebp), libsass (bep/golibsass), spf13/afero, spf13/cast, tdewolff/parse, google.golang.org/protobuf, and more — none of which are used by Air at all. This is a known anti-pattern in Go: importing a large module for one package. A better approach would be to vendor just the filenotify package directly or extract it to a standalone library.
TOML v1 vs v2: Air uses pelletier/go-toml v1 directly while Hugo (pulled in as a dep) uses v2, resulting in both versions appearing in the module graph. This suggests Air has not yet migrated to the v2 API.
No CLI framework: Air uses flag from stdlib plus its own reflection-based flag generation (runner/flag.go) instead of cobra or urfave/cli. This keeps the dependency count low but creates non-standard CLI behavior (no --help auto-generation, no subcommands).
Minimal data layer: Zero database, cache, or serialization dependencies beyond TOML and JSON (stdlib). The tool is purely computational — file watching, process management, and HTTP proxying — which justifies the lean dependency profile in everything except the Hugo import.