I use Claude Code from the terminal inside VS Code.
That works well until I open a second project.
When I finish with that project, muscle memory takes over and I close VS Code with Cmd+Q. The problem is that this also closes the first window and interrupts any Claude Code session still running there.
After doing this enough times, I started looking for a way to keep Claude alive independently of VS Code.
My first attempt: screen
My first thought was GNU Screen.
I discovered it years ago on Linux, and it has helped me through plenty of long-running jobs on remote servers. It seemed like a natural fit for this problem.
I started a named session:
screen -S claude
Then I launched Claude Code inside it, closed VS Code with Cmd+Q, reopened the project, and reattached to the session.
Claude was still there.
That was the good news. The basic idea worked: the agent did not need to live and die with the editor terminal.
The terminal colors were less successful.
macOS ships an older version of Screen, so I installed a newer one with Homebrew. That improved things partially, but I still could not get the full color output from my terminal setup. Claude Code was usable, but the interface looked mostly gray.
I had solved the persistence problem, but the experience still did not feel right.
Moving to tmux
Then I remembered tmux.
I had already been using it in desktop terminal workflows for years, so I tried the same setup there. This time everything worked as I wanted: the Claude Code session survived closing VS Code, and the terminal interface kept its colors.
The workflow is simple:
- Start Claude Code inside a named tmux session.
- Close VS Code whenever needed.
- Open a terminal later and attach to the same session.
The Claude process belongs to tmux rather than the VS Code terminal, so closing the editor no longer ends the session.
The shell shortcuts
Once the setup proved reliable, I added a few shell functions:
claude-new() {
if [ -z "$1" ]; then
echo "Usage: claude-new <tmux-name>"
return 1
fi
tmux new-session -d -s "$1" "claude"
tmux attach -t "$1"
}
claude-resume() {
tmux new-session "claude -r"
}
# Attach to an existing Claude tmux session
claude-attach() {
if [ -z "$1" ]; then
echo "Usage: claude-attach <session-name>"
return 1
fi
tmux attach-session -t "$1"
}
# Kill a Claude tmux session
claude-kill() {
if [ -z "$1" ]; then
echo "Usage: claude-kill <session-name>"
return 1
fi
tmux kill-session -t "$1"
}
claude-new creates a detached tmux session, starts Claude Code inside it, and immediately attaches to it:
claude-new blog
claude-resume opens Claude’s session picker inside a new tmux session:
claude-resume
This resumes a Claude session. It does not reconnect to an existing tmux session.
If the tmux session itself is already running, I reconnect to it with claude-attach:
claude-attach blog
When I no longer need it:
claude-kill blog
And whenever I want to see what is still active:
tmux ls
A small fix for an annoying habit
This is not a complicated setup.
There is no daemon to configure, no custom Claude integration, and no need to change how I use VS Code. tmux simply gives the process a longer lifetime than the terminal window where it started.
Now I can open multiple projects, close VS Code with Cmd+Q, and return later without wondering whether I just killed an active Claude Code session.