DEV Community

pookdeveloper
pookdeveloper

Posted on

πŸ”§ Integrating tmux automatically in VS Code with persistent sessions

If you use VS Code as your editor but rely on tmux as the real source of truth for your terminal sessions, it's natural to want the integrated terminal to always land in the right tmux session β€” without manual commands or duplicated sessions.

🟒 The "native" solution (the obvious one)

VS Code allows you to configure a terminal profile like this:

// "terminal.integrated.profiles.osx": {
//   "tmux-shell": {
//     "path": "tmux",
//     "args": ["new-session", "-A", "-s", "${workspaceFolderBasename}"]
//   }
// },
// "terminal.integrated.defaultProfile.osx": "tmux-shell"
Enter fullscreen mode Exit fullscreen mode

What this does well:

  • One workspace β†’ one tmux session
  • Automatic persistence via -A
  • Simple, clean configuration
  • No scripts involved

For many setups, this is good enough and elegant.


πŸ”΄ The real limitation

settings.json does not support conditional logic.

Variables like ${workspaceFolderBasename}:

  • βœ… Are expanded
  • ❌ Cannot be transformed
  • ❌ Cannot use regex
  • ❌ Cannot be grouped or normalized

Grouping multiple folders into a single session

Imagine you have several related projects and you want to work on all of them within one shared tmux session to preserve context, panes, and layouts:

fe-dashboard, fe-admin, be-api, be-auth
Enter fullscreen mode Exit fullscreen mode

With the native configuration, each folder forces its own tmux session, even if conceptually they all belong to the same "work context".

You cannot express rules like:

"If the folder starts with fe- or be-, use the work session"

This is simply not representable in VS Code's terminal configuration.


🧠 The robust solution: move the logic to the shell

VS Code injects environment variables such as VSCODE_PID and TERM_PROGRAM=vscode, which allow you to reliably detect when a terminal is launched from VS Code.

From there, the shell decides.

Example using fish:

if set -q VSCODE_PID; or test "$TERM_PROGRAM" = "vscode"
    if not set -q TMUX
        set -l folder_name (basename (pwd))

        if string match -qr "^fe-.*" -- $folder_name
            set folder_name "work"
        else if string match -qr "^be-.*" -- $folder_name
            set folder_name "work"
        else
            set folder_name "projects"
        end

        # tmux new-session -A -s $folder_name &>/dev/null
    end
end
Enter fullscreen mode Exit fullscreen mode

VS Code becomes just a launcher.

The decision-making logic lives where it belongs: the shell.


πŸš€ Practical benefits

  • Group projects by meaning, not literal folder names
  • Reuse tmux sessions even after closing VS Code
  • Avoid session duplication
  • Keep panes and layouts persistent
  • No plugins, no extensions β€” just tmux and standard environment variables

⚠️ Notes

  • Applies to the integrated terminal, not external terminals
  • VSCODE_PID is not a formal API, but it has been stable for years
  • The same pattern works in bash or zsh

If you use VS Code as your editor but tmux as your session manager, this integration removes friction and significantly improves day-to-day workflow.


πŸ‘‰ How do you manage your terminal sessions across projects?

Top comments (0)