Rclone — Structure#

Layout pattern#

Custom Plugin-Registry Layout (not standard Go layout)

Rclone uses a custom layout centered on a central registry (fs/registry.go) and two symmetrical “aggregator” packages (backend/all, cmd/all) that activate plugins via blank imports. The repo does not use a top-level internal/ or pkg/ directory; instead it uses lib/ for shared utilities and fs/ as the core abstraction layer. This is a deliberate architectural choice to support 70+ independently compiled backends without requiring every build to include every backend.

Directory map#

rclone/
├── rclone.go            — Single main.go: imports all backends + commands via blank imports
├── go.mod / go.sum      — Module definition
├── Makefile             — Primary build system
├── Dockerfile           — Multi-stage Docker build
├── VERSION              — Version string (used in Makefile + LDFLAGS)
│
├── backend/             — 70+ cloud/protocol storage backends (each in its own package)
│   ├── all/             — Aggregator: blank-imports every backend to register them
│   ├── alias/           — Virtual: remaps a path in another remote
│   ├── archive/         — Virtual: transparent archive handling
│   ├── azureblob/       — Azure Blob Storage
│   ├── b2/              — Backblaze B2
│   ├── cache/           — Virtual: caching decorator
│   ├── chunker/         — Virtual: splits large files into chunks
│   ├── compress/        — Virtual: transparent compression
│   ├── crypt/           — Virtual: transparent encryption/decryption
│   ├── combine/         — Virtual: merges multiple remotes into one namespace
│   ├── drive/           — Google Drive
│   ├── dropbox/         — Dropbox
│   ├── ftp/             — FTP
│   ├── local/           — Local filesystem
│   ├── memory/          — In-memory (testing/transient)
│   ├── onedrive/        — Microsoft OneDrive
│   ├── s3/              — Amazon S3 (and S3-compatible APIs)
│   ├── sftp/            — SFTP
│   ├── union/           — Virtual: policy-based union of remotes
│   └── ...              — ~55 more backends
│
├── cmd/                 — CLI commands (one package per subcommand)
│   ├── all/             — Aggregator: blank-imports every command to register them
│   ├── cmd.go           — Core CLI setup: cobra root command, global flags, Main()
│   ├── completion.go    — Shell completion helpers
│   ├── copy/            — `rclone copy`
│   ├── sync/            — `rclone sync`
│   ├── move/            — `rclone move`
│   ├── ls* /            — `rclone ls`, lsd, lsl, lsf, lsjson
│   ├── check/           — `rclone check`
│   ├── mount/           — `rclone mount` (FUSE, build-tag guarded)
│   ├── cmount/          — `rclone mount` via cgofuse
│   ├── mount2/          — Alternative FUSE mount implementation
│   ├── nfsmount/        — NFS mount
│   ├── serve/           — `rclone serve` subcommands:
│   │   ├── dlna/        —   serve via DLNA/UPnP
│   │   ├── docker/      —   Docker volume plugin
│   │   ├── ftp/         —   serve as FTP server
│   │   ├── http/        —   serve as HTTP server
│   │   ├── nfs/         —   serve as NFS server
│   │   ├── restic/      —   serve Restic REST API
│   │   ├── s3/          —   serve as S3-compatible server
│   │   ├── sftp/        —   serve as SFTP server
│   │   └── webdav/      —   serve as WebDAV server
│   ├── rc/              — `rclone rc` (remote control client)
│   ├── rcd/             — `rclone rcd` (remote control daemon)
│   ├── bisync/          — `rclone bisync` (bidirectional sync)
│   ├── config/          — `rclone config` (interactive configuration)
│   ├── test/            — Development/debug subcommands
│   └── ...              — ~30 more commands
│
├── fs/                  — Core filesystem abstraction layer (the heart of rclone)
│   ├── fs.go            — Core interfaces: Fs, Object, Directory
│   ├── registry.go      — Backend registration (RegInfo, Register())
│   ├── features.go      — Optional feature detection (Features struct)
│   ├── config/          — Configuration loading, flags, configmap, configstruct
│   ├── filter/          — Include/exclude filter rules
│   ├── operations/      — File operations: copy, check, dedupe, lsjson
│   ├── sync/            — Sync engine: sync.go, pipe.go
│   ├── march/           — Directory tree walking + pairing (two-tree sync)
│   ├── walk/            — Recursive directory listing
│   ├── accounting/      — Transfer stats, bandwidth throttling
│   ├── cache/           — Fs object cache (avoid re-creating remotes)
│   ├── hash/            — Hash type registry (MD5, SHA1, SHA256, etc.)
│   ├── fserrors/        — Error types (retriable, fatal, no retry)
│   ├── fspath/          — Remote path parsing ("remote:path")
│   ├── fshttp/          — Shared HTTP transport with retries/rate-limiting
│   ├── rc/              — Remote control API (JSON-RPC over HTTP)
│   ├── log/             — Structured logging
│   ├── logger/          — Per-file transfer logging
│   ├── asyncreader/     — Asynchronous read-ahead buffering
│   ├── chunkedreader/   — Chunked reads for large objects
│   ├── list/            — List helpers
│   ├── object/          — Object wrapper utilities
│   └── dirtree/         — Directory tree data structure
│
├── vfs/                 — Virtual filesystem layer (FUSE, VFS-serve, mount)
│   ├── vfs.go           — VFS struct: POSIX semantics over fs.Fs
│   ├── dir.go           — VFS directory node
│   ├── file.go          — VFS file node
│   ├── read.go          — Read path
│   ├── write.go         — Write path
│   ├── read_write.go    — Read-write combined mode
│   ├── vfscache/        — Local disk cache for VFS writes
│   ├── vfscommon/       — Shared VFS options (VFSCommonOpt)
│   ├── vfsflags/        — CLI flags for VFS options
│   └── vfstest/         — Generic VFS test suite
│
├── lib/                 — Shared utilities (no imports from cmd/ or backend/)
│   ├── rest/            — Generic REST client
│   ├── oauthutil/       — OAuth2 token management + web flow
│   ├── http/            — HTTP server framework (used by serve/*)
│   ├── pacer/           — Retry + rate-limit pacer (used by all backends)
│   ├── dircache/        — Directory ID cache (used by drive-like backends)
│   ├── encoder/         — Filename encoding/decoding for special characters
│   ├── errors/          — Error wrapping helpers
│   ├── multipart/       — Multipart upload helpers
│   ├── cache/           — Generic LRU cache
│   ├── kv/              — Key-value store (used by cache backend)
│   ├── batcher/         — Batch operations helper
│   ├── pool/            — Buffer pool
│   ├── readers/         — io.Reader utilities
│   ├── ranges/          — Byte range tracking
│   ├── atexit/          — Clean shutdown hooks
│   ├── systemd/         — Systemd notify integration
│   ├── daemonize/       — Process daemonization
│   ├── buildinfo/       — Version + build metadata
│   └── plugin/          — External plugin loader
│
├── librclone/           — C shared library + Gomobile bindings
│   ├── librclone/       — Core CGo export: RPC() and Initialize()
│   ├── gomobile/        — Gomobile-compatible wrapper
│   ├── ctest/           — C test program
│   ├── python/          — Python bindings example
│   └── php/             — PHP bindings example
│
├── fstest/              — Integration test infrastructure
│   ├── fstests/         — Generic backend test suite (runs against all backends)
│   ├── mockfs/          — Mock Fs for unit tests
│   ├── mockobject/      — Mock Object for unit tests
│   ├── mockdir/         — Mock Directory for unit tests
│   ├── test_all/        — Test runner for all backends
│   └── testserver/      — Test server helpers
│
├── cmdtest/             — CLI integration tests
├── contrib/             — External contributions (Docker plugin, Docker image)
├── bin/                 — Build helper scripts
├── docs/                — Hugo-based documentation site
└── graphics/            — Logo assets

Entry points#

Rclone produces a single binary from the root rclone.go:

FileBinaryDescription
rclone.gorcloneThe sole production binary — all commands and backends included via blank imports
fstest/test_all/main.gotest_allTest runner that executes the generic backend test suite against all real remotes
cmd/test/info/internal/build_csv/main.go(dev tool)Development tool for building CSV data about backends

All rclone subcommands (copy, sync, mount, serve webdav, etc.) are part of the same binary, selected via cobra subcommand dispatch. There is no multi-binary architecture.

The librclone/ packages do not have their own main.go; they produce a .so/.a C shared library via go build -buildmode=c-shared.

Package organization#

  • Internal packages: None — rclone does not use a top-level internal/ directory. All packages are importable in principle (though organized by convention).

  • Public packages (lib/): The lib/ directory acts as the shared utilities layer. Key packages:

    • lib/rest — Generic REST HTTP client with retries
    • lib/oauthutil — OAuth2 flows (used by drive, dropbox, onedrive, etc.)
    • lib/pacer — Retry/backoff pacer used by every backend
    • lib/dircache — Directory ID caching for hierarchical APIs
    • lib/encoder — Filename character encoding/escaping
    • lib/http — HTTP server used by all rclone serve commands
    • lib/rest — REST client used by most API-based backends
  • Layering: The architecture enforces a strict dependency direction:

    cmd/* → fs/* → lib/*
    backend/* → fs/* → lib/*
    vfs/* → fs/* → lib/*
    cmd/* → vfs/* (for mount/serve)
    librclone/* → fs/rc (via JSON-RPC)

    Commands do not import backends directly. Backends register themselves into fs.Registry via init() in their backend/<name>/<name>.go file, and the backend/all/all.go aggregator triggers all registrations with a single blank import from rclone.go.

Build system#

  • Build tool: GNU Make + go build
  • Key targets:
    • make / make rclone — Builds the rclone binary with version LDFLAGS
    • make test_all — Builds the multi-backend test runner
    • Various release targets for uploading betas to beta.rclone.org
    • Build tags (GOTAGS) control feature inclusion (e.g., FUSE support: cmount)
  • Docker: Yes, multi-stage. Builder stage uses golang:alpine + make. Final stage uses alpine:latest with fuse3 and ca-certificates. CGO is disabled by default (ARG CGO_ENABLED=0), though FUSE backends require CGo.

Notable structural decisions#

  1. Blank-import plugin registration: Backends and commands self-register via init() functions. The backend/all and cmd/all aggregators are the only place that couples all plugins together. This allows building custom rclone binaries with a subset of backends by substituting or omitting the aggregator, with zero changes to backend code.

  2. cmd/ as one-package-per-subcommand: Each rclone subcommand lives in its own directory (e.g., cmd/copy/copy.go). Commands register themselves into cobra’s root command via their own init(), keeping the command tree decentralized and the core cmd.go file small.

  3. fs/ as the abstraction kernel: The fs/ package is rclone’s core — it holds the Fs and Object interfaces, the backend registry, configuration handling, operations engine, and the sync algorithm. It is the heaviest directory and functions as the project’s “kernel” that everything else depends on.

  4. vfs/ as a POSIX adapter: Rather than baking POSIX semantics into individual backends, rclone provides a dedicated VFS layer that translates POSIX filesystem calls (read, write, seek, truncate) into object-storage operations. This VFS is shared between FUSE mounting, WebDAV serving, SFTP serving, and Docker volume plugin.

  5. librclone/ as a lateral exit point: The C shared library exposes the entire rclone feature set via the fs/rc JSON-RPC API, not via direct function calls. This means the library interface is the same protocol as rclone rcd + rclone rc, keeping the embedded API and the daemon API identical without additional maintenance burden.

  6. No vendor/ directory: Rclone does not vendor its dependencies, relying on Go module proxy caching. Given the ~100 direct dependencies, vendoring would add significant repository weight.