VCode home

Install VCode on a Mac with one command

Agents: claude, codex, opencode, cursor · On: desktop · beta

curl -fsSL https://fezu.dev/install | sh

Run in Terminal on a Mac, this command installs the newest signed release of VCode, starts it as a launch agent, and links it to your fezu.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 workstation on fezu.dev/account adds a join code, so the Mac links in one step, with no browser step. It also installs the VCode desktop app in ~/Applications/VCode.app (desktop-app).

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 fezu.dev/account: tap Add a workstation, pick macOS, and copy the command it shows (add-a-workstation). Paste it into Terminal on the Mac:

curl -fsSL https://fezu.dev/install | V_CODE_JOIN=<code> sh

Without a join code:

  1. 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.

  2. Run:

    curl -fsSL https://fezu.dev/install | sh
    

    To pick the port yourself:

    curl -fsSL https://fezu.dev/install | sh -s -- --port 3500
    
  3. At the end VCode opens on its login card: in the desktop app the command has just installed, else in Chrome, else Safari. The card reads Create an account or log in to connect <computer>. We send a code to your email. Type your email and click Continue, then enter the code the email brings. A new email makes a new account with 30 days of the full plan (free-trial); an email you have used logs in to your account. The Mac is linked to that account, VCode comes back signed in with the Mac in it, and the terminal prints Linked to <email> (link-this-box).

  4. Pair your phone: v-code box pair (add-a-phone).

  5. Later, type v-code in a terminal to open VCode. On a computer linked to your email it opens the desktop app signed in, or app.fezu.dev in the browser without the app. On a Mac not linked it runs v-code box link, and on one still on an older trial account it runs v-code box trial, which gets no new start link now: open VCode on a device signed in to that account.

  6. 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

You use the Mac through the app at app.fezu.dev. A release has no page of its own: opening its port in a browser shows a line that points to the app.

The same summary as on Linux, each line starting with v-code:: v-code: installing <version>, v-code: details in ~/.local/share/v-code/install.log, v-code: running on port <port>, the install counts notice (install-counts), then the link or the join. Before them the desktop app's step prints one line, such as VCode desktop app: installed <version>; a failed app step never stops the install (desktop-app). The link prints Opening VCode to connect this computer… and If it doesn't open, go to <address> on any device, and paste the code it shows here:, then Linked to <email> once you have logged in. After a join that opened the app, the box prints Opened the VCode app. On a Mac still on an older trial account, the trial's lines come instead (free-trial). With no terminal the install prints v-code: Link this box: v-code box link. When that step gives no link, as after a join or on a Mac already linked to an email, the last line is v-code: Use it in the app: https://app.fezu.dev. 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:

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.

Run again on a Mac where VCode runs, the command behaves as on Linux (install-on-linux). From Terminal, a newer release is checked once it starts, and rolled back when it does not come up. From a thread or the shell panel, VCode is never restarted, and nothing is installed: v-code: <version> is out, but this run is inside dev.v-code.server, whose restart would stop it: nothing was installed. To install it now, run the install command from a terminal outside VCode. A run there that has to restart VCode stops before it downloads anything: v-code: this is running inside dev.v-code.server (a VCode thread or its shell panel), which the install would stop part way through. Nothing was changed. Run it from Terminal on the Mac.

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.fezu.dev Where releases are read from. For tests
V_CODE_JOIN=<code> unset The join code from Add a workstation on fezu.dev/account. Never written to the env file
V_CODE_NO_ANALYTICS=1 unset Sends no install counts. See install-counts

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, and the desktop app (~/Applications/VCode.app). 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