Native Windows port of the Ghostty terminal emulator.
Status
Β·
Building
Β·
Shortcuts
Β·
Configuration
Β·
Upstream Docs
This is a fork of Ghostty that adds native Windows support via a Win32 application runtime. It runs as a standalone .exe β no WSL, no Cygwin, no compatibility layers.
The goal is to track the upstream main branch while maintaining a native Windows port that leverages Ghostty's cross-platform core (terminal emulation, renderer, font system).
Upstream Ghostty supports Linux (GTK) and macOS natively. This fork adds a
win32application runtime alongside those existing backends. See the upstream repository for the original project.
Feature-complete β 100% apprt action coverage (66/66 actions handled), synced with upstream main. The terminal is ready for daily use.
Terminal
- Full VT sequence support with OpenGL 4.6 rendering (WGL)
- FreeType + HarfBuzz fonts with DirectWrite system font discovery
- ConPTY shell spawning (cmd.exe, PowerShell, WSL)
- Win32 Input Mode (mode 9001) for full Unicode through ConPTY
- IME support for CJK input (Japanese, Chinese, Korean) with the composition (preedit) rendered inline at the cursor and the candidate window anchored to it
- AltGr layouts (German, Polish, β¦) encode correctly
- Per-monitor DPI awareness, window resize with grid reflow
- 463 built-in color themes (same as macOS)
Windows & Tabs
- Multiple windows, tabbed interface with custom GDI tab bar
- Tab drag-and-drop reorder, inline rename (double-click), right-click context menu
- Close tab modes: current, all others, all to the right
Split Panes
- Split right/down/left/up, navigate between panes
- Mouse drag to resize dividers, double-click to equalize
- Toggle split zoom, equalize all splits
- Independent split tree per tab
Security
- Paste protection: unsafe/multi-line pastes prompt before reaching the
shell (
clipboard-paste-protection) - OSC 52 clipboard read/write authorization prompts
(
clipboard-read/clipboard-write = ask)
Extras
- Command palette with filterable actions, keybinding hints, and
user-defined entries (
command-palette-entry) - Right-click context menu on the terminal (Copy / Paste / Select All / Split / Reset)
- Taskbar progress for OSC 9;4 progress reports (
ITaskbarList3) - Global hotkeys for any
global:-flagged keybind (not just the quick terminal) window-themehonored for the title bar (dark / light / system / auto)- Background blur (acrylic-style) behind translucent windows
(
background-blurwithbackground-opacity < 1) - Resize overlay showing columns Γ rows while resizing (
resize-overlay) - Hovered-URL preview bubble (browser-style, bottom-left)
- Search bar match counter ("3/17")
- Command-finished notifications (
notify-on-command-finish*): bell and/or a desktop notification with duration and exit code - Desktop notifications are click-to-focus (raise the originating tab)
- X1/X2 (back/forward) mouse buttons delivered to the terminal
window-decoration = none(borderless) andwindow-position-x/y- Renderer occlusion: hidden tabs, zoomed-out splits, and minimized windows stop rendering (saves GPU/CPU/battery)
- Quick terminal (slide-in/out from screen edge with global hotkey)
- Find-in-terminal search bar
- URL detection with Ctrl+click to open in browser
- Desktop notifications (OSC 9, OSC 777)
- Background opacity, fullscreen, window decorations toggle
- Font size zoom with inheritance to new tabs/splits
- Config hot-reload, scrollbar
- DWM dark/light chrome and Win11 22H2+ caption color matching the configured background
- Shell integration for PowerShell (prompt marking, CWD, title)
- Drag a file from Explorer onto the terminal to paste its path
- Visual bell (taskbar flash) when BEL fires on an unfocused window
- Taskbar flash when a command exits non-zero in an unfocused window
- Confirm-close dialog when a programmatic close hits a tab with a running command
- Auto-update check against GitHub releases (rate-limited to once per hour); clicking the "Update available" balloon opens the releases page in your browser
- Horizontal scroll wheels / trackpad gestures (
WM_MOUSEHWHEEL)
- Inspector (debug overlay) β acknowledged but no Win32 UI yet
undo/redoβ macOS NSUndoManager only, no Win32 equivalentsecure_inputβ macOS EnableSecureEventInput only- Release build + installer (MSI/MSIX) β not yet packaged
Requires Zig 0.16.0.
zig build -Dapp-runtime=win32 -Dtarget=x86_64-windows-gnuThe executable is at zig-out/bin/ghostty.exe. Building with the native
Windows Zig toolchain is the most reliable path and is also the
authoritative compile check.
The -Dtarget=x86_64-windows-gnu flag matters even on Windows: with the
GNU ABI Zig provides its own bundled libc (MinGW), whereas omitting the
target selects the MSVC ABI, which requires an installed Visual Studio /
Windows SDK and otherwise fails every C dependency with
error: failed to find libc installation: WindowsSdkNotFound.
To replace a ghostty.exe that is currently running, rename the old file
aside first β Windows write-locks a running executable against overwrite
but still allows it to be renamed.
The same command works from Linux with the GNU ABI target
(x86_64-windows-gnu β the plain x86_64-windows target selects the MSVC
ABI, which cannot cross-compile from Linux because it lacks the MSVC
headers).
On WSL, drop the Windows entries from PATH before building:
export PATH=$(echo "$PATH" | tr ':' '\n' | grep -v '^/mnt/c' | paste -sd:)WSL appends the Windows PATH by default, and one of its entries
(/mnt/c/Windows/system32/config/systemprofile/AppData/Local/Microsoft/WindowsApps)
is unreadable from Linux. Zig probes PATH for a system cc and reports
the resulting EACCES as a bare error: AccessDenied with no indication
of which file it came from. With the Windows entries removed, the full
ghostty.exe cross-links and zig build test -Dapp-runtime=win32 runs the
test suite through WSL interop.
One test, Command: custom env vars, fails under WSL interop because it
spawns cmd.exe with a minimal environment block; it passes on Windows CI.
zig build -Dapp-runtime=win32 -Dtarget=x86_64-windows-gnu -Doptimize=ReleaseFastTo debug a release build with stderr visible, add -Dwindows-console=true
β it links against /SUBSYSTEM:CONSOLE instead of the default Windows
GUI subsystem so the process gets a console attached.
All keybindings are configurable via the keybind config option. These are the defaults:
| Action | Shortcut |
|---|---|
| New window | Ctrl+Shift+N |
| Close surface (tab/pane) | Ctrl+Shift+W |
| Close window | Ctrl+Shift+Q |
| Toggle fullscreen | Ctrl+Enter |
| Command palette | Ctrl+Shift+P |
| Open config file | Ctrl+, |
| Reload config | Ctrl+Shift+, |
| Quit | Ctrl+Shift+Q |
| Action | Shortcut |
|---|---|
| New tab | Ctrl+Shift+T |
| Next tab | Ctrl+Page Down |
| Previous tab | Ctrl+Page Up |
| Go to tab 1β8 | Ctrl+1 β Ctrl+8 |
| Go to last tab | Ctrl+9 |
| Move tab left | Ctrl+Shift+Page Up |
| Move tab right | Ctrl+Shift+Page Down |
| Drag reorder | Mouse drag on tab |
| Rename tab | Double-click tab |
| Tab context menu | Right-click tab |
| Action | Shortcut |
|---|---|
| Split right | Ctrl+Shift+O |
| Split down | Ctrl+Shift+E |
| Focus next pane | Ctrl+Shift+] |
| Focus previous pane | Ctrl+Shift+[ |
| Equalize splits | Configurable (equalize_splits) |
| Toggle split zoom | Configurable (toggle_split_zoom) |
| Resize split | Mouse drag on divider |
| Equalize split | Double-click divider |
| Action | Shortcut |
|---|---|
| Copy | Ctrl+Shift+C |
| Paste | Ctrl+Shift+V |
| Select all | Ctrl+Shift+A |
| Find | Ctrl+Shift+F |
| Find next | Enter (in search bar) |
| Find previous | Shift+Enter (in search bar) |
| Close search | Escape |
| Action | Shortcut |
|---|---|
| Increase font size | Ctrl+= |
| Decrease font size | Ctrl+- |
| Reset font size | Ctrl+0 |
| Action | Gesture |
|---|---|
| Vertical scroll | Mouse wheel |
| Horizontal scroll | Trackpad swipe / horizontal wheel |
| Drag-select | Left-click drag |
| Open URL | Ctrl+Click on a detected URL |
| Middle-click paste | Middle button (configurable via middle-click-action) |
| Drop file | Drag a file from Explorer onto the terminal β its path is pasted |
The quick terminal requires a keybinding in your config:
keybind = global:ctrl+grave_accent=toggle_quick_terminal
The global: prefix makes it work system-wide, even when Ghostty isn't focused.
Ghostty reads its config file from %LOCALAPPDATA%\ghostty\config (or %XDG_CONFIG_HOME%\ghostty\config if set). Example:
# Font
font-family = JetBrains Mono
font-size = 14
# Colors
background = #1e1e2e
foreground = #cdd6f4
# Shell
command = powershell.exe
# Behavior
quit-after-last-window-closed = true
# Quick terminal (global hotkey)
keybind = global:ctrl+grave_accent=toggle_quick_terminal
See the upstream documentation for the full list of config options. Most settings work on Windows β the exceptions are platform-specific options (GTK, macOS).
The Windows port adds a win32 application runtime (src/apprt/win32/) alongside the existing GTK (Linux) and AppKit (macOS) runtimes. It reuses Ghostty's cross-platform core:
- Terminal emulation: Shared VT parser, screen, scrollback (
src/terminal/) - Rendering: OpenGL 4.3+ with WGL context management (
src/renderer/) - Fonts: FreeType rasterization + HarfBuzz shaping + DirectWrite discovery (
src/font/) - PTY: Windows ConPTY via
CreatePseudoConsole(src/pty.zig) - I/O: libxev with IOCP backend (
src/termio/)
src/apprt/win32/
App.zig β Win32 message loop, window classes, action dispatch
Window.zig β Top-level container HWND, tab bar, splits, tab lifecycle
Surface.zig β WS_CHILD HWND, WGL context, input, clipboard, search, command palette
QuickTerminal.zig β Quick terminal popup with slide animation
win32.zig β Win32 API type definitions and extern declarations
src/shell-integration/powershell/
ghostty-shell-integration.ps1 β PowerShell prompt marking, CWD, title
A test harness runs from WSL2 using PowerShell automation:
bash test/win32/ghostty_test.sh all25+ automated tests cover: launch/close, window properties, keyboard input, multiple windows, clipboard, config loading, scrollbar, close confirmation, URL detection, notifications, window sizing, window resize (real assertion), search bar, config reload, tabs (new/switch/close), opacity, command palette, tab drag reorder, inline tab rename, split panes, font zoom, fullscreen toggle, open config, and quick terminal.
Tab and split tests run in PowerShell sessions:
powershell.exe -ExecutionPolicy Bypass -File test/win32/test_tabs.ps1 -ExePath path\to\ghostty.exe
powershell.exe -ExecutionPolicy Bypass -File test/win32/test_splits.ps1 -ExePath path\to\ghostty.exeThis fork tracks ghostty-org/ghostty main branch. To sync:
git remote add upstream https://github.com/ghostty-org/ghostty.git
git fetch upstream
git merge upstream/maingit rerere is enabled in the local repo so previously-resolved
conflict resolutions get re-applied automatically on subsequent merges.
When resolving conflicts, default to keep upstream for any file
outside src/apprt/win32/, dist/windows/, or test/win32/. The
.win32 switch arms (.none, .win32 => void and similar) need to be
preserved in upstream switches that handle apprt variants.
Files most likely to conflict on upstream merges:
src/Surface.zig,src/config/Config.zig,src/font/discovery.zig,src/font/DeferredFace.zig,src/font/backend.zig- Switch-arm files:
src/apprt/runtime.zig,src/apprt.zig,src/datastruct/split_tree.zig,src/input/Binding.zig,src/font/face.zig,src/terminal/mouse.zig
Same as upstream Ghostty β see LICENSE.