Use Obsidian Sync on Desktop without Installing Obsidian

Mar. 27, 2026

I know this might sound a bit odd. Let me explain: (1) Obsidian Sync is, for now, the most stable, lowest-latency cross-platform (including desktop and mobile) service I’ve found for syncing plain text notes, and it works better than various cloud storage options; but (2) I mainly use Obsidian on mobile, while on desktop I prefer VS Code (see my setup in “VS Code as A Scratchpad”). Previously, to keep things synced, I had to keep Obsidian running on my computer, which is a heavy Electron app, and if it accidentally closed, syncing would stop.

A while ago, I noticed Obsidian released a headless version of the Obsidian Sync terminal client. (I loathe the recent “claw hype” but concede that it contributed to a CLI renaissance, after all.) Once set up, ob --continuous starts monitoring and syncing the notes folder in real time, which is exactly what I need. The only downside is that it doesn’t run in the background or stay active persistently. But that’s fine — this is exactly what PID 1 excels at. For example, on macOS, you can achieve this with launchd. The steps are as follows.

  1. Install obsidian-headless

    npm install -g obsidian-headless
    
  2. Log in and connect your notes library

    cd /path/to/local/vault
    ob login
    ob sync-setup --vault "Your Remote Vault"
    
  3. Create a Launch Agent under ~/Library/LaunchAgents/ with the name, for example, md.obsidian.headless-sync.plist (GitHub):

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
    "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
    
    <key>Label</key>
    <string>md.obsidian.headless-sync</string>
    
    <key>ProgramArguments</key>
    <array>
        <!-- Replace with your output of npm prefix -g -->
        <string>/opt/homebrew/bin/ob</string>
        <string>sync</string>
        <string>--path</string>
        <!-- Replace with your local vault path -->
        <string>/path/to/local/vault/</string>
        <string>--continuous</string>
    </array>
    
    <key>RunAtLoad</key>
    <true/>
    
    <key>KeepAlive</key>
    <dict>
        <key>SuccessfulExit</key>
        <false/>
    </dict>
    
    <key>StandardOutPath</key>
    <string>/tmp/obsidian-headless-sync.log</string>
    
    <key>StandardErrorPath</key>
    <string>/tmp/obsidian-headless-sync.err</string>
    
    <key>EnvironmentVariables</key>
    <dict>
        <key>PATH</key>
        <string>/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin</string>
    </dict>
    
    </dict>
    </plist>
    
  4. Load the Launch Agent and verify

    launchctl load ~/Library/LaunchAgents/md.obsidian.headless-sync.plist
    launchctl list | grep obsidian
    tail -f /tmp/obsidian-headless-sync.log
    

From now on, Obsidian Sync will automatically start syncing after login and restart if it exits unexpectedly. This headless version uses about 40 MB+ of memory, which, while still not a small footprint — Node being Node — is only a fraction of the GUI version.

(On Linux and Windows, you can use systemd and Task Scheduler, respectively, to similar effect.)