Show HN: Shitty – fast terminal. Memory-unsafe and faster than yours

master
Branches
Tags
Go to file
Code
Open more actions menu
Folders and files
Name
Name
Last commit message
Last commit date
Latest commit
History
795 Commits
795 Commits
.github
.github
dev
dev
fonts
fonts
tests
tests
third_party
third_party
.clang-format
.clang-format
.gitignore
.gitignore
CONTRIBUTING.md
CONTRIBUTING.md
FIX.md
FIX.md
LICENSE
LICENSE
LICENSE.GPL3
LICENSE.GPL3
LICENSE.MIT
LICENSE.MIT
PLAN.md
PLAN.md
README.md
README.md
STYLE.md
STYLE.md
application.cpp
application.cpp
application.h
application.h
base64.cpp
base64.cpp
base64.h
base64.h
base64_ut.cpp
base64_ut.cpp
build
build
build.py
build.py
cell_extra_store.cpp
cell_extra_store.cpp
cell_extra_store.h
cell_extra_store.h
cell_extra_store_ut.cpp
cell_extra_store_ut.cpp
check_parser_totality.py
check_parser_totality.py
codecov.yml
codecov.yml
color.cpp
color.cpp
color.h
color.h
color_names.cpp
color_names.cpp
color_spec.cpp
color_spec.cpp
color_spec.h
color_spec.h
color_spec_ut.cpp
color_spec_ut.cpp
color_ut.cpp
color_ut.cpp
composer.cpp
composer.cpp
composer.h
composer.h
composer_ut.cpp
composer_ut.cpp
drop_target.cpp
drop_target.cpp
drop_target.h
drop_target.h
fd_redirect.cpp
fd_redirect.cpp
fd_redirect.h
fd_redirect.h
flake.lock
flake.lock
flake.nix
flake.nix
font.cpp
font.cpp
font.h
font.h
font_coretext.cpp
font_coretext.cpp
font_coretext.h
font_coretext.h
font_embedded.cpp
font_embedded.cpp
font_embedded.h
font_embedded.h
font_face.cpp
font_face.cpp
font_face.h
font_face.h
font_fontconfig.cpp
font_fontconfig.cpp
font_fontconfig.h
font_fontconfig.h
font_freetype.cpp
font_freetype.cpp
font_freetype.h
font_freetype.h
font_pack.cpp
font_pack.cpp
font_pack.h
font_pack.h
font_path.cpp
font_path.cpp
font_path.h
font_path.h
font_resolver.cpp
font_resolver.cpp
font_resolver.h
font_resolver.h
font_resolver_ut.cpp
font_resolver_ut.cpp
gdb.sh
gdb.sh
generate_font_data.py
generate_font_data.py
generate_render_shaders.py
generate_render_shaders.py
generate_utf8_dfa.py
generate_utf8_dfa.py
grapheme.cpp
grapheme.cpp
grapheme.h
grapheme.h
grapheme_ut.cpp
grapheme_ut.cpp
heap_profile.cpp
heap_profile.cpp
heap_profile.h
heap_profile.h
hex.cpp
hex.cpp
hex.h
hex.h
hex_ut.cpp
hex_ut.cpp
input_bindings.cpp
input_bindings.cpp
input_bindings.h
input_bindings.h
input_bindings_ut.cpp
input_bindings_ut.cpp
input_handler.cpp
input_handler.cpp
input_handler.h
input_handler.h
input_router.cpp
input_router.cpp
input_router.h
input_router.h
input_router_ut.cpp
input_router_ut.cpp
keyboard.cpp
keyboard.cpp
keyboard.h
keyboard.h
keyboard_ut.cpp
keyboard_ut.cpp
listener.cpp
listener.cpp
listener.h
listener.h
main.cpp
main.cpp
main_fuzz.cpp
main_fuzz.cpp
mouse_frontend.cpp
mouse_frontend.cpp
mouse_frontend.h
mouse_frontend.h
mouse_frontend_ut.cpp
mouse_frontend_ut.cpp
mouse_protocol.cpp
mouse_protocol.cpp
mouse_protocol.h
mouse_protocol.h
mouse_protocol_ut.cpp
mouse_protocol_ut.cpp
options.cpp
options.cpp
options.h
options.h
parser.cpp
parser.cpp
parser.h
parser.h
parser.rl
parser.rl
View all files
Repository files navigation
README
Contributing
License
GPL-3.0 license
MIT license
More
items
Shitty
Blazingly fast. Memory-unsafe and faster than yours.
Shitty is built for low latency, fast startup, and predictable resource use.
It keeps terminal state on the CPU and renders cells with native compute
backends: Vulkan on Linux and Metal on macOS.
Performance
100MB catted through the GUI on an Apple-silicon MacBook, every terminal
equalized first: Menlo 12pt, the same 14x28px cell, an 80×24 grid, 500
lines of scrollback. Best wall time of three runs.
Printable ASCII (the scroll path):
terminal
wall
user
throughput
shitty
0.81s
0.50s
~118 MiB/s
alacritty 0.17.0
0.96s
0.78s
~99 MiB/s
kitty 0.48.2
1.28s
0.95s
~75 MiB/s
ghostty 1.3.1
1.49s
1.60s
~64 MiB/s
Random bytes (the parser’s worst case, invalid UTF-8 throughout):
terminal
wall
user
throughput
shitty
1.88s
1.79s
~51 MiB/s
alacritty 0.17.0
3.07s
2.92s
~31 MiB/s
ghostty 1.3.1
4.63s
~7.0s
~21 MiB/s
kitty 0.48.2
–
–
–
kitty sits the random payload out: it reacts to the embedded escape junk
with title changes and bells instead of drawing. Reproduce with
dev/compare.py
, which verifies the equalized setup from
inside every terminal before measuring anything.
Features
VT52 through VT5xx controls and widely used xterm extensions.
Primary and alternate screens, primary-screen scrollback, margins, tabs,
rectangular operations, protected cells, and synchronized output.
Reflow of primary-screen scrollback when the terminal width changes.
Unicode grapheme clusters, combining characters, emoji sequences, and
double-width characters.
DEC single-width, double-width, and double-height lines.
16-colour, 256-colour, and 24-bit colour, including underline colour and
extended underline styles.
Legacy, modifyOtherKeys, and Kitty keyboard protocols.
X10, VT200, UTF-8, SGR, SGR-pixel, and urxvt mouse protocols.
Linear and rectangular selection, primary selection, clipboard integration,
OSC 52 policy, and OSC 8 hyperlinks.
Shell integration, notifications, progress reports, and in-band resize
reporting.
Lazy glyph rasterization, a persistent GPU glyph cache, and damage-driven
compute rendering.
Shitty uses UTF-8 internally and exports
TERM=xterm-256color
to child
processes. The host must provide the corresponding terminfo entry.
Requirements
Shitty is written in C++23 and built with Clang. Every build requires:
Python 3 and
glslangValidator
;
librsvg (
rsvg-convert
), which renders the icon at build time;
pkg-config;
Brotli and utf8proc;
POSIX threads and PTY support.
The exact
libstd
revision used by Shitty is bundled in
third_party/libstd
and built as part of the same graph.
Linux additionally requires FreeType, HarfBuzz, Wayland client headers,
xkbcommon,
wayland-scanner
, and Vulkan headers and loader. macOS requires
SPIRV-Cross and uses CoreText, Cocoa, Metal, and IOSurface from the system SDK.
A scalar Base64 implementation is always available. If simdutf 6.5 or newer
is installed, the build uses it automatically to accelerate Base64 encoding.
Fontconfig is also optional. When present, it enables font-family lookup;
explicit font file paths are handled directly through FreeType.
Linux requires a working Vulkan driver and Wayland compositor at runtime.
macOS uses the native Metal driver. The native window and event-loop layer is
built from
third_party/plt
; the terminal does not depend on a generic
windowing toolkit.
The complete imported conformance suite additionally needs ncurses and Perl.
Build
Build the default
install
group:
./build
Common build options:
./build -j 8
./build -B .build-debug
CPPFLAGS=-DDEBUG ./build
Run
Start the default shell:
./st
Run a command:
./st -e tmux new-session
Choose the initial terminal size and scrollback capacity:
./st -geometry 120×36 -saveLines 5000
Choose fonts:
./st -font
‘
DejaVu Sans Mono
‘
-fontsize 16
./st -font
‘
DejaVu Sans Mono
‘
-dwfont
‘
Noto Sans Mono CJK JP
‘
-font
and
-dwfont
accept explicit font file paths. When Fontconfig is
available, they also accept family queries and Shitty resolves regular, bold,
italic, and bold-italic faces automatically. An optional double-width font is
used only when its cell is exactly twice as wide as the primary font at the
same height.
Use
./st -v
to print the build version without opening a window,
./st -help
for the main option list, and
./st -listres
for advanced
terminal, colour, clipboard, and window-policy options. Boolean flags use
-flag
to enable and
+flag
to disable.
SHITTY_FONT_SIZE
sets the default
font size;
-fontsize
takes precedence.
During a session,
Ctrl+Shift++
increases the font size,
Ctrl+-
decreases
it, and
Ctrl+0
restores the startup size. Font resizing preserves the
terminal’s rows and columns by resizing the window to the new cell dimensions.
By default, applications cannot read local selections through OSC 52 and
cannot manipulate or query the host window. These operations can be enabled
explicitly for trusted applications.
Install
The executable is named
st
; the desktop application and icon are named
shitty
:
install -Dm755 ./st /usr/local/bin/st
install -Dm644 shitty.desktop \
/usr/local/share/applications/shitty.desktop
install -Dm644 shitty.svg \
/usr/local/share/icons/hicolor/scalable/apps/shitty.svg
Exec=st
is resolved through
PATH
, while
Icon=shitty
is resolved through
the active icon theme.
Nix
A flake provides the
shitty
package and a development shell:
nix build
#
./result/bin/st
nix run
#
run st directly
nix develop
#
clang toolchain + build dependencies
Add the package to a NixOS system from the flake overlay or via:
{
inputs
.
shitty
.
url
=
“github:pg83/shitty”
;
# …
environment
.
systemPackages
=
[
inputs
.
shitty
.
packages
.
${
system
}
.
default
]
;
}
shell.nix
remains available for
nix-shell
without flakes.
Tests
Run the full native and imported conformance suite:
./build
test
Run only the native black-box suite:
./build test_suite
Run the same normal and sanitizer chains as GitHub CI:
nix build -L –no-link .
#
checks.x86_64-linux.build &&
nix build -L –no-link .
#
checks.x86_64-linux.tests
nix build -L –no-link .
#
checks.x86_64-linux.build-asan &&
nix build -L –no-link .
#
checks.x86_64-linux.tests-asan
nix build -L –no-link .
#
checks.x86_64-linux.build-ubsan &&
nix build -L –no-link .
#
checks.x86_64-linux.tests-ubsan
Build an instrumented copy of the complete suite and generate LCOV, text, and
browsable HTML reports:
nix build -L -o result-coverage .
#
checks.x86_64-linux.coverage
xdg-open result-coverage/html/index.html
The same report is attached to every GitHub coverage run and uploaded to
Codecov for per-file and pull-request coverage.
The native suite drives a dedicated headless
st_test
binary through a real
raw PTY and checks externally visible terminal snapshots and output. The
production
st
binary does not expose the test control entry point.
Known limits
Shitty does not currently implement bidirectional text layout or inline
graphics protocols such as sixel. Some historical DEC and xterm extensions
are intentionally outside the supported profile.
License transition and authorship
Shitty is a hard fork and complete rewrite of
Zutty
. The original Zutty
terminal emulator was created by
Tom Szilagyi
. Shitty keeps that lineage,
but replaces the architecture, renderer, platform integration, testing
strategy, and project identity.
Shitty is moving from the imported GPL baseline to an MIT-only codebase. It
does not intend to retain the GPL as the final project license.
The source snapshot first imported into this repository, and code predating
that snapshot, remains licensed under GPLv3-or-later. New Shitty contributions
are dual-licensed under GPLv3-or-later and MIT. While GPL-only imported material
remains in the tree, distribution of the combined work is still subject to
the GPL.
See
LICENSE
,
LICENSE.GPL3
,
LICENSE.MIT
, and
CONTRIBUTING.md
for the
exact terms and contribution policy.
Tom Szilagyi is the original author of Zutty, from which Shitty descends.
Shitty retains his copyright notices where historical code lineage requires
them; subsequent work is copyright of the Shitty contributors.
About
A serious terminal emulator with a stupid name
Resources
Readme
License and 2 other licenses found
Contributing
Contributing
Activity
Stars
62
stars
Watchers
0
watching
Forks
8
forks
Report repository
Releases
Packages
Contributors
Languages