✨ Try our AI novel writing platform → StoryAlter.com
#MD SoloMD

v3.0

Sync, optionally.

v3.0 ships the one feature SoloMD always avoided: sync. We avoided it because the obvious shape — SoloMD-hosted CRDT servers — would have made us a SaaS. The shape we landed on instead: your vault → your GitHub repo. Optional end-to-end encryption. Optional iCloud / Dropbox / OneDrive folder mode. Optional public read-only share. No SoloMD server. No subscription. No account.

☁️ GitHub-backed sync

Open Settings → GitHub Sync. Paste a Personal Access Token (stored in your OS keychain — macOS Keychain Access, Windows Credential Manager, Linux Secret Service). Pick an existing repo or let SoloMD create a fresh private one. From that point on:

  • Auto-push 5s after every save (debounced). Skips when there's nothing to commit.
  • Auto-pull on a configurable interval (5 / 15 / 30 / 60 min). Skips when local has uncommitted changes — no surprise overwrites.
  • Conflict resolver in the History panel: per-file Use Mine / Use GitHub / Keep Both. The "Keep Both" path saves the remote version alongside as note.remote-2026-04-26.md.
  • libgit2-vendored — same engine that powers v2.2 AutoGit. No system git binary needed.

SoloMD never holds your data. We don't even know your repo exists. Push to GitHub Free if you can fit in 1 GB; push to GitHub Pro ($4/mo) for unlimited private repos. Either way the subscription stays between you and GitHub.

🔒 End-to-end encryption (optional)

Tick "Encrypt before push" when linking. Set a passphrase. From then on the remote sees only ciphertext: every .md becomes a .md.enc blob with our 4-byte SLMD magic, a 24-byte XChaCha20 nonce, and a 16-byte Poly1305 tag.

Trade-offs we picked, on purpose:

  • Argon2id for passphrase → key. RFC9106 default params (~19 MB / 2 iters). Salt + KDF params committed to the encrypted repo so a second device with the same passphrase derives the same key.
  • XChaCha20-Poly1305 for the AEAD. Authenticated; tampering is detected.
  • Deterministic, key-bound nonce — SHA-256(key ‖ aad ‖ plaintext)[..24]. This is convergent encryption: re-encrypting unchanged plaintext produces zero git diff. Without this, every push would touch every file. The trade-off: an attacker with read access to the remote can detect plaintext-equality across files in the same vault. For a single-user vault, that's acceptable.
  • Path is AAD. Swapping secret-2026.md.enc ciphertext into boring.md.enc fails verification. Adversaries can't move blobs around.
  • Plaintext stays local. Search, RAG, AI rewrite, slideshow — all keep working because nothing intercepts the local .md read path. The encrypted shadow lives in <workspace>/.solomd-encrypted/ and is the only thing pushed.

Not bulletproof against a malicious local process or a compromised device — that's not the threat model. It IS bulletproof against a leaked PAT, a public-by-mistake repo, an accidental clone, or GitHub's compliance team.

🗂️ iCloud / Dropbox / OneDrive (no setup required)

If your workspace already lives at ~/Library/Mobile Documents/com~apple~CloudDocs/Notes or ~/Dropbox/Notes, you don't need GitHub sync at all — Apple / Dropbox / Microsoft already do the file-level sync. v3.0 detects that and surfaces a banner in Settings, so you know.

We add one thing on top: per-device session restore. Each device writes a .solomd/session.<deviceId>.json with its open tabs. When you open the same workspace on a second device and it sees a sibling session that's fresher than your own, you get a one-click "Restore tabs from Mac mini" prompt. Pick up where you left off, even across machines, without us touching your data.

🌐 Public read-only share

Open the command palette, run GitHub Sync: Copy Share Link for This Note. The link looks like solomd.app/share/?repo=you/notes&path=2026-roadmap.md. Anyone with that URL gets a clean Markdown render of the note — fetched directly from raw.githubusercontent.com, rendered in their browser via marked + DOMPurify, no SoloMD server in the loop, no analytics tracking who reads it.

Private repos can't be shared this way (raw URLs need auth). The page surfaces a clear "may be private" message instead of silently 404-ing. If you do want to share something, push it to a public repo first.

🔧 Multi-provider

GitHub is the default and gets the full UX (auto-create + repo picker via the GitHub REST API). For GitLab, Gitea, or any self-hosted git server, pick your provider in the dropdown, paste a clone URL, and push / pull works the same way — the underlying libgit2 + PAT credential dance is provider-agnostic.

🧰 Quality of life from the community

Two community PRs landed alongside v3.0:

  • Collapsible outline + sidebar position (#35, @ZHTodd223): the outline panel now collapses nested headings, and Settings → "Outline side" puts it on the left or right.
  • External file change watcher (#24, @beihai23): edit a file outside SoloMD and the editor notices — preview mode auto-reloads, edit mode pops a "reload vs keep" dialog. Coordinated with v3.0 GitHub sync so a pull doesn't fire the dialog per file (suppression window covers the rewrite).

The shape of "sync" we picked, vs. the shape we didn't

SoloMD v3.0 (GitHub-backed)Obsidian SynciCloud-only
Where data livesYour GitHub accountObsidian's serversApple's servers
CostFree (or your existing GitHub plan)$96 / yrFree up to 5 GB
End-to-end encrypted✅ optional, opt-in✅ optional❌ (Apple holds keys)
Conflict resolutionPer-file UIPer-file UI"Keep both" rename
Version historyFull git log per file1 year30 days
Multi-providerGitHub / GitLab / Gitea / customObsidian onlyApple only
Subscription requiredNoYesPast 5 GB

What didn't change

Everything else about SoloMD is the same as v2.5: local-first plain .md files, ~15 MB installer, all 14 AI providers BYOK, MCP server bundled, AutoGit per-note history, semantic search, WYSIWYG live edit, slash commands, theme marketplace, CJK proofread. v3.0 adds an optional sync layer on top — turn it off and SoloMD is still the editor you've been using.

Thanks @beihai23, @ZHTodd223, and everyone in the GitHub Discussions for the v3.0 cycle. Bug reports + ideas → issues.

Comments & feedback

Comments live on GitHub Discussions — sign in once with your GitHub account.

Comments load from GitHub Discussions. If you see this message instead, the maintainer has not finished the one-time giscus.app setup yet — see web/COMMUNITY-SETUP.md.

Open on GitHub Discussions →