01The question
Claude Code comes as a command in the terminal, a desktop app, an extension in VS Code and a page at claude.ai/code. The desktop app can open a project folder on your laptop. The web version can only work on a repository it gets from GitHub. And a plain chat on claude.ai runs commands too, somewhere that isn't your laptop at all.
A tempting explanation is the browser: a web page can't read your disk (Why the browser needs an API), so the web version can't either. It is a reasonable guess, and it is wrong. To see why, take these products apart into what they are made of.
02Three layers, and the app is only one
Every one of them has the same three parts. The model reads text and writes text, and nothing else: it can't run anything, and it remembers nothing from one call to the next (The harness is a program on your machine). The is the loop that makes it an agent: send the conversation and a list of tools, get back a , run it, send the result, and go round until the model says it is done. Permissions, CLAUDE.md, hooks and the squeezing of a long conversation all live here. The interface shows you the loop: it draws the messages, takes what you type and puts up the buttons to approve. It decides nothing.
So the products differ mostly in their interface. Typing claude starts the harness with a full-screen interface in the terminal. claude -p "fix the lint errors" starts the same loop with no interface at all, printing its answer for a script to read: that is its mode. The Agent SDK is the harness as a library for TypeScript or Python: it runs the Claude Code program underneath and passes its messages back as JSON.
The desktop app works the same way. On a Mac, its Code tab starts a copy of the claude program that it keeps in its own folder, with --input-format stream-json --output-format stream-json: messages go in and out as lines of JSON, and the app draws them.
Claude Code is the harness. The terminal, the desktop app and VS Code are different windows onto it.
03Where the loop runs decides what it sees
If the interface decides nothing, what makes the web version different? Where the harness runs. A harness reads files on the machine it runs on, as any program does, so that machine's disk is what it can see.
- Harness runs on
- Your laptop, as a program of yours
- Lid shut
- Stops
Claude Code on the web doesn't run in your browser. The tab only shows a loop running in a virtual machine on Anthropic's servers. That machine starts empty, and your code has to be carried to it: cloned from GitHub, or packed up and uploaded from your laptop by claude --cloud. Even if the browser could read your whole disk, the harness would be on another computer.
The desktop app is a native program, not a page, so it may start programs on your laptop. For a local session it starts the harness there, and that harness sees the folder you pick. For a cloud session it asks for a machine in the cloud, as the web does: the same window, two places for the loop. A chat on claude.ai is a third arrangement. Its harness runs in the cloud, and if you link the chat to your laptop through the desktop app, the app runs commands there on the harness's behalf.
Two questions place any of them, including ones that don't exist yet:
- Where does the loop run? That decides which files it sees, and whether it keeps going when your laptop sleeps.
- How does the code get there? Either it is already on that machine, or it is cloned or uploaded in.
A harness on your laptop has your real files and stops when the lid shuts. A harness in the cloud has only what was carried there, and keeps going while you're away.
04What stands round it
Where the loop runs also decides what stands between it and everything else. On your laptop, not much. claude in a terminal is an ordinary running as you, with your permissions. It asks before it runs commands because no wall is in the way: your approval is the check. Its optional sandbox adds rules from the operating system round the commands it runs (Seatbelt on a Mac, bubblewrap on Linux), limiting the files and network they can reach. That still isn't a container or a virtual machine.
In the cloud, the machine is shared with strangers, and every sandbox on it runs code nobody reviewed: commands a model wrote, packages from npm, scripts from someone's repository. The usual way to fence code off is a : an ordinary process that the Linux gives a private view, through (its own list of processes, its own network, its own files from an ), and a budget, through (so much memory, so much CPU). From the host, it is one more process in the list.
- To reach the other
- One bug in the kernel they share.
- Starts
- About as fast as a process
That is enough for code you trust, and thin for code you don't, because every container on the server shares one kernel. The kernel is huge, with hundreds of system calls and a long history of bugs, and one exploited bug can let a tenant out to the host and to everyone else on it. A gives each tenant a kernel of its own, so getting out means getting through that kernel and then through the , which offers only a few simple virtual devices. A full virtual machine pretends to be a whole PC, firmware and all, and is slow to boot. A keeps the separate kernel and drops the rest. Firecracker, which AWS built for Lambda, boots one in under 125 ms with under 5 MiB of overhead.
That is what a chat's workspace on claude.ai turns out to be, though everyone calls it a container. From inside, ps shows kthreadd, the kernel's own thread manager, which a container never sees, and the kernel's version points to Firecracker. For cloud Claude Code sessions Anthropic says only that each runs in an isolated virtual machine.
A container is a process with blinkers and a budget. When strangers' code shares the hardware, each gets a kernel of its own, and a microVM is the cheapest way to give it one.
05What lasts, and where it is kept
One more thing follows from the harness living on a machine: the machine can go. A cloud workspace is shut down once it has sat idle a while, and its processor and memory go back to the pool for someone else. Yet you can come back to the conversation days later and carry on as if nothing happened. That works because the conversation was never in the machine.
The model remembers nothing, so the harness sends the whole conversation on every turn, read from Anthropic's database. The machine holds only the working files and the programs running on them. So there are three layers, kept in three places, for three lengths of time.
- ConversationAnthropic's databaseSent to the model again, whole, every turn
- FilesThe machine's diskFiles and installed packages stay put
- Running programsThe machine's memoryStill running
Coming back boots a fresh machine. The files can come back with it, if the disk was kept or saved: a disk . Running programs don't, because they lived in memory, so a dev server left running is gone. Firecracker can save memory too and resume a machine mid-step, but a workspace that comes back with an uptime of zero minutes was booted fresh. Claude Code's docs say the same of its cloud sessions: reopened, a session gets a fresh VM, its conversation restored and its background work not.
The tools that last aren't in the machine either. Web search is run by Anthropic's API, inside the request. Connectors such as Gmail or Notion are servers elsewhere that the harness calls. Memory is a separate store kept across chats. Only the scratch work lives on the machine.
The transcript is kept, the files for a while, and running programs only as long as the machine is up.
Connected
- Note · same patternWhat is a runtime, and why can it be the weak point?
Engine, harness, environment, there for Node and PHP. Here the engine is a model, and the environment is the thing that moves between products.
- Note · same thingWhat happens when a program runs?
The harness on your laptop and the model on someone's servers, with the API between. This note moves the harness off the laptop too.
- Note · same thingHow does code reach what it needs?
Claude Code as a command on PATH, and where its files sit in
~/.claude. The skills thread here is the same rule: a harness reads the folders of the machine it runs on. - Note · same thingWhen an agent uses a browser, what is it actually doing?
Grok Bot from the other side: what its loop does in a browser. Here, the computer it does it on, shared by every Bot on an account.
- Note · same thingWhat is actually in Bun?
Its Docker thread is the image a container starts from. This note picks up what fences the container off, and when that isn't enough.
Side threads
Questions that came up once the main idea began to hold, kept as they were asked. Each opens beside the paragraph it grew from.
Terms
Checked
What the chat had wrong or only half right, against sources. The note above already says the corrected thing.
- Claude Code on the web can only get your code by cloning it from GitHub.
claude --cloudpacks up and uploads a local repository when it has no GitHub remote, or when the Claude GitHub App isn't installed on it.Claude Code docs, Use Claude Code in the cloud - Cloud Claude Code sessions run in a Firecracker microVM, the same as a claude.ai chat.Anthropic says each runs in an isolated, Anthropic-managed VM, and not which kind. The Firecracker reading was made from inside a chat's workspace.Claude Code docs, Security and isolation
- Local Claude Code has no container or VM unless you turn on its sandbox mode.Its sandbox isn't one either: it is operating-system rules round the shell commands it runs, Seatbelt on macOS and bubblewrap on Linux.Claude Code docs, Sandboxing
- The desktop app runs the harness through the Agent SDK.On a Mac its Code tab starts its own copy of the
claudeprogram with stream-json input and output, the protocol the SDK speaks. Whether it goes through the SDK library can't be seen from outside.`ps` on a Mac running Claude Code 2.1.317, 4 November 2026 - A chat's workspace can reach package registries and GitHub, and not much else.That depends on the account's and the organisation's settings, which allow full, partial or no network access.Claude docs, Agent Skills
- A microVM starts in about a second.Firecracker's figure is under 125 ms to boot, which the chat itself gave later.Firecracker