Introduction
Afero is a filesystem abstraction library for Go created by Steve Francia (spf13). It defines an Fs interface that mirrors the os package, letting applications swap between real filesystems, in-memory filesystems, and custom backends without changing business logic. This makes code testable, portable, and easier to reason about.
What Afero Does
- Provides a drop-in
Fsinterface compatible with standardosfile operations - Includes an in-memory filesystem (MemMapFs) for fast, isolated testing
- Offers a read-only filesystem wrapper to enforce immutability
- Supports layered union filesystems that overlay multiple backends
- Ships utility functions (ReadFile, WriteFile, Walk, Exists) that mirror the os and io/ioutil packages
Architecture Overview
Afero defines the Fs interface with methods matching os.Create, os.Open, os.Stat, and related operations. Concrete implementations include OsFs (delegates to the real OS), MemMapFs (stores files in a thread-safe map), BasePathFs (restricts access to a subtree), and ReadOnlyFs (wraps any Fs and rejects writes). Union filesystems compose multiple layers with configurable read and write priorities.
Self-Hosting & Configuration
- Add to your project with
go get github.com/spf13/afero - Use
afero.NewOsFs()for production andafero.NewMemMapFs()for tests - Restrict file access to a directory with
afero.NewBasePathFs(base, "/app/data") - Combine layers with
afero.NewCopyOnWriteFs(readOnly, writable)for overlay patterns - All implementations are safe for concurrent use
Key Features
- Drop-in replacement for os file operations via a single interface
- MemMapFs enables deterministic, fast tests without touching disk
- BasePathFs sandboxes file access to a specific directory subtree
- CopyOnWriteFs supports union mounts for layered file systems
- Used by Hugo, Viper, Cobra, and other widely adopted Go projects
Comparison with Similar Tools
- os package — Afero wraps os with an interface, adding testability and portability
- embed.FS — read-only embedded files; Afero supports full read-write operations
- Billy (go-git) — similar abstraction but tightly coupled to go-git; Afero is general-purpose
- io/fs (Go 1.16) — read-only interface; Afero provides read-write plus layered composition
- testify mock — mocks individual calls; Afero gives a complete in-memory filesystem
FAQ
Q: Is MemMapFs thread-safe? A: Yes, MemMapFs uses internal locks and is safe for concurrent reads and writes.
Q: Can I use Afero with cloud storage like S3? A: Afero defines the interface; community packages like afero-s3 implement the Fs interface for cloud backends.
Q: How does Afero relate to Viper and Cobra? A: All three are by spf13. Viper uses Afero for configuration file access, and Cobra uses Viper for config. Afero is the filesystem layer in this stack.
Q: Does Afero support file watchers? A: Afero does not include built-in file watching. Use fsnotify alongside OsFs for change notifications.