Dmitry Goncharenko4 downloadsTwo-way sync between your vault and a Google Drive folder using the Google Drive API. Works on desktop and mobile.
Two-way sync between an Obsidian vault and a folder in Google Drive, using the Google Drive API directly.
Works on Windows, macOS, Linux, Android, and iPad/iPhone, including mobile devices that can't run Google Drive for Desktop.
note (conflict YYYY-MM-DD HHmm).md..obsidian, .trash, and .git are never synced, so each device keeps its own settings and plugins.accounts.google.com and oauth2.googleapis.com: Google sign-in and refreshing access tokens.www.googleapis.com: the Google Drive API, to list, download, upload, and trash files in the folder you choose.dg0988.github.io (only during sign-in, and only if you keep the default redirect page): a static page in this repository (docs/callback.html) that hands Google's one-time sign-in code back to Obsidian through an obsidian:// link. It has no server-side code and stores nothing. You can host your own copy instead.If a device's vault already lives inside Google Drive for Desktop (e.g. G:\My Drive\...), Drive for Desktop is already syncing it. Don't also run GSync on that device against the same Drive folder, or two sync engines will fight over the same files.
A common setup:
| Device | Vault location | Sync method |
|---|---|---|
| Windows/Mac computer | Inside the Google Drive for Desktop folder | Google Drive for Desktop (GSync off, or auto-sync set to 0) |
| Android phone | Local storage | GSync |
| iPad / iPhone | On My iPad / On My iPhone | GSync |
Also disable any other sync plugin that points at the same folder.
https://dg0988.github.io/ObsidianGSync/callback.html
Copy the Client ID and Client secret.
Settings → Community plugins → Browse, search GSync, install and enable.
Install BRAT from Community plugins, then Add beta plugin → dg0988/ObsidianGSync.
Download main.js and manifest.json from the latest release into:
<your vault>/.obsidian/plugins/gsync/
Then fully restart Obsidian and enable GSync under Community plugins. (On iPad/iPhone the Files app hides .obsidian; use BRAT, or an app like a-Shell to create the folder.)
This works the same on desktop, Android, and iOS. As an alternative, you can copy a refresh token from a signed-in device (Copy refresh token) and paste it into Refresh token (manual) on another device.
Set Google Drive folder to the folder's path under My Drive, using / between folders:
Obsidian/Notes
The path must match the Drive folder's name exactly (same spelling and capitalization). If it doesn't exist, it is created.
Start a sync with any of:
First sync on mobile: keep Obsidian open and the screen on until the progress notice disappears. Mobile operating systems pause apps in the background.
| Setting | Default | Description |
|---|---|---|
| OAuth client ID / secret | — | From your Google Cloud Web application OAuth client. |
| Refresh token (manual) | — | Filled in by signing in; or paste one from another device. |
| Sign-in redirect page | https://dg0988.github.io/ObsidianGSync/callback.html |
Must exactly match an authorized redirect URI on your OAuth client. |
| Google Drive folder | Obsidian/<vault name> |
Path under My Drive. Backslashes are converted to /. |
| Auto-sync every (minutes) | 10 |
0 disables auto-sync. Only runs while Obsidian is open. |
| Sync when Obsidian starts | On | Skipped automatically if the previous sync didn't finish. |
| Sync deletions | On | Off = files deleted on one side come back on the next sync. |
| Max file size (MB) | 25 |
Larger files are skipped and listed. 0 = no limit. Use ~10 on phones. |
| Exclude | desktop.ini, Thumbs.db |
One rule per line (see below). |
| Reset sync state | — | Forgets sync history. The next sync compares every file by content; nothing is deleted. |
# comments start with #
Templates/ # a folder (prefix) and everything in it
*.exe # a file extension
desktop.ini # an exact file name, anywhere
Notes/draft.md # an exact path
Excluded files stay in Drive and on other devices; they just aren't synced to this one.
GSync remembers what each file looked like on both sides at the last sync:
| Situation | Result |
|---|---|
| Changed locally only | Uploaded |
| Changed in Drive only | Downloaded |
| Changed on both sides | Local keeps the name; Drive version saved as a (conflict …) copy |
| Deleted locally, unchanged in Drive | Moved to Drive trash |
| Deleted in Drive, unchanged locally | Moved to Obsidian trash |
| Deleted on one side, edited on the other | The edit wins; the file is restored |
| Exists on both sides, never synced before | Contents compared; identical files are left alone |
Limitations
.) are never synced.| Problem | Fix |
|---|---|
redirect_uri_mismatch |
Your OAuth client must be type Web application, with the redirect page URL added exactly as shown in GSync's settings. |
| Browser doesn't return to Obsidian | Tap Open Obsidian on the page. On Android, allow the browser to open Obsidian if asked. |
| "This sign-in link expired…" | Sign-in must finish within 15 minutes, on the same device where it started. Tap Sign in with Google again. |
"Access blocked" / access_denied |
Add your account as a test user on the consent screen, or publish the app. |
invalid_grant, or sign-in expires every ~7 days |
Publish the OAuth app to In production, then sign in again. |
Drive API 403 on first sync |
Enable the Google Drive API for your project. |
| A new, empty folder appeared in Drive | The folder path doesn't match. Check spelling and capitalization, and use / between folders. Delete the stray folder. |
| "The last sync didn't finish…" | Obsidian closed or crashed mid-sync. Progress was saved; tap Sync now to resume. |
| Obsidian crashes during the first mobile sync | Lower Max file size to 10, exclude installers and archives, and leave the app on one note until the sync finishes. |
Errors are logged to the developer console (desktop: Ctrl+Shift+I) with the prefix [gsync].
.obsidian/plugins/gsync/data.json. Never commit or share that file. The refresh token grants access to your Google Drive.https://www.googleapis.com/auth/drive) so it can see files already in your folder that it didn't create. It only reads and writes inside the folder you configure.npm install
npm run dev # watch build
npm run build # type-check + production build -> main.js
Releases are built and signed by GitHub Actions (.github/workflows/release.yml), so the published main.js has a verifiable build provenance attestation.
version in manifest.json and package.json, and add it to versions.json.1.0.3, no v). Don't attach files: the workflow builds main.js from the tagged source, attests it, and attaches main.js and manifest.json.To verify a downloaded main.js:
gh attestation verify main.js --repo dg0988/ObsidianGSync