Google Drive Syncer
npm install gdrive-syncerA command line tool to manage sync folders with Google Drive. Features two-way sync with local config files and legacy gdrive sync support.
Install the gdrive CLI. This tool supports both gdrive@2 and gdrive@3.
Install gdrive@3 via Homebrew:
``bash`
brew install gdrive
Setup requires Google OAuth credentials.
> Before you start: Ask your team if someone already has OAuth credentials set up for gdrive. Sharing existing credentials avoids creating duplicate Google Cloud projects and simplifies onboarding.
#### Setting up OAuth credentials
1. Go to Google Cloud Console
2. Create a new project or select existing
3. Enable the Google Drive API
4. Configure OAuth consent screen:
- For organizations (Google Workspace): Select Internal user type. This avoids the app review process and allows immediate use by your team.
- For personal accounts: Select External and add your email as a test user.
5. Create OAuth 2.0 credentials (Desktop application)
6. Add an account:
`bash`
gdrive account add
7. Enter your Client ID and Client Secret when prompted
8. Complete the OAuth flow in your browser
> Tip: If you're in an organization, using Internal OAuth consent means the app is automatically trusted for all users in your domain—no verification required.
Note: gdrive@3 does not support gdrive sync commands. Use the filesync:* commands instead.
gdrive@2 is deprecated and no longer available via Homebrew. If you have it installed, login with:
`bash`
gdrive about
`bash`
gdrive version
`bash`
npm i -g gdrive-syncer
`bash`
gdrive-syncer [command]
Run without arguments for interactive menu, or use direct commands.
| Command | Description |
|---------|-------------|
| filesync:diff [local\|global\|registered] | Show differences between local and Drive |filesync:download [local\|global\|registered]
| | Download changed files from Drive |filesync:upload [local\|global\|registered]
| | Upload changed files to Drive |filesync:init
| | Create or add to .gdrive-sync.json config |filesync:show
| | Show sync configurations |filesync:remove
| | Remove a sync from config |filesync:register
| | Register local config to global registry |filesync:unregister
| | Remove from global registry |filesync:migrate
| | Migrate legacy syncs to Files Sync format |
| Command | Description |
|---------|-------------|
| drive:search | Search files in Google Drive |drive:list
| | List contents of a folder |drive:mkdir
| | Create a directory in Drive |drive:delete
| | Delete a file/folder from Drive |
Note: These commands require gdrive@2. They are not available with gdrive@3.
| Command | Description |
|---------|-------------|
| sync:diff | Preview sync changes (dry run) |sync:upload
| | Sync local folder to Drive |sync:list
| | List active sync tasks |sync:show
| | Show sync configurations |sync:add
| | Add a new sync configuration |sync:remove
| | Remove a sync configuration |
`bash`
gdrive-syncer help
Files Sync supports two configuration locations:
| Location | File Path | Use Case |
|----------|-----------|----------|
| Local | .gdrive-sync.json (in project root) | Project-specific syncs with relative paths |~/.gdrive_syncer/env-sync.json
| Global | | Machine-wide syncs with absolute paths |
Create a .gdrive-sync.json file in your project root:
`json`
{
"syncs": [
{
"name": "env-files",
"folderId": "your-google-drive-folder-id",
"localDir": "env",
"pattern": ".env.*",
"backupDir": "backups/env"
},
{
"name": "config",
"folderId": "another-folder-id",
"localDir": "config",
"pattern": "*"
}
],
"backupDir": "gdrive-backups"
}
Global config at ~/.gdrive_syncer/env-sync.json uses absolute paths:
`json`
{
"syncs": [
{
"name": "project-a-env",
"folderId": "your-google-drive-folder-id",
"localDir": "/Users/you/projects/project-a/env",
"pattern": ".env.*",
"backupDir": "/Users/you/backups/project-a"
},
{
"name": "project-b-config",
"folderId": "another-folder-id",
"localDir": "/Users/you/projects/project-b/config",
"pattern": "*"
}
],
"backupDir": "/Users/you/gdrive-backups"
}
| Field | Description |
|-------|-------------|
| name | Unique name for the sync |folderId
| | Google Drive folder ID |localDir
| | Local directory path (relative for local config, absolute for global) |pattern
| | File pattern to sync (see Pattern Syntax) |ignore
| | Optional pattern to exclude files (see Pattern Syntax) |backupDir
| (per-sync) | Override backup directory for this sync only |backupDir
| (root) | Default backup directory (local: gdrive-backups, global: ~/gdrive-backups) |
Patterns support glob-style matching with the following features:
| Pattern | Description | Example |
|---------|-------------|---------|
| | Matches any characters | .env. matches .env.development, .env.production |?
| | Matches single character | file?.txt matches file1.txt, fileA.txt |[abc]
| | Matches specific characters | file[123].txt matches file1.txt, file2.txt |[a-z]
| | Matches character range | [0-9] matches any digit |[!abc]
| | Negated character class | [!.] matches any non-dot character |regex:
| | Raw regex (advanced) | regex:\.env\.[^.]+$ for precise matching |
#### Examples
`json
// Match all .env files
"pattern": ".env.*"
// Match .env files but exclude .template files
"pattern": ".env.*",
"ignore": "*.template"
// Match .env files without additional extensions (no dots after env name)
"pattern": ".env.[!.]*"
// Match using raw regex (excludes .env.xx.template)
"pattern": "regex:\\.env\\.[^.]+$"
// Match specific file types
"pattern": "*.[jt]s" // matches .js and .ts files
`
- Nested folder support - Recursively syncs files in subdirectories
- Multiple sync folders - Configure multiple sync pairs in one config
- Local & Global configs - Per-project or machine-wide configurations
- File patterns - Filter files by pattern (applied to filenames, not paths)
- Auto-discovery - Finds local config in current or parent directories
- Git-style diffs - Colored diff output showing changes with full paths
- Automatic backups - Creates timestamped backups before download (preserves folder structure)
- Two-way sync - Upload local changes or download from Drive
- Optional deletion - Prompts to delete orphan files/folders after sync
- Sync All - Run operations on all syncs within selected config
- Registered Local Configs - Run sync on multiple projects from anywhere
- Auto-create folders - Creates missing folders on Drive during upload
The sync compares files between local and Drive, showing:
| Status | Diff | Upload | Download |
|--------|------|--------|----------|
| Modified | Shows diff | Updates on Drive | Updates locally |
| Local only | Listed | Uploads to Drive | Prompts to delete |
| Drive only | Listed | Prompts to delete | Downloads locally |
| Empty folders | Listed | Prompts to delete | — |
Delete prompts:
- Upload: After uploading, prompts to delete files/folders on Drive that don't exist locally
- Download: After downloading, prompts to delete local files that don't exist on Drive (backup is created first)
This ensures you can keep Drive in sync with local (or vice versa) without accumulating orphan files.
Register local configs to a global registry, then run sync operations on multiple projects from any directory.
`bashRegister current project's local config
cd ~/projects/my-app
gdrive-syncer filesync:registerSuggests name from directory, stores path in global registry
Commands:
-
filesync:register - Register current local config (auto-suggests directory name)
- filesync:unregister - Remove from registry
- filesync:show - Shows registered configs with ✓/✗ statusWorkflow:
1. Go to each project directory and run
filesync:register
2. From any terminal, run filesync:diff (or upload/download)
3. Select "Registered Local Configs"
4. Multi-select which projects to sync
5. Operation runs on all selected projectsLegacy Sync Configuration (gdrive@2 only)
> Note: Legacy sync requires gdrive@2. If you have gdrive@3 installed, use Files Sync (
filesync:* commands) instead.Legacy sync uses the
gdrive sync upload command under the hood. Configuration is stored globally at:`
~/.gdrive_syncer/gdrive.config.json
`$3
1. Find your Drive folder ID
`bash
# Search for a folder
gdrive-syncer drive:search # Or list contents to find folder IDs
gdrive-syncer drive:list
`2. Add a sync configuration
`bash
gdrive-syncer sync:add
` This will prompt for:
- Local folder path (use file picker)
- Google Drive folder ID
- Unique name for the sync
3. View your configurations
`bash
gdrive-syncer sync:show
`$3
`json
{
"syncs": [
{
"name": "my-project",
"fullpath": "/Users/you/projects/my-project",
"driveId": "1ABCdefGHIjklMNOpqrSTUvwxYZ"
}
]
}
`$3
| Field | Description |
|-------|-------------|
|
name | Unique identifier for the sync |
| fullpath | Absolute path to local folder |
| driveId | Google Drive folder ID to sync with |$3
Legacy sync uses
gdrive sync upload which:
- Keeps local files (won't delete local files)
- Deletes extraneous files on Drive (files not in local)
- One-way sync: local → Drive only`bash
Preview what will change (dry run)
gdrive-syncer sync:diffActually sync to Drive
gdrive-syncer sync:uploadList gdrive's internal sync tasks
gdrive-syncer sync:list
`Migrating from Legacy Sync to Files Sync
If you have existing legacy sync configurations (
~/.gdrive_syncer/gdrive.config.json), you can migrate them to the new Files Sync format:`bash
gdrive-syncer filesync:migrate
`The migration wizard:
1. Shows all legacy syncs and lets you select which to migrate
2. For each sync, asks whether to save to Local or Global config
3. For local configs, calculates the relative path from the config location
4. Warns if the path is outside the project directory (suggests using global instead)
5. Lets you set a file pattern (default:
* for all files)
6. Shows a preview before confirming
7. Optionally removes migrated syncs from the legacy configThis is not a one-time migration—you can run it multiple times to gradually migrate syncs as needed.
Files Sync vs Legacy Sync
| Feature | Files Sync | Legacy Sync |
|---------|----------|-------------|
| gdrive version | gdrive@2 and gdrive@3 | gdrive@2 only |
| Config location | Local (
.gdrive-sync.json) or Global (~/.gdrive_syncer/env-sync.json) | ~/.gdrive_syncer/gdrive.config.json (global only) |
| Direction | Two-way (upload & download) | One-way (upload only) |
| File patterns | Supported (.env., ) | All files in folder |
| Backups | Automatic before download | None |
| Diff preview | Git-style colored diff | gdrive dry-run output |
| Multiple folders | Yes, in one config | Yes, separate entries |
| Batch operations | Sync All (within selected config) | Sync All |Examples
`bash
Interactive mode
gdrive-syncerShow help
gdrive-syncer help--- Files Sync ---
Show differences (interactive - prompts for config if both exist)
gdrive-syncer filesync:diffShow differences for local config only
gdrive-syncer filesync:diff localShow differences for global config only
gdrive-syncer filesync:diff globalShow differences for registered local configs
gdrive-syncer filesync:diff registeredDownload from Drive (with backup)
gdrive-syncer filesync:download
gdrive-syncer filesync:download localUpload to Drive
gdrive-syncer filesync:upload
gdrive-syncer filesync:upload globalUpload from all registered configs
gdrive-syncer filesync:upload registeredInitialize config (choose Local or Global)
gdrive-syncer filesync:initShow all configs (local and global)
gdrive-syncer filesync:show--- Drive Operations ---
Search files
gdrive-syncer drive:searchList folder contents
gdrive-syncer drive:listCreate directory
gdrive-syncer drive:mkdirDelete file/folder
gdrive-syncer drive:delete--- Legacy Sync ---
Preview sync (dry run)
gdrive-syncer sync:diffSync to Drive
gdrive-syncer sync:uploadShow sync config
gdrive-syncer sync:showAdd new sync
gdrive-syncer sync:add
``