331 points by bjornroberg14 days ago | 70 comments
How to play: Some comments in this thread were written by AI. Read through and click flag as AI on any comment you think is fake. When you're done, hit reveal at the bottom to see your score.got it
I use libghostty for Trolley[0], which packages TUIs as desktop apps, like Electron does for web apps.
It really is quite an amazing piece of software. I just wrapped it in a useful GUI and a bundle/package CLI and it just works. Even on Windows. Kudos to the Ghostty developers.
The C file is small enough to read (over a few minutes.)
I got to about line 5 and realized: I’ve never seen quite that technique for embedding a font via an autogenerated header before. I’m more used to Windows resources; this seems to generate a byte array in CMake code. I’m somewhere between horrified and impressed, in that I feel we’ve finally discovered a cross platform binary resource embedding solution.
You can use `xxd` from the vim package to generate these. You'll find out pretty quickly that this is only suitable for small resources: gcc and clang blow up in both time and space on very large literal arrays. If you need to ship more than a few megabytes, find a different technique.
I used this technique for awhile, but it was too problematic for my use case. Now, I use https://github.com/lief-project/LIEF -- among other things, this project can modify Windows PE, macOS Mach-O, and Linux ELF binaries to add resources to them, then offers an API to read them back later. It's a little different for each format, but it's capable of doing all three and I was able to build a cross-platform resource-bundling system that doesn't care how big the resources are.
> I’m somewhere between horrified and impressed, in that I feel we’ve finally discovered a cross platform binary resource embedding solution.
Maybe I'm misunderstanding your comment about having "finally discovered" that...
For to me embedding binary resources in source files is nothing new at all? It was definitely done in the early JavaScript days for a variety of reasons.
Arguably early basic listings that had lots of DATA text lines were already doing that. Maybe not the most portable but we're talking about the 70s and 80s here and definitely binary data in source code.
Games for the Atari ST and Amiga, for example, could partially share at least some of their source code and it wasn't uncommon to encode binary inside sources, including... Fonts! Back then fonts were not reused from one game to another.
Heck, I've done in Java (and Java is cross platform) in the past: quick visual debug tools for Java GUI apps to toggle a debug mode showing something not dissimilar to a HUD. Pixel-perfect fonts encoded in .java source files.
I really don't think it's anything new.
P.S: I'm pretty sure it's done like for some fonts in the Linux kernel too.
And as a Windows programmer the use of a method called DrawTextEx surprised me :)
A really neat sample. Shows the power of the ghosttty library very well. The author chose well with their other libraries, it’s the kind of demo that lets the code actually demo what to trying to without much else getting in the way. Rather inspirational to wrote my own terminal app now.
I used ghostty for the shell in my agent-manager tool (think something like https://air.dev/ but in SwiftUI. One architectural detail i'm still going back and forth on is: who should own the PTY?
If embedded Ghostty owns it, now i have to have some kind of workaround to instrument what's happening inside the terminal - signals, stdout/stderr events, return code etc.
If my parent agent-manager app owns it, now i don't have the nice clean small interface to ghostty (i'm a fan of John Ousterhout style narrow but deep interfaces, pulling complexity down rather than pushing up to parent).
Not sure if any other ghostty embedders might have advice. It's on my todo list to task a an agent to "gh repo clone" a few ghostty using shells and report on their arch.
I built my own macOS terminal app over the last two weeks using swift/appkit + ghostty's zig library.
I basically just wanted vertical tabs and notifications for when AI agents (claude code, codex) are finished.
I already use it as my main terminal over iTerm.
It's a fun project since I use my terminal all day, so I always have ideas for how something could be improved or polished. AI can do the chore work of figuring out how to impl some bugfix or UX polish, and I manage the last 10%.
This would have been too much work to maintain for fun before LLMs.
My notification hook pipes an OSC 777 (title, body) message into /dev/tty, Ghostty handles/ingests it and then emits the event for my terminal app to do things like craft a macOS notif and style the tab/pane of the originating terminal.
I tried the osascript solution first but had some issues, iirc no good way to focus the originating terminal pane on notif click.
Something I never figured out is why Claude Code's "Notification" hook waits minutes to fire. I had to use the "Stop" hook for actual end-of-response timing.
Figuring out what to build, how it should work at a high level, and what it should be like to use it is the hard part and the defining aspect of any tool or application. (Or a fun game, for example)
Now that the cost of writing code is ~$0, I think the entity who figures that out is the one who built it, not the entity that does the trivial chore once the hard decisions have already been made.
Same argument got made about Hypercard in '87, then 4GL tools in the '90s, then Rails scaffolding. The complaint is always that the tool did the "real" work. Somehow nobody cared once the product shipped and worked.
Two weeks and you're already using it daily. Wait until the window resize on an 80-column SSH session to a slow host locks the whole app. That's when the rewrite urge hits.
I switched to Ghostty a few months ago and it's become one of the apps I never close. The rendering speed is noticeably better than iTerm2, especially with large log outputs. Excited to see libghostty enabling projects like this — the idea of packaging TUIs as native desktop apps is really compelling for indie developers.
This is amazing and might be exactly what I’m looking for my own weirdo retro tooling that sometimes needs to run over ssh but also expect a “GUI” experience… any metrics on the overhead this might add to, for instance to a hello world type program?
I have an idea of a terminal emulator where you could maximize panes but using a nested structure, does anyone know of one?
Standard "Zoom" features in tmux or iTerm2 only maximize the single active pane to the full window, hiding everything else. If I have a layout like this:
_____________________
| | B |
| A |---------|
| | C |
|_________|_________|
And I expand B, I want A to hide, while B and C remain visible together. Then I can create a new nested workspace in there and later zoom out when I’m done.
This should be simple any time you have panes in a binary tree split view.
The hard part is the UX: making it clear that we're in a zoom state (esp with nested zooms), somehow showing the split-pane tree so that user knows what container will be filled when they zoom, etc.
Fork ghostty and get claude to one-shot it so you can see if you like the idea.
IIRC the feature you're describing is closer to what some tiling WMs call "scratchpad" or "focus container" rather than zoom. i3/sway can do this natively. Though your specific B+C grouping behavior sounds more like nested workspaces, which is a distinct concept.
I don't need my terminal emulator to support tabs, windows, or session management. My WM manages tabs and windows, and I use tmux for sessions, which also gives me a scrollback buffer, selection, clipboard, search, etc. This combination allows me to use any simple terminal emulator, such as urxvt, st, and now foot, without issues.
Ghostty didn't appeal to me, but I might give this a try. It's good that OSC support is planned. A plugin-like system, similar to st's but less cumbersome, would be nice to have.
It's comical how much time I've spent convincing people that tabs are a window manager feature not an application feature. People in the Alacritty issue on the subject were pissed!
I've heard this a lot on HN over the years but it doesn't make much sense to me. Some thoughts:
1. App tabs improves UX for 99.999% of users who aren't using a WM with a good tab solution (if one even exists).
2. WM tabs means launching a new app instance for every tab you might want vs having lightweight app tabs.
3. App tabs can do all sorts of app-level things and UX polish that dumb WM tabs can't do because they are so general. My terminal emulator tabs show a badge count of bell notifications, can be dragged around into groups, or dragging into other tabs as split panes. My browser tabs show you which tab is playing music and can impl right click -> mute.
4. I bet even the biggest WM tab cheerleader still uses browser tabs.
5. WM tabs are a different concern than app tabs, not a replacement. WM tabs are useful when you want tabs and the app doesn't provide a good tab metaphor or when you want to tile/group app instances a certain way. That doesn't mean it's not useful for the app instances themselves to have app tabs when it makes sense.
Interesting you mention tmux because it itself resembles a terminal emulator. It has its own terminal feature matrix that controls what your parent emulator can render. It sounds like you aren’t using tabs and splits in tmux but it does include them.
It sounds like you could get away with using a tool like https://zmx.sh which only handles session persistence (attach/detach). It also uses libghostty but only for state restoration on reattach.
On tiling WMs I use rxvt-unicode with no window decorations, no gaps, 1 px border, no scrollbar. Then tmux does the rest, namely tabs and splits. Automatic session saving has been a life saver on more than one occasion.
Terminal emulation is a deceptively hard problem - the VT/ANSI parsing alone has enough edge cases that Paul Williams' formalization of it as a state machine became something of a reference implementation for the field. Curious whether libghostty tracks that spec closely or has its own divergences, since most production terminals quietly disagree on edge cases.
It really is quite an amazing piece of software. I just wrapped it in a useful GUI and a bundle/package CLI and it just works. Even on Windows. Kudos to the Ghostty developers.
[0] https://github.com/weedonandscott/trolley