✨ Why vsync?
The Problem: You love using multiple AI vibe coding tools (Claude Code, Cursor, OpenCode, Codex...), but each tool has:
- Different directory structures for Skills, Agents, Commands, MCP servers
- Different config file formats (JSON, TOML, JSONC)
- Different environment variable syntax
Managing configurations across tools becomes a nightmare, especially for teams.
The Solution: vsync gives you one command to sync everything. Pick one tool as your source of truth, and all others stay perfectly in sync.
The Problem We Solve
| 📋 Manually copy configs between multiple vibe coding tools | ⚡ One command syncs everything automatically |
| 📂 Different directories for Skills/Agents/Commands/MCP in each tool | 🎯 One command maps to all correct paths |
| 🔥 Environment variables break during migration | 🛡️ Variables preserved safely (JSON ↔ TOML ↔ JSONC) |
| 🤷 No idea which configs are outdated or in conflict | 📊 Smart diff shows exactly what changed and why |
| ⚠️ Risky deletions, manual cleanup nightmares | ✅ Safe mode by default, Prune mode for strict mirroring |
| 🔧 Multiple tools = multiple config formats | 🎯 Transparent format conversion (preserves JSONC comments!) |
| 🐌 Copying dozens of configs manually is painfully slow | ⚡ Instant sync with parallel operations & smart caching |
Key Benefits
📚 Single Source of Truth → All tools sync from one place
🎯 Smart Diff Planning → Preview changes before applying
⚡ Safe & Prune Modes → Choose your sync strategy
🌈 Multi-Tool Support → Claude Code, Cursor, OpenCode, Codex
🗣️ Multi-Language CLI → English & 中文 (Chinese)
⚡ Performance Optimized → Parallel ops, caching, symlinks
🔗 Symlink Support → Share Skills via symlinks (optional)
How It Works
flowchart TD
A[Pick Source Tool<br/>Your source of truth] --> B[vsync reads configs<br/>Skills, MCP, Agents, Commands]
B --> C[Compare with targets<br/>Calculate differences]
C --> D[Show you the plan<br/>What will change]
D --> E{Your approval}
E -->|Yes| F[Auto-convert formats<br/>JSON → TOML → JSONC]
E -->|No| G[Cancelled]
F --> H[Write to all targets<br/>Crash-safe atomic writes]
H --> I[✅ All tools synced!]
style A fill:#e1f5ff
style I fill:#c8e6c9
style E fill:#fff9c4
The magic: Edit configs in ONE tool → Run vsync sync → ALL tools stay in sync
🎯 Features
| Skills Sync | Sync Agent Skills across all tools | ✅ v1.0 |
| MCP Sync | Sync MCP servers with security checks | ✅ v1.0 |
| Diff Planning | Preview changes before applying | ✅ v1.0 |
| Safe Mode | Add & update only, no deletions | ✅ v1.0 |
| Prune Mode | Strict mirroring with deletions | ✅ v1.0 |
| Atomic Writes | All-or-nothing file operations | ✅ v1.0 |
| Manifest Tracking | Hash-based change detection | ✅ v1.0 |
| User Layer | Global configs (~/.vsync.json) | ✅ v1.1 |
| Agents Sync | Custom AI agents | ✅ v1.1 |
| Commands Sync | Quick commands | ✅ v1.1 |
| Codex Support | Full Codex integration (TOML format) | ✅ v1.1 |
| Multi-Language | English & 中文 CLI output | ✅ v1.2 |
| Performance | Parallel operations, smart caching | ✅ v1.2 |
| Symlinks | Symbolic link support | ✅ v1.2 |
| Import/Export | Share configs between projects | ✅ v1.1 |
⚡ Quick Start
Full documentation: https://vsync.xiaominglab.com
Installation
npx @nicepkg/vsync
npm install -g @nicepkg/vsync
vsync --version
Initialize
vsync init
vsync init --user
Interactive prompts:
🚀 Welcome to vsync!
✔ Detecting existing tools...
✔ Detected: claude-code, cursor
? Which AI coding tools do you use?
◉ claude-code (detected)
◉ cursor (detected)
◯ opencode
◯ codex
? Which tool is your source of truth?
❯ claude-code
? What do you want to sync?
◉ Skills
◉ MCP
✔ Configuration created
✔ Cache directory created
✔ Manifest initialized
✅ Setup complete! Run vsync sync to start syncing
Sync Your Configs
vsync sync
vsync sync --dry-run
vsync sync --prune
Example output:
📖 Reading source (claude-code)...
✓ Found 3 skills
✓ Found 2 MCP servers
📊 Analyzing differences...
📋 Sync Plan (Safe Mode)
cursor:
CREATE:
• skill/deploy-prod
UPDATE:
• skill/git-release
• mcp/github
? Proceed with sync? (Y/n) y
✓ Sync completed in 1.2s
Real-World Usage
Scenario 1: Team Onboarding
cd my-project
vsync init
vsync sync
Scenario 2: User-Level Config Sync Across Multiple Tools
vsync init --user
vsync sync --user
Scenario 3: Migration from One Tool to Another
vsync init
vsync sync
🛠 CLI Commands
Core Commands
vsync init [--user]
vsync sync [--user] [--dry-run] [--prune]
vsync plan [--user]
vsync status [--user]
vsync list [skills|mcp] [--user]
vsync clean [name] [--user] [--from-source]
vsync import <path> [--user]
Example Workflows
1. Daily sync after updating Skills:
vim ~/.claude/skills/my-skill/SKILL.md
vsync sync
2. Preview changes before applying:
vsync plan
vsync sync
3. Strict mirror mode (delete outdated configs):
vsync sync --prune
4. Clean up a skill from all targets:
vsync clean skill/old-skill
vsync clean skill/old-skill --from-source
5. Import configs from another project:
vsync import ../other-project
📋 Configuration
.vsync.json
Project-level: <project>/.vsync.json
User-level: ~/.vsync.json
{
"version": "1.0.0",
"level": "project",
"source_tool": "claude-code",
"target_tools": ["cursor", "opencode", "codex"],
"sync_config": {
"skills": true,
"mcp": true
},
"use_symlinks_for_skills": false,
"language": "en"
}
Key Settings:
source_tool: Your source of truth (where you edit configs)
target_tools: Tools that will sync FROM the source
sync_config: What to sync (skills, mcp, agents, commands)
use_symlinks_for_skills: Use symlinks instead of copying (saves disk space)
language: CLI language - "en" or "zh" (user-level only)
Config Format Differences (Why You Need vsync)
Each vibe coding tool uses different formats AND different directory structures. vsync handles all the complexity:
Directory Structure Differences:
| Skills | .claude/skills/ | .cursor/skills/ | .opencode/skills/ | .codex/skills/ |
| Agents | .claude/agents/ | N/A | .opencode/agents/ | N/A |
| Commands | .claude/commands/ | .cursor/commands/ | .opencode/commands/ | N/A |
| MCP Config | .mcp.json | mcp.json | opencode.json(c) | config.toml |
File Format Differences:
| Format | JSON | JSON | JSONC (with comments) | TOML |
| MCP Field Name | mcpServers | mcpServers | mcp ⚠️ | mcp_servers |
| Env Var Syntax | ${VAR} | ${env:VAR} | {env:VAR} | No interpolation |
| Type Field | Not required | Not required | Required (local/remote) | Required |
Without vsync:
- ❌ Manually copy files between different directories
- ❌ Remember which tool uses which path
- ❌ Convert environment variable syntax by hand
- ❌ Often break configs or forget required fields
With vsync:
- ✅ One command → auto-syncs to all tools
- ✅ Automatic format conversion
- ✅ Skills support symlinks (optional)
Advanced Features (v1.2+)
Performance Optimizations:
- ⚡ Parallel Operations: Sync to multiple targets simultaneously
- 💾 Smart Caching: Skip unchanged configs using hash-based manifest
- 🔗 Symlink Support: Follows symbolic links correctly
- 📦 Optimized I/O: Atomic writes with fsync for crash safety
Format Intelligence:
- 🎯 TOML Support: Full Codex config.toml handling
- 💬 JSONC Preservation: Keeps comments in OpenCode configs
- 🔄 Cross-Format Variables: Converts
${VAR} ↔ ${env:VAR} ↔ {env:VAR} automatically
- 🛡️ Variable Safety: Never expands environment variables, preserves syntax
🎨 Sync Modes
Safe Mode (Default)
What it does:
- ✅ Create new items
- ✅ Update existing items
- ❌ Never deletes
vsync sync
Prune Mode
What it does:
- ✅ Create new items
- ✅ Update existing items
- ⚠️ Deletes items not in source
vsync sync --prune
Use when: You want strict mirroring (e.g., cleaning up old configs)
❓ FAQ
Q: Which tool should I use as the source?
A: We recommend Claude Code as it has the most complete feature set. However, you can use any tool as your source.
Q: Will vsync overwrite my existing configs?
A: By default, Safe Mode only creates and updates—it never deletes. Use --prune if you want strict mirroring.
Q: What happens if I edit configs directly in target tools?
A: Changes in target tools will be overwritten on the next sync. The SOURCE is your reference standard—everything syncs FROM the source. Always edit in your source tool, or use import to pull changes from another project.
Q: How do I switch my source tool?
A: Run vsync init again and choose a different source. Then sync to update all targets.
Q: Does it work with monorepos?
A: Yes! Each project can have its own .vsync.json. User-level configs (~/.vsync.json) work globally.
Q: Is it safe to commit .vsync.json to git?
A: Yes! The config file contains no secrets—only tool names and sync preferences. MCP configs with secrets should use environment variables.
Q: Can I sync in both directions?
A: vsync is one-directional (source → targets). To switch directions, re-run init and choose a different source tool.
Q: What's the difference between project-level and user-level?
A:
- Project-level (
.vsync.json): Team configs, checked into git
- User-level (
~/.vsync.json): Personal global configs, not shared
🤝 Contributing
Contributions are welcome! Here's how you can help:
- ⭐ Star this repo - Help others discover this project
- 🐛 Report bugs - Open an issue if something isn't working
- 💡 Suggest features - What would make this better for you?
- 🔧 Submit PRs - Improve code, docs, or add features
See CONTRIBUTING.md for guidelines.
Development
Want to contribute? See CONTRIBUTING.md for development setup and guidelines.
Contributors
📚 Roadmap
v1.0 (MVP) ✅ Released
v1.1 ✅ Released
v1.2 ✅ Current
v1.3 🔜 Next (Watch Mode & Automation)
v2.0 🚀 Future
📄 License
MIT © nicepkg
If this project helped you, please consider giving it a ⭐
Made with ❤️ by nicepkg