Skip to main content

Embedding Ghostty

This guide walks through the process of embedding libghostty into your application. We’ll build a minimal terminal emulator from scratch.
The libghostty embedding API is currently only used by the macOS app and is not yet a general-purpose API. Expect breaking changes.

Prerequisites

Before embedding libghostty, you’ll need:
  • C compiler with C11 support
  • Platform-specific development tools (Xcode for macOS, GTK for Linux)
  • libghostty headers and library
  • Basic understanding of your platform’s UI framework

Build System Integration

1

Link libghostty

Add libghostty to your build system:CMake:
Xcode:
zig build:
2

Include headers

Include the main header in your source files:

Implementation Steps

1

Initialize global state

Call ghostty_init() once at application startup:
This initializes internal allocators, logging, and other global state.
2

Create and configure settings

Create a configuration object and load settings:
3

Implement runtime callbacks

Implement the callback functions that libghostty will use to communicate with your app:
4

Create the app instance

Create the main ghostty app with your callbacks:
5

Create a terminal surface

Create a surface for rendering the terminal:
6

Handle input events

Forward keyboard and mouse events to the surface:
7

Integrate with render loop

Call libghostty functions in your render loop:
8

Clean up on exit

Free all resources when the app exits:

Complete Example

Here’s a complete minimal example for macOS:

Next Steps

Troubleshooting

Surface doesn’t render

Make sure you’re calling:
  • ghostty_app_tick() regularly (at least once per frame)
  • ghostty_surface_draw() when rendering
  • ghostty_surface_set_size() after surface creation and on resize

Input not working

Verify that:
  • You’re correctly converting platform keycodes to ghostty_input_key_e
  • Modifier keys are properly mapped to ghostty_input_mods_e
  • The surface has focus via ghostty_surface_set_focus(surface, true)

Memory leaks

Ensure you’re freeing all resources: