Clone your entire GitHub/GitLab setup — personal repos and org repos — in one command.
Perfect for onboarding to a new device.
npm install -g @cj-ways/usercloneOr download a binary from Releases.
userclone cloneThe interactive wizard walks you through:
- Platform — GitHub or GitLab
- Authentication — auto-detects
ghCLI token, or OAuth device flow, or paste manually - Destination — Desktop (default) or custom path
- Folder name — "GitHub User", your display name, or custom
- Visibility — All, public only, or private only
- Scope — Everything, personal only, orgs only, or pick manually
- Structure — Separated (orgs alongside) or Grouped (everything nested)
- Summary — Review and confirm before cloning
? Which platform? GitHub
Found token from GitHub CLI (gh)
Authenticated as Saba Janelidze (@sabajanelidze)
? Where to clone? Desktop (~/Desktop)
? Folder name for your repos? Saba Janelidze
? Which repos? All repos
Fetching repos...
Found 23 personal repos, 35 repos across 3 orgs
? What to clone? Everything (23 personal + 35 from 3 orgs)
? Folder structure? Separated — orgs alongside, personal in "Saba Janelidze/"
━━ Summary ━━━━━━━━━━━━━━━━━━━
Platform: GitHub
User: Saba Janelidze (@sabajanelidze)
Path: ~/Desktop
Folder: Saba Janelidze
Repos: 58 (23 personal + 35 from 3 orgs)
Visibility: All
Structure: Separated
? Show full repo list? No
? Proceed? Yes
Orgs sit alongside the personal folder:
~/Desktop/
├── Saba Janelidze/ <- personal repos
│ ├── repo-1/
│ └── repo-2/
├── cj-ways/ <- org repos
│ └── org-repo-1/
└── another-org/
└── org-repo-2/
Everything under one folder:
~/Desktop/Saba Janelidze/
├── repo-1/ <- personal repos
├── repo-2/
├── cj-ways/ <- org repos nested inside
│ └── org-repo-1/
└── another-org/
└── org-repo-2/
Flags skip wizard steps. Provide all flags for fully non-interactive usage.
| Flag | Short | Description |
|---|---|---|
--token |
-t |
GitHub/GitLab personal access token |
--dest |
-d |
Base destination directory (legacy mode, no folder name) |
--with-orgs |
Clone repos from all orgs | |
--org |
-o |
Clone specific org(s) only (repeatable) |
--only-orgs |
Skip personal repos | |
--exclude |
-e |
Comma-separated repo names to skip |
--skip-archived |
Skip archived repos | |
--skip-forks |
Skip forked repos | |
--private-only |
Only private repos | |
--public-only |
Only public repos | |
--pick |
Interactive checkbox selection | |
--dry-run |
Preview without cloning | |
--flat |
No org grouping, everything in dest root | |
--gitlab |
Use GitLab instead of GitHub | |
--gitlab-url |
Self-hosted GitLab URL |
# Clone personal repos only (old behavior)
userclone clone --token ghp_xxx --dest ~/Desktop
# Clone everything including orgs
userclone clone --token ghp_xxx --dest ~/Desktop --with-orgs
# Only public repos from a specific org
userclone clone --token ghp_xxx --dest ~/Projects --org cj-ways --public-only
# Preview what would be cloned
userclone clone --dry-runToken is resolved in this order:
--tokenflag~/.userclone.ymlconfig file- Environment variable (
GITHUB_TOKEN/GITLAB_TOKEN) ghCLI /glabCLI (auto-detected)- OAuth Device Flow (GitHub — requires registered OAuth App)
- Manual paste (interactive prompt)
Tokens obtained interactively can be saved to ~/.userclone.yml for future use.
userclone initCreates ~/.userclone.yml:
default_dest: ~/Desktop
default_platform: github
with_orgs: false
github:
token: ghp_xxx # or set GITHUB_TOKEN env var
gitlab:
token: glpat_xxx # or set GITLAB_TOKEN env var
url: https://gitlab.com
exclude:
- dotfiles
- old-project
orgs:
my-org:
exclude:
- legacy-repoSet defaults quickly:
userclone default platform github
userclone default dest ~/Projects
userclone default with-orgs trueGitHub: repo (full control of private repositories)
GitLab: read_api (read access to the API)
MIT