This repository (github.com/microsoft/terminal) contains source code for multiple distinct deliverables:
| Deliverable | Description | Key Location |
|---|---|---|
| Windows Terminal | The modern tabbed terminal application (WindowsTerminal.exe) | src/cascadia/ |
| Windows Terminal Preview | Pre-release channel; same codebase, different release stream | — |
| Windows Console Host | conhost.exe — Windows' built-in console host, produced from this source | src/host/ |
| Shared components | VT parser, text buffer, and renderer libraries shared by both projects | src/terminal/, src/buffer/, src/renderer/ |
| ColorTool | Console color-scheme application utility | src/tools/ColorTool |
| Sample projects | Examples demonstrating the Windows Console APIs | samples/ |
Related external repositories:
| Repository | Purpose |
|---|---|
MicrosoftDocs/terminal | Windows Terminal user documentation |
MicrosoftDocs/Console-Docs | Windows Console API reference |
Microsoft/Cascadia-Code | Cascadia Code font shipped with Windows Terminal |
Sources: README.md43-58
Windows Terminal is a modern terminal emulator for Windows. It hosts multiple command-line processes in a tabbed, split-pane interface and combines:
StateMachine and AdaptDispatchConptyConnectionAtlasEngineTerminalPage, Pane, and CommandPaletteCascadiaSettings with profile inheritance and fragment extensionsThe core terminal control (TermControl) is a reusable WinRT component — other applications can embed it directly.
Sources: README.md192-258 src/cascadia/TerminalControl/TermControl.h46-136
conhost.exe)conhost.exe is Windows' original command-line host. Its source lives in src/host/ and provides:
Console* API implementations via ApiRoutinesCOOKED_READ_DATA, raw input, and VT input sequencesGdiEngine) and VT output (XtermEngine)The code in this repository is the actual source used to produce conhost.exe in Windows. It also builds as OpenConsole.exe, which Windows Terminal spawns to host child processes via ConPTY.
Sources: README.md201-222 src/host/
During the modernization of conhost.exe, key libraries were extracted for reuse by both projects:
| Component | Source Path | Used By |
|---|---|---|
StateMachine, AdaptDispatch | src/terminal/adapter/ | Terminal and conhost |
TextBuffer, ROW | src/buffer/out/ | Terminal and conhost |
Terminal (core emulator) | src/cascadia/TerminalCore/ | Windows Terminal |
AtlasEngine, DxRenderer | src/renderer/atlas/, src/renderer/dx/ | Windows Terminal |
GdiEngine | src/renderer/gdi/ | conhost |
XtermEngine | src/renderer/vt/ | conhost (ConPTY VT output) |
Sources: README.md230-258
Each major subsystem is documented in a child wiki page:
| Subsystem | Wiki Page | Primary Source Path |
|---|---|---|
| Core Terminal Engine | 2 | src/cascadia/TerminalCore/ |
| Terminal Control Architecture | 2.1 | src/cascadia/TerminalControl/ |
| Text Buffer System | 2.2 | src/buffer/out/ |
| VT Sequence Processing | 2.3 | src/terminal/adapter/ |
| ConPTY and VT I/O | 2.4 | src/terminal/adapter/, src/host/ |
| Console Host Architecture | 2.5 | src/host/ |
| Rendering System | 3 | src/renderer/ |
| Atlas Engine (DirectX renderer) | 3.2 | src/renderer/atlas/ |
| UI Architecture | 4 | src/cascadia/TerminalApp/ |
| Tab and Pane Management | 4.2 | src/cascadia/TerminalApp/ |
| Settings System | 5 | src/cascadia/TerminalSettingsModel/ |
| Window Management | 6 | src/cascadia/WindowsTerminal/ |
| Building and Testing | 7.1 | tools/, build/ |
Windows Terminal follows a layered architecture with clear separation between the application shell, terminal controls, emulation logic, and rendering:
Architecture Diagram: Major Components and Relationships
The architecture consists of several distinct layers:
| Layer | Key Components | Responsibility |
|---|---|---|
| Application | AppHost, AppLogic, TerminalWindow, TerminalPage | Window management, application state, tab/pane orchestration |
| Control | TermControl, ControlCore, ControlInteractivity | Terminal UI component, input handling, control lifecycle |
| Emulation | Terminal, StateMachine, AdaptDispatch, TextBuffer | VT sequence parsing, terminal state management, buffer storage |
| Rendering | Renderer, AtlasEngine, DxRenderer | Frame composition, text rendering, paint invalidation |
| Connection | ITerminalConnection, ConptyConnection, ConPTY | I/O abstraction, process hosting, PTY management |
| Settings | CascadiaSettings, Profile, ActionMap | Configuration loading, profile management, keybindings |
Sources: src/cascadia/WindowsTerminal/AppHost.cpp47-85 src/cascadia/TerminalApp/TerminalPage.cpp218-227 src/cascadia/TerminalControl/TermControl.cpp265-280 src/cascadia/TerminalControl/ControlCore.cpp68-99 src/cascadia/TerminalCore/Terminal.cpp28-56
The application layer manages the overall lifecycle of the Windows Terminal application and coordinates between multiple windows:
Application Layer Component Hierarchy
AppLogic: Singleton application state shared across all windows. Manages settings loading, global hotkeys, and window creation requests. Located at src/cascadia/TerminalApp/AppLogic.cpp122-159AppHost: Per-window host that bridges Win32 window management with XAML content. Each window gets its own AppHost instance. Defined in src/cascadia/WindowsTerminal/AppHost.cpp47-85IslandWindow: Win32 window wrapper that hosts XAML Islands via DesktopWindowXamlSource. Handles window messages, DPI changes, and system integration. Implementation at src/cascadia/WindowsTerminal/IslandWindow.cpp74-130TerminalWindow: Per-window business logic that doesn't directly interact with Win32. Coordinates between TerminalPage and AppHost.TerminalPage: Main content container that manages tabs, panes, the command palette, and action dispatch. Core implementation in src/cascadia/TerminalApp/TerminalPage.cpp218-456Sources: src/cascadia/WindowsTerminal/AppHost.cpp47-163 src/cascadia/TerminalApp/AppLogic.cpp84-159 src/cascadia/TerminalApp/TerminalPage.cpp218-295 src/cascadia/WindowsTerminal/IslandWindow.cpp74-130
The control layer provides the reusable terminal component and separates UI concerns from business logic:
Terminal Control Architecture
This three-layer design enables:
ControlCore contains no XAML dependenciesControlCore and creating a new TermControl wrapperControlCore can be tested without XAML infrastructureTermControl: XAML UserControl containing the SwapChainPanel for rendering, search box, scrollbar, and context menus. Defined in src/cascadia/TerminalControl/TermControl.h46-238ControlInteractivity: Processes keyboard, mouse, and touch input, converting them to terminal actions or VT sequences. Handles selection, hyperlink detection, and context menu requests.ControlCore: Core business logic including terminal lifecycle, connection management, rendering coordination, and settings application. No XAML dependencies. Implementation at src/cascadia/TerminalControl/ControlCore.cpp68-157The control uses throttled functions to batch UI updates and prevent flooding during high-speed output. For example, scrollbar updates are throttled to 8ms intervals via ThrottledFunc<ScrollBarUpdate> in src/cascadia/TerminalControl/TermControl.cpp374-385
Sources: src/cascadia/TerminalControl/TermControl.cpp265-468 src/cascadia/TerminalControl/ControlCore.cpp68-244 src/cascadia/TerminalControl/TermControl.h46-290 src/cascadia/TerminalControl/ControlCore.h1-56
The emulation layer implements VT100/ANSI terminal emulation:
VT Processing Pipeline
The emulation core processes output through a state machine:
Terminal::Write(): Entry point for all output data. Writes are locked with LockForWriting(). Located at src/cascadia/TerminalCore/Terminal.cpp105StateMachine: State-based parser that recognizes VT sequences character-by-character. Part of the VT parser library.OutputStateMachineEngine: Recognizes complete VT sequences and dispatches them to the appropriate handler.AdaptDispatch: Implements ITermDispatch interface, executing VT commands by calling ITerminalApi methods. Located in src/terminal/adapter/adaptDispatch.hppTerminal: Implements ITerminalApi, providing the actual terminal operations like cursor movement, text insertion, and buffer manipulation. Core implementation at src/cascadia/TerminalCore/Terminal.cpp28-56TextBuffer: Stores terminal content as a circular buffer of ROW objects, each containing OutputCell characters.The Terminal class also implements IRenderData to provide the renderer with access to the buffer, viewport, and cursor state.
Sources: src/cascadia/TerminalCore/Terminal.cpp28-56 src/cascadia/TerminalCore/Terminal.hpp54-183 src/cascadia/TerminalCore/TerminalApi.cpp1-35
The rendering system transforms the terminal buffer into visual output:
Rendering Architecture
The rendering system is designed to support multiple simultaneous render engines:
Renderer: Orchestrates the rendering process on a background thread. Queries IRenderData for buffer state, invalidates dirty regions, and calls PaintFrame() on each attached engine. Core logic in src/renderer/base/renderer.cppIRenderEngine: Abstract interface for render engines. Each engine implements methods for painting text, cursor, selection, and scrollbar.AtlasEngine: Modern Direct3D 11 renderer using instanced rendering and texture atlases for high performance. Can fall back to Direct2D for complex scenarios. Implementation at src/renderer/atlas/AtlasEngine.cppDxRenderer: Legacy renderer using DirectWrite for text shaping. Used as fallback.UiaEngine: Accessibility engine that generates UI Automation events for screen readers.The renderer uses a frame-based approach where changes accumulate in dirty regions and are painted together during the next frame. Rendering happens on a dedicated background thread to avoid blocking the UI thread during heavy output.
Sources: src/cascadia/TerminalControl/ControlCore.cpp142-154 src/renderer/base/renderer.cpp
Settings are loaded from multiple sources and layered to produce the final configuration:
Settings Loading Pipeline
Settings loading happens in src/cascadia/TerminalSettingsModel/CascadiaSettingsSerialization.cpp69-589 through several stages:
source property. Implementation in src/cascadia/TerminalSettingsModel/CascadiaSettings.cpp26-44CascadiaSettings object with resolved profilesThe ActionMap processes keybindings and commands, supporting layering where user bindings can override default bindings. Each action has arguments (e.g., NewTerminalArgs, SplitPaneArgs) defined in src/cascadia/TerminalSettingsModel/ActionArgs.h
Sources: src/cascadia/TerminalSettingsModel/CascadiaSettingsSerialization.cpp69-589 src/cascadia/TerminalSettingsModel/CascadiaSettings.cpp26-44 src/cascadia/TerminalSettingsModel/defaults.json1-66
Output Flow from Child Process to Screen
Output flows through these stages:
TerminalOutput Event: ConptyConnection raises event with data chunk. Handler at src/cascadia/TerminalControl/ControlCore.cpp340Terminal::Write(): Acquires write lock and feeds data to state machineStateMachine parses sequences, AdaptDispatch executes themTextBuffer, cursor moved, attributes changedNotifyPaintFrame()Renderer paints dirty regions via AtlasEngineOutput is throttled using ThrottledFunc mechanisms to batch updates during high-speed output. The outputIdle throttled function in src/cascadia/TerminalControl/ControlCore.cpp194-215 fires 100ms after output stops to trigger pattern updates.
Sources: src/cascadia/TerminalControl/ControlCore.cpp340 src/cascadia/TerminalCore/Terminal.cpp105 src/cascadia/TerminalControl/ControlCore.cpp194-215
Input Flow from User to Child Process
Input processing prioritizes keybindings over terminal input:
TermControlControlInteractivity checks ActionMap for matching keybindingTerminalInput::HandleKey()ITerminalConnection::WriteInput()Some keys like Ctrl+C may generate both an action and terminal input depending on context. The TerminalInput class in src/terminal/input/terminalInput.cpp handles mode-dependent behavior (e.g., application vs. normal cursor keys).
Sources: src/cascadia/TerminalControl/TermControl.cpp1-100 src/terminal/input/terminalInput.cpp
The terminal control exposes several key interfaces:
| Interface | Purpose | Implementation |
|---|---|---|
IControlSettings | Configuration for terminal appearance and behavior | TerminalSettings |
IControlAppearance | Visual settings (colors, font, background) | Various appearance objects |
ICoreSettings | Core terminal settings interface | Profile or TerminalSettings |
ICoreState | Read-only terminal state | ControlCore |
ITerminalConnection | I/O abstraction for process communication | ConptyConnection, AzureConnection |
These interfaces enable dependency inversion - higher layers depend on abstractions rather than concrete implementations. For example, ControlCore accepts an IControlSettings rather than a specific settings class, making it testable and reusable.
Sources: src/cascadia/TerminalControl/IControlSettings.idl src/cascadia/TerminalControl/ICoreState.idl src/cascadia/TerminalControl/TermControl.h46-136
The emulation layer uses these interfaces for VT processing:
| Interface | Purpose | Implementer |
|---|---|---|
ITerminalApi | Terminal operations (cursor, text, modes) | Terminal, ConhostInternalGetSet |
ITermDispatch | VT sequence execution interface | AdaptDispatch |
IRenderData | Renderer access to terminal buffer | Terminal |
ITerminalInput | Input event processing | Terminal |
The ITerminalApi abstraction allows the same VT dispatch logic (AdaptDispatch) to work with both the new Terminal class and the legacy conhost console. This is achieved through the adapter pattern where ConhostInternalGetSet adapts the console API to ITerminalApi.
Sources: src/terminal/adapter/ITerminalApi.hpp src/terminal/adapter/ITermDispatch.hpp src/cascadia/TerminalCore/Terminal.hpp54-165
Settings use a WinRT projection model where interfaces are defined in IDL:
INewContentArgs: Base for arguments to create new content (terminals, panes, etc.)NewTerminalArgs: Arguments for creating a terminal (profile, directory, commandline)ActionEventArgs: Wraps a ActionAndArgs for action dispatchProfile: Terminal profile with inheritance supportProfiles support inheritance through a parent-child system. A child profile can reference a parent using "source": "ParentName" or by GUID. The layering happens in src/cascadia/TerminalSettingsModel/CascadiaSettings.cpp26-44
Sources: src/cascadia/TerminalSettingsModel/ActionArgs.h src/cascadia/TerminalSettingsModel/CascadiaSettings.cpp26-44
Windows Terminal uses multiple processes:
Multi-Process Architecture
The separation allows:
Connection creation happens in src/cascadia/TerminalApp/TabManagement.cpp63-200 where TerminalPage::_OpenNewTab() creates a ConptyConnection that spawns OpenConsole.
Sources: src/cascadia/TerminalApp/TabManagement.cpp63-200 src/terminal/adapter/ITerminalConnection.idl
For developers looking to understand code flow, these are critical entry points:
| Entry Point | Purpose | Location |
|---|---|---|
AppHost::Initialize() | Window initialization | src/cascadia/WindowsTerminal/AppHost.cpp175-252 |
TerminalPage::Create() | Page setup | src/cascadia/TerminalApp/TerminalPage.cpp318-456 |
ControlCore::Initialize() | Terminal control init | src/cascadia/TerminalControl/ControlCore.cpp352-421 |
Terminal::Create() | Core terminal creation | src/cascadia/TerminalCore/Terminal.cpp43-56 |
Terminal::Write() | Output processing | src/cascadia/TerminalCore/Terminal.cpp105 |
CascadiaSettings::LoadAll() | Settings loading | src/cascadia/TerminalSettingsModel/CascadiaSettingsSerialization.cpp |
The initialization flow generally follows: AppHost::Initialize() → TerminalWindow::Create() → TerminalPage::Create() → tab creation → TermControl construction → ControlCore::Initialize() → Terminal::Create().
Sources: src/cascadia/WindowsTerminal/AppHost.cpp175-252 src/cascadia/TerminalApp/TerminalPage.cpp318-456 src/cascadia/TerminalControl/ControlCore.cpp352-421 src/cascadia/TerminalCore/Terminal.cpp43-56
Windows Terminal uses multiple threads for different concerns:
| Thread | Purpose | Key Components |
|---|---|---|
| UI Thread | XAML events, user interaction | TermControl, TerminalPage, XAML controls |
| Render Thread | Background rendering | Renderer, AtlasEngine |
| I/O Thread | Connection input/output | ConptyConnection event handlers |
| Throttled Func Threads | Debounced operations | Output idle, scrollbar updates |
The terminal uses til::recursive_ticket_lock for buffer access, allowing the same thread to acquire the lock multiple times. Read operations acquire a shared lock via LockForReading(), while writes acquire an exclusive lock via LockForWriting(). Lock assertion helpers _assertLocked() and _assertUnlocked() enforce correct lock usage.
Cross-thread communication happens via WinRT events and DispatcherQueue for marshaling to the UI thread. Throttled functions use til::throttled_func to batch operations, as seen in src/cascadia/TerminalControl/ControlCore.cpp194-243
Sources: src/cascadia/TerminalCore/Terminal.hpp107-112 src/cascadia/TerminalControl/ControlCore.cpp174-243
For new contributors, we recommend exploring the codebase in this order:
Terminal class (src/cascadia/TerminalCore/Terminal.cpp): Understand the core emulation logicControlCore (src/cascadia/TerminalControl/ControlCore.cpp): See how control logic integrates terminal and renderingTerminalPage (src/cascadia/TerminalApp/TerminalPage.cpp): Learn tab/pane managementTerminal::Write() through state machine to bufferCascadiaSettings loading and layeringFor more detailed guidance, see Getting Started for Contributors.
Sources: All sections above
Refresh this wiki
This wiki was recently refreshed. Please wait 4 days to refresh again.