Install VCode on a Mac with one command
curl -fsSL https://v-code.dev/install | sh, run in Terminal on a Mac,
installs the newest signed release of VCode, starts it as a launch agent, and
links it to your v-code.dev account. It works on Apple silicon and on Intel
Macs running macOS 13.5 (Ventura) or later. You need no git, node, npm or Homebrew. The command from "Add a computer"
on app.v-code.dev adds a join code, so the Mac links and pairs with that
browser in one step, with no email prompt.
Why you would use it
You want to drive the agents on your Mac from your phone. The release brings its own node and packages, starts again when it stops, and keeps itself up to date. The command is the same one Linux uses; the installer sees the Mac and sets it up with launchd instead of systemd (install-on-linux).
How to use it
The quickest way starts on app.v-code.dev: open "Add a computer", pick macOS in the list, and copy the command it shows (add-a-computer). Paste it into Terminal on the Mac:
curl -fsSL https://v-code.dev/install | V_CODE_JOIN=<code> sh
Without a join code:
Log in to the Mac as the user VCode should run as, and open Terminal on the Mac itself. An ssh session with nobody logged in at the screen has no GUI session, and a launch agent needs one.
Run:
curl -fsSL https://v-code.dev/install | shTo pick the port yourself:
curl -fsSL https://v-code.dev/install | sh -s -- --port 3500When it asks, type your v-code.dev email, then the code from the email (link-this-box).
Pair your phone:
v-code box pair(add-a-phone).For the shell panel, install tmux:
brew install tmux. VCode does not ship it on a Mac.
The installer has no screen of its own. It runs in the terminal only.
What you see
The same summary as on Linux, each line starting with v-code::
v-code: installing <version>, v-code: running at http://127.0.0.1:<port>,
the agents it found, the link or the join, and
v-code: details in ~/.local/share/v-code/install.log. The steps go to that
file; on a Mac they include one rendered ~/Library/LaunchAgents/<name>.plist
line per agent.
With no tmux on the Mac, the install says so and carries on:
warning: tmux not found, so the shell panel is off. Install it with: brew install tmux
The shell panel then shows
tmux is not installed, so there is no shell here. Install it with: brew install tmux
instead of a shell.
When VCode does not come up in time:
v-code: VCode did not answer on http://127.0.0.1:<port> within 60 s. See: <home>/Library/Logs/v-code/server.log.
When launchd refuses to load an agent after five tries, the install stops:
launchctl bootstrap gui/<uid> <home>/Library/LaunchAgents/dev.v-code.server.plist failed; see ~/.local/share/v-code/install.log.
The checks that stop the install before anything is written:
| Check | Message |
|---|---|
| Linux or macOS | VCode installs on Linux and macOS only; this machine runs <os> |
| macOS 13.5 or later | VCode needs macOS 13.5 or later; this Mac runs <version>. Update macOS in System Settings, then run this again |
| A GUI session for this user | launchd has no GUI session for this user: run this from Terminal on the Mac while logged in |
tar, gzip, ssh-keygen, head, find, readlink, ps, launchctl, sysctl |
<tool> is missing; install it and run this again |
/bin/bash |
/bin/bash is missing |
curl or wget |
curl and wget are both missing; install either one and run this again |
| bsdtar or GNU tar | VCode needs bsdtar or GNU tar; this tar is: <first line of tar --version> |
| OpenSSH 8.1 or newer | ssh-keygen has no -Y verify: VCode needs OpenSSH 8.1 or newer |
No TUNNEL_TOKEN in the env file |
the Cloudflare tunnel runs on Linux only: empty TUNNEL_TOKEN in <env file> to install VCode on macOS |
A .lock that is not the installer's |
<home>/.local/share/v-code/.lock is not a lock this script made; remove it and run this again |
A Mac as it ships passes every tool check. The checks on the release itself (signature, sha256, size, version) are the same as on Linux.
Options and settings
| Option | Default | What it changes |
|---|---|---|
--port N |
first free port from 3445 to 3499, skipping 3446 | VCODE_PORT in a new env file. An existing env file keeps its port |
--base URL |
https://dl.v-code.dev |
Where releases are read from. For tests |
V_CODE_JOIN=<code> |
unset | The join code from "Add a computer". Never written to the env file |
Where everything lives:
~/.local/share/v-code/ the releases, current, bin/v-code-update, update-state/, install.log
~/.config/v-code/env AUTH_TOKEN, VCODE_PORT and the rest (0600)
~/.local/state/v-code/ threads and the box's key
~/.local/bin/v-code, ~/.local/bin/portal the CLI
~/Library/LaunchAgents/dev.v-code.server.plist VCode
~/Library/LaunchAgents/dev.v-code.update.plist the hourly updater
~/Library/Logs/v-code/server.log what VCode prints
~/Library/Logs/v-code/update.log what the updater prints
Commands on an installed Mac:
| Command | What it does |
|---|---|
~/.local/share/v-code/current/install.sh install |
Rewrites both plists, boots the agents out of launchd and in again, prints the URL and links again. Run it after you install an agent |
~/.local/share/v-code/current/install.sh update |
Runs v-code-update --update now (update-automatically) |
~/.local/share/v-code/current/install.sh status |
One line per agent, such as dev.v-code.server: running, pid 812, runs 1, or dev.v-code.update: not loaded, then logs: <home>/Library/Logs/v-code |
~/.local/share/v-code/current/install.sh uninstall |
Boots out the updater, then VCode, removes both plists, the CLI, the releases and the updater. The env file, the state and the logs stay. While an update runs it stops: an update is running; try again when it has finished |
Limits and known gaps
- No voice.
install.sh voice,voice-browserandinstall --voicestop with<command> is Linux only for now; VCode on macOS runs without voice(--voice is Linux only for now; VCode on macOS runs without voice). - No tunnel. There is no cloudflared agent on a Mac; the install refuses an
env file with
TUNNEL_TOKENset (above). Reach the Mac through link-this-box instead. - No dev instance.
--instance devstops with--instance dev is Linux only; VCode on macOS runs the standard instance only. - No tmux. The shell panel needs
brew install tmux. Everything else works without it. - macOS 13.5 or later. The node the release brings is built for 13.5, so an older Mac is refused before anything is downloaded (above). A 2018 Mac mini can update to macOS 15.
- Logged in only. A launch agent runs while you are logged in to the Mac. It starts again at your next login, not at boot with nobody logged in. There is no linger on a Mac.
- A Mac that sleeps is offline. Your phone reaches the Mac only while it is
awake. On a Mac mini or any Mac you leave running, turn on automatic login
(System Settings, Users & Groups; FileVault must be off for it) so VCode
starts after a restart, and stop it sleeping (System Settings, Energy, or
sudo pmset -a sleep 0). The installer changes neither. - No Apple signing. The release is not signed or notarised by Apple.
curlsets no quarantine flag, so Gatekeeper does not check the node the release brings. The release is still checked against VCode's own signature. curl -fsSL … | shfrom an ssh session with nobody at the screen stops with the GUI session message above.- The installer does not install agents; install
claude,codex,opencodeorcursor-agent, then run~/.local/share/v-code/current/install.sh install.
Related
- install-on-linux — the same command on Linux, with systemd
- update-automatically — how the Mac keeps itself up to date
- add-a-computer — the command with the join code
- link-this-box — the link the installer runs at the end
- add-a-phone — the next step after linking