vercel cli has one global login. switching accounts means vercel logout,
vercel login, pick the team again, and now the other project deploys to the
wrong place. i got tired of it.
vcx gives every account its own vercel config dir and runs the real vercel
against whichever one you picked. plain vercel follows along.
vcx profile login work
vcx profile login personal
vcx profile use work
vercel whoami # work accounttokens sit on disk as plain files. nothing is encrypted. read where the credentials live before running this on a shared box.
one line. installs bun if you don't have it, then vercel cli, then vcx.
curl -fsSL https://raw.githubusercontent.com/ApptoAI/vcx/main/install.sh | sheverything lands in ~/.vcx with its own lockfile, and vcx gets linked into
bun's bin dir. bun's global package list stays untouched. bun 1.4.0 keeps
appending duplicate entries to that list on repeat installs, and once it's
messed up nothing installs globally anymore, so the script stays out of it.
run the same line again to upgrade.
VCX_REF picks a tag, branch, or commit. VCX_INSTALL_DIR moves the
directory. you still need node 20 or newer, vercel cli runs on it.
got bun already and want it the normal way:
bun install --global vercel
bun install --global 'github:ApptoAI/vcx#v0.3.2'use the github: form, not a tarball url. bun 1.4.0 installs from a tarball
fine and then exits with unsafe name anyway.
from a clone:
git clone https://github.com/ApptoAI/vcx.git
cd vcx
bun install
bun install --global .vcx profile login personal
vcx profile login work
vcx profile listlogin opens vercel's normal browser login and saves the result under the
name you gave it. the first profile becomes active. switch with use.
vcx profile use work
vcx whoami
vercel whoami # same account. vcx points vercel's global config at the active profilealready have a token? vcx profile add work asks for it with a hidden prompt.
from a password manager:
printf '%s' "$MY_VERCEL_TOKEN" | vcx profile add work --token-stdin--token <value> works too but lands in shell history. add checks the token
with vercel whoami before saving. --no-verify skips that if you're offline.
| command | what it does |
|---|---|
vcx profile login <name> |
vercel login flow into a new profile |
vcx profile add <name> |
save an existing token |
vcx profile use <name> |
switch the active profile |
vcx profile list |
list profiles, no credentials printed |
vcx profile current |
print the active profile |
vcx profile remove <name> |
delete a profile (asks first) |
vcx profile path |
print the vcx data dir |
vcx exec -p <name> -- <args> |
run one command under another profile |
vcx <args> |
run vercel under the active profile |
one-off with a different account:
vcx exec --profile personal -- deploy
VCX_PROFILE=personal vcx whoami # same thingprofile stuff lives under vcx profile so vercel keeps its own names.
vcx list, vcx login, vcx logout, vcx rm go straight to vercel under
the active profile.
--token and --global-config are blocked because they'd bypass the profile.
call vercel directly if you need them.
each profile is a full vercel global config dir. vcx starts vercel with
--global-config <vcx data dir>/profiles/<name>
vercel reads and writes its own auth.json and config.json in there, so
login, logout, and team selection stay inside the profile. tokens never go into
child args or VERCEL_TOKEN. an inherited VERCEL_TOKEN gets dropped before
vercel starts, so a stray shell var can't hijack the account.
plain vercel follows the active profile too. on every switch vcx replaces
vercel's default global config dir with a link to the profile:
linux ~/.local/share/com.vercel.cli
macos ~/Library/Application Support/com.vercel.cli
windows %APPDATA%\xdg.data\com.vercel.cli (a junction)
XDG_DATA_HOME moves it, VCX_VERCEL_GLOBAL_DIR overrides it. if a real dir
is already there, vcx renames it to <dir>.before-vcx on the first switch and
never touches it again. removing the active profile removes the link.
vcx logout and vercel logout both log out the active profile.
project links (.vercel/project.json) are per project, not per profile. if a
project points at the wrong team, run vcx link under the right profile.
--scope passes through.
one vercel cli 59 thing. vercel whoami inside a linked project resolves the
team from that project, and an account that's not in the team gets
Not authorized. that's vercel, not vcx. run it from ~ for the plain answer.
vcx profile path prints it. with XDG_CONFIG_HOME set it's
$XDG_CONFIG_HOME/vcx everywhere. otherwise:
linux ~/.config/vcx
macos ~/Library/Application Support/vcx
windows %LOCALAPPDATA%\vcx
vcx/
profiles.json
profiles/
personal/
auth.json
config.json vercel creates this when it needs it
work/
auth.json
config.json
dirs are 0700 and credential files 0600 on linux and macos. windows
inherits from local app data.
plaintext means anything running as your user can read these. keep the dir out of git, cloud sync, logs, and support bundles. if it leaks, rotate the token.
VCX_CONFIG_DIR moves the whole thing. 0.2 migrated the old
credentials.json store on first run and deleted it.
bun install
bun run test
bun run typechecktests run against a fake vercel binary in temp dirs. they never touch your
real login. ci covers linux, macos, and windows on node 20, 22, and 24, real
github installs on bun 1.4.0, latest, and canary, and install.sh on linux
and macos.