Multiple terminals in a single VS Code tab.
A VS Code extension that renders a configurable grid of fully interactive terminal emulators inside one editor tab. Default layout is 2x2 -- switchable on the fly to any NxM arrangement. Includes a sidebar panel for planning grid launches, saving presets, and configuring per-cell startup commands.
VS Code's built-in terminal panel lives at the bottom. You can split it, but you can't mix terminals freely in the editor area as a single cohesive view. MultiTerminal solves this: one tab, N terminals, real PTYs, full xterm.js rendering -- with a sidebar to plan everything before launch.
┌────────────────────────────────────────────┐
│ Webview (single editor tab) │
│ ┌──────────────┬──────────────┐ │
│ │ xterm.js │ xterm.js │ │
│ │ terminal 1 │ terminal 2 │ │
│ ├──────────────┼──────────────┤ │
│ │ xterm.js │ xterm.js │ │
│ │ terminal 3 │ terminal 4 │ │
│ └──────────────┴──────────────┘ │
│ ▲ ▲ │
│ │ postMessage │ │
│ ▼ ▼ │
│ ┌─────────────────────────────┐ │
│ │ Extension Host │ │
│ │ spawns bridge processes │ │
│ └──────┬──────────────┬───────┘ │
│ │ stdio/JSON │ │
│ ▼ ▼ │
│ ┌────────────┐ ┌────────────┐ │
│ │ bridge.js │ │ bridge.js │ ... │
│ │ (node-pty) │ │ (node-pty) │ │
│ └────────────┘ └────────────┘ │
└────────────────────────────────────────────┘
Each terminal cell in the webview communicates with a dedicated bridge process running under system Node.js. The bridge uses node-pty to spawn a real pseudo-terminal, so every shell feature works: colors, cursor movement, tab completion, interactive programs (vim, top, htop, etc.).
The bridge speaks a simple JSON-over-stdio protocol with the extension host, which relays data to/from the webview via postMessage.
- Single-tab grid -- 2x2 by default, switchable to 1x1, 2x1, 1x2, 3x2, 2x3, 3x3 or beyond
- Real PTYs -- each terminal is backed by
node-pty, not a subprocess pipe. Full interactive shell support - xterm.js rendering -- the same terminal engine VS Code uses internally, with web links addon and fit addon
- Sidebar planner -- dedicated activity bar icon with a webview panel to configure and launch grids
- Grid preview -- visual NxM preview in the sidebar before launching
- Startup commands -- assign a command to each cell (e.g.,
npm run dev,git log --oneline,htop) that auto-runs on launch - Presets -- save and load named configurations (layout + shell + cwd + commands)
- Shell picker -- auto-detects installed shells (zsh, bash, fish, sh)
- Directory picker -- browse and select working directory from the sidebar
- Live status -- sidebar shows active terminal count with Focus and Kill All controls
- Add/remove terminals dynamically from the grid toolbar
- Auto-resize -- terminals reflow when the panel or window resizes
- Process lifecycle -- dead processes are visually marked; close individual terminals with the X button
- Smart Node.js discovery -- finds system Node.js across fnm, nvm, homebrew, and standard paths
git clone https://github.com/YosephFr/multi-terminal.git
cd multi-terminal
npm install
npm run compileThen symlink into VS Code's extension directory:
ln -s "$(pwd)" ~/.vscode-extensions/local.multi-terminal-0.2.0
# Reload VS Code (Cmd+Shift+P > "Developer: Reload Window")On macOS, the node-pty prebuilt binary's spawn-helper may need execute permissions. The extension handles this automatically on first launch, but if you encounter issues:
chmod +x node_modules/node-pty/prebuilds/darwin-*/spawn-helperClick the MultiTerminal icon in the activity bar (left sidebar, below Extensions). The sidebar provides:
| Section | Description |
|---|---|
| Status | Shows active grid state with Focus and Kill All buttons |
| Grid Layout | Visual NxM preview with +/- controls for columns and rows (1-4) |
| Environment | Shell selector (auto-detected) and working directory picker |
| Startup Commands | Per-cell command inputs that auto-execute on grid launch |
| Launch Grid | Primary action button -- opens the configured grid in an editor tab |
| Presets | Save, load, and delete named configurations |
- Open the command palette:
Cmd+Shift+P(macOS) /Ctrl+Shift+P(Windows/Linux) - Run MultiTerminal: Open Grid
- Or use the keyboard shortcut:
Cmd+Shift+G/Ctrl+Shift+G
Once the grid is open, use the in-tab toolbar:
| Control | Action |
|---|---|
| Layout select | Choose grid dimensions (1x1 through 3x3) |
| Apply | Rebuild the grid with the selected layout |
| + Add | Append a new terminal to the current grid |
| x (cell) | Close an individual terminal and its process |
All settings are under multiTerminal.* in VS Code settings:
| Setting | Type | Default | Description |
|---|---|---|---|
multiTerminal.defaultRows |
number |
2 |
Number of rows in the default grid |
multiTerminal.defaultCols |
number |
2 |
Number of columns in the default grid |
multiTerminal.shell |
string |
"" |
Shell executable path (empty = system default) |
multi-terminal/
├── src/
│ ├── extension.ts # Extension entry point, command & sidebar registration
│ ├── TerminalPanel.ts # Webview panel lifecycle, bridge process management
│ └── SidebarProvider.ts # Activity bar sidebar with grid planner UI
├── webview/
│ └── main.js # Webview client: xterm.js grid, message handling
├── bridge/
│ └── server.js # PTY bridge: node-pty <> JSON stdio protocol
├── media/
│ └── icon.svg # Activity bar icon (2x2 terminal grid)
├── build-webview.js # esbuild config for bundling webview JS
├── package.json
└── tsconfig.json
out/-- compiled TypeScript (extension host code)dist/-- bundled webview JavaScript (xterm.js + client logic)
- VS Code 1.93+
- Node.js 18+ (for building and for the bridge process at runtime)
- macOS, Linux, or Windows (node-pty ships prebuilt binaries for all platforms)