Headless Go client for Obsidian
Home
Getting Started
  • Overview
  • macOS
  • Linux
  • Windows
  • Docker
  • From Source
  • Overview
  • Authentication
  • Sync
  • Publish
  • Configuration
  • Overview
  • Sync Protocol
  • Encryption
  • REST API
  • Circuit Breaker
GitHub
Home
Getting Started
  • Overview
  • macOS
  • Linux
  • Windows
  • Docker
  • From Source
  • Overview
  • Authentication
  • Sync
  • Publish
  • Configuration
  • Overview
  • Sync Protocol
  • Encryption
  • REST API
  • Circuit Breaker
GitHub
  • Architecture
  • Sync Protocol
  • Encryption
  • REST API
  • Circuit Breaker

Architecture

This page provides a high-level overview of how the Headless Go client for Obsidian is structured, how data moves through the system, and where configuration lives.

For deeper dives into specific areas, see the architecture subpages.

Module Layout

The source code lives under src/ and is split into focused packages:

PackageKey FilesPurpose
apiclient.goHTTP REST client for Obsidian cloud services
circuitbreakerconfig.goCircuit breaker factory functions and error types
cliroot.go, sync.goCobra CLI entry point and command tree
configconfig.go, secrets.goConfiguration management (auth, sync, publish)
encryptionprovider.goEncryptionProvider interface, V0 AES-GCM, V2/V3 AES-SIV + AES-GCM
logginglogger.gozerolog console + file logger with lumberjack rotation
modeltypes.goShared types (UserInfo, Vault, SyncConfig, FileRecord, etc.)
publishengine.goPublish scanning, upload, and removal engine
storagestate.go, crypto.goSQLite state store via modernc.org/sqlite, credential encryption
syncengine.go, connection.go, plan.go, merge.go, lock.goSync engine, WebSocket connection, plan builder, three-way merge, file locking
utilfiles.goFile scanning, SHA-256 hashing, safe path join, random hex

Data Flow

Sync Flow

The sync flow keeps a local vault in sync with the Obsidian Sync server over a WebSocket connection.

WebSocket connection, engine.RunOnce/RunContinuous, file watcher (fsnotify), plan builder (upload/download/delete/merge actions), parallel downloads with worker pool, three-way merge for text, JSON key-level merge for configs, 2MB chunks, 200MB max file, 30s interval, 5 concurrent downloads.

For details on the sync protocol, see Sync Protocol. For encryption specifics, see Encryption.

Publish Flow

The publish flow scans local files and uploads them to the Obsidian Publish API.

For details on the REST API used by publish (and sync), see REST API.

File Watching Strategy

The sync engine uses fsnotify (cross-platform Go file system notifications), with a periodic full-rescan for consistency. Event aggregation with debounce is used to batch rapid changes. In continuous mode, the watcher triggers sync cycles on file changes.

Watch disabled for read-only modes

In pull-only and mirror sync modes, local file changes are never uploaded. The fsnotify watcher is not started; only an initial scan is performed. This eliminates filesystem event overhead on machines that only download.

Configuration Storage

All configuration is stored under a platform-specific base directory:

  • Linux: $XDG_CONFIG_HOME/obsidian-headless or ~/.config/obsidian-headless
  • macOS: ~/.obsidian-headless

Directory structure:

  • auth token: OS keyring (with encrypted SQLite fallback at credentials.db)
  • vault config: sync/{vaultID}/config.json + state.db
  • site config: publish/{siteID}/config.json + cache.json

Dependencies

PackagePurpose
spf13/cobraCLI framework for command parsing and flag management
modernc.org/sqlitePure-Go SQLite driver for sync state storage
gopkg.in/yaml.v3YAML parsing for frontmatter extraction
sony/gobreaker/v2Circuit breaker for API and WebSocket resilience

Runtime Requirements

  • Go 1.21+ — Required for building the CLI binary. Uses Go 1.26 in CI.
  • Platforms: Linux, macOS, Windows (amd64, arm64)

Further Reading

  • Sync Protocol — Deep dive into the WebSocket sync protocol
  • Encryption — Encryption providers, AES-SIV, and key derivation
  • REST API — HTTP REST client and API endpoints
  • Circuit Breaker — Pattern overview, retry integration, and state management
Edit this page on GitHub
Last Updated: 5/1/26, 8:35 PM
Contributors: Belphemur
Next
Sync Protocol