libghosttyとは:libghostty-vt 1.0のC ABI安定化と、CとCMakeで端末を組み込む手順

libghosttyとは:libghostty-vt 1.0のC ABI安定化と、CとCMakeで端末を組み込む手順

libghosttyは、ターミナルエミュレータGhosttyの中核にある端末処理を、他のアプリケーションへ組み込めるように切り出したC互換のライブラリです。最初に部品化されたlibghostty-vtが2026年11月6日に1.0となり、C ABIが安定版になりました。この記事では、libghostty-vtが受け持つ範囲と1.x系の互換ルール、Zig 0.17でのビルドからCMakeやpkg-configでのリンク、Cで端末を作って画面を読み出す最小コードまでを順に追います。最後に、JetBrains IDEやNeovimの採用状況を踏まえて、自社のツールに組み込むかどうかの判断に進む構成です。Ghosttyアプリ自体のキー操作や設定はGhosttyのショートカット一覧とkeybind設定で扱っています。

まとめ|libghostty-vt 1.0は端末の解析と状態管理を担うCライブラリ

2026年11月10日時点の最新版は1.0.0です。担当するのは、プログラムが出力したバイト列を解釈し、画面・カーソル・スクロールバックの状態を保つところまでです。画面の描画、PTY(疑似端末)の管理、フォントの処理は、組み込む側のアプリケーションが書きます。ライセンスはMITで、実行時の依存はlibcだけです。

1.x系の中では、古い1.xでビルドしたプログラムが新しい1.xでもそのまま動くと約束されています。端末表示を自前で作る、あるいは既存の端末部品がKittyキーボードプロトコルなどの新しい制御シーケンスに追いつかないなら、置き換え先の第一候補です。注意点はビルドにZig 0.17が必須なことと、Linux・Windows向けのビルド済みパッケージが無いことの2つです。

libghosttyとlibghostty-vtの関係と1.0で安定版になった範囲

Ghostty本体から端末処理を切り出したlibghosttyの構想と現状

GhosttyのGitHubリポジトリのREADMEは、libghosttyを「端末エミュレータを作るための、クロスプラットフォームで依存の無いCとZigのライブラリ」と説明しています。端末エミュレータを自作する用途と、既存のアプリに端末を埋め込む用途の両方が想定されています。

libghosttyは一度に公開されるのではなく、複数のライブラリに分けて順に切り出されています。最初の部品がlibghostty-vtで、Ghosttyアプリとは別のvt-X.Y.Z形式のタグで配布されます。検索で「libghostty」と書かれていても、2026年11月時点で単体の安定版として使えるのはlibghostty-vtだけだと考えてください。

libghostty-vtが受け持つ処理と、描画・PTY・フォントを含まない境界

libghostty-vtの公式ドキュメントによると、このライブラリはソフトウェアから送られたバイト列を処理し、画面・カーソル・スクロールバックといった端末の状態を公開します。入力については、キー入力を端末向けのバイト列に変換するエンコーダも含みます。

一方で、ウィンドウを開いて文字を描く処理、シェルを子プロセスとして起動するPTYの処理、フォントの読み込みと字形の組み立ては含みません。公式のサンプルも、GUIのウィンドウもPTYも使わずに動く形で書かれています。組み込む側は「バイト列を渡す」「状態を読んで自分の画面に描く」の2つを実装することになります。

CIでテストされる7系統のプラットフォームとビルド確認だけの対象

作者Mitchell Hashimoto氏による1.0の発表では、CIでテストまで実行している環境が次のように示されています。

プラットフォーム アーキテクチャ 配布物の形
Linux(glibc・musl) x86_64・aarch64 共有・静的ライブラリ
macOS 13以降 x86_64・aarch64 dylib、XCFramework
iOS 13以降 aarch64 XCFramework
FreeBSD x86_64・aarch64 共有・静的ライブラリ
Windows x86_64 DLL、インポートライブラリ
Android aarch64・x86_64・arm 16KBページ対応の共有ライブラリ
WebAssembly wasm32(freestanding) 速度優先版とサイズ優先版

Windowsのarm64、WASI、32bitのx86、illumosなどはビルドの確認だけで、テストは走っていません。

1.x系で壊さないと約束されたC ABIの互換ルールと版の確認方法

不透明ハンドルとenumキーのgetter・setterでABIを保つ設計

端末やフォーマッタといったオブジェクトは、中身を公開しない不透明なハンドルとして渡されます。値の読み書きは、enumをキーにした少数のgetterとsetterで行います。新しい設定項目が増えても、新しい関数を足さずにenumの値を増やすだけで済む作りです。

公式のStabilityのページは、マイナー版で許される変更を、新しい関数・型・enum値の追加と、サイズ付き構造体の末尾へのフィールド追加に限っています。削除、サイズ変更、並べ替え、型の変更は行いません。挙動を変えたいときは新しい名前の関数を足し、古い関数はGHOSTTY_DEPRECATEDを付けて次のメジャー版まで残します。CIではlibabigailを使って、変更がこのルールに違反していないかを検査しています。

新しいヘッダと古いライブラリの組み合わせで返るGHOSTTY_UNSUPPORTED

ヘッダより古いライブラリにリンクしてしまった場合でも、クラッシュや未定義動作にはならず、該当する呼び出しがGHOSTTY_UNSUPPORTEDを返します。ビルドフラグで検索・選択・Kitty graphicsなどの機能を外した場合も、関数自体は残り、同じ値を返します。

読み取り専用のビューアのように機能を絞ったビルドへ切り替えても、呼び出し側のコードは書き換えずに済みます。その前提として、戻り値をGHOSTTY_SUCCESSと比べる処理をすべての呼び出しに入れておきます。

GHOSTTY_VT_VERSION_AT_LEASTでビルド時に版を検査するコード

ビルド時には、ヘッダのマクロで必要な版を確かめられます。古いヘッダでのコンパイルをその場で止められます。

#include <ghostty/vt.h>

#if !GHOSTTY_VT_VERSION_AT_LEAST(1, 0, 0)
#error "libghostty-vt 1.0.0 or newer is required"
#endif

実行時には、ghostty_version()が版を文字列で、ghostty_build_info()がGHOSTTY_BUILD_INFO_VERSION_MAJORなどのキーで数値の版を返します。メジャー版が一致し、実行時のライブラリのマイナー版がビルド時のヘッダ以上なら互換です。

Zig 0.17でのビルドから、pkg-configやCMakeでリンクするまでの手順

ビルド済みの配布はmacOS・iOS向けのXCFrameworkとWebAssemblyのモジュールだけなので、Linux・FreeBSD・Windowsではソースからビルドします。

リリースtarballの取得とminisign署名・SHA256の検証コマンド

公式のInstallingのページによると、配布物はrelease.files.ghostty.orgの版ごとのディレクトリに置かれ、各ファイルにminisignの署名が付きます。ソースのtarballと、オフラインでビルドするための依存パッケージのtarballが別々にあります。

curl -LO https://release.files.ghostty.org/libghostty-vt/1.0.0/libghostty-vt-1.0.0.tar.gz
curl -LO https://release.files.ghostty.org/libghostty-vt/1.0.0/SHA256SUMS
curl -LO https://release.files.ghostty.org/libghostty-vt/1.0.0/SHA256SUMS.minisig

minisign -V -P RWQlAjJC23149WL2sEpT/l0QKy7hMIFhYdQOFy0Z7z7PbneUgvlsnYcV -m SHA256SUMS
sha256sum --ignore-missing -c SHA256SUMS

GitHubがタグから自動で作るソースアーカイブは使いません。公式ドキュメントは、ライブラリのビルドに必要なファイルが含まれず、Ghosttyアプリのほうがビルドされてしまうと注意しています。配布元としてパッケージを作る場合は、PACKAGING-LIBGHOSTTY.mdにビルドオプションの全量がまとまっています。

zig buildでの導入先の指定とpkg-configを使ったCプログラムのリンク

ビルドにはZig 0.17が必要で、ほかのマイナー版ではエラーで止まります。Zigの版はABIの保証の対象外なので、libghostty-vtの版を上げるときは要求されるZigの版も確認します。

tar -xzf libghostty-vt-1.0.0.tar.gz
cd libghostty-vt-1.0.0
zig build -Doptimize=ReleaseFast --prefix "$HOME/.local"

export PKG_CONFIG_PATH="$HOME/.local/lib/pkgconfig"
cc -o hello hello.c $(pkg-config --cflags --libs libghostty-vt) -Wl,-rpath,"$HOME/.local/lib"
./hello

macOSでは@rpath/libghostty-vt.1.dylibとして読み込まれるため、rpathの指定が常に要ります。Linuxで/usr/libなどローダーが探す場所に入れた場合は省略が可能です。静的リンクにするなら、pkg-configの名前をlibghostty-vt-staticにして--staticを付けます。リポジトリを直接cloneしてビルドする場合は、-Demit-lib-vtを付け忘れるとGhosttyアプリがビルドされます。

CMakeのFetchContentで取得とビルドを任せる設定ファイルの例

CMakeのプロジェクトなら、tarballの取得からビルドまでをCMakeに任せられます。ZigがPATHに入っていることが前提です。FetchContentの書き方そのものはCMakeのFetchContentの書き方とオプション早見表で解説しています。

cmake_minimum_required(VERSION 3.24)
project(hello C)

include(FetchContent)
FetchContent_Declare(ghostty
  URL https://release.files.ghostty.org/libghostty-vt/1.0.0/libghostty-vt-1.0.0.tar.gz
  URL_HASH SHA256=4a6ef758be721923e1969e7b81b443dcc92d8dd3fb5a39600c03a8817a753676
)
FetchContent_MakeAvailable(ghostty)

add_executable(hello hello.c)
target_link_libraries(hello PRIVATE ghostty-vt)

URL_HASHは、2026年11月10日に1.0.0のSHA256SUMSから取得した値です。静的リンクならターゲット名をghostty-vt-staticにします。インストール済みの環境ではfind_package(ghostty-vt REQUIRED)を使います。

C言語で端末を作り、VTシーケンスを流して画面を読み出す実装

ここからは公式ガイドYour First Terminalの流れに沿って、端末の作成から解放までを1つのプログラムにまとめます。

ghostty_terminal_newで80列24行の端末を作りバイト列を書き込む

次のhello.cは、80列24行の端末を作り、色付きの文字列とカーソル移動のエスケープシーケンスを流し込み、最後に画面をプレーンテキストで出力します。前の章のpkg-configやCMakeの手順でそのままビルドできます。

#include <assert.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <ghostty/vt.h>

static void feed(GhosttyTerminal t, const char *s) {
  ghostty_terminal_vt_write(t, (const uint8_t *)s, strlen(s));
}

int main(void) {
  GhosttyTerminal terminal;
  GhosttyResult result = ghostty_terminal_new(NULL, &terminal, 80, 24);
  assert(result == GHOSTTY_SUCCESS);

  feed(terminal, "Hello, World!\r\n");
  feed(terminal, "\x1b[1;32mGreen Text\x1b[0m\r\n");
  feed(terminal, "\x1b[1;1HTop-left corner\r\n");

  GhosttyFormatter formatter;
  result = ghostty_formatter_terminal_new(NULL, &formatter, terminal);
  assert(result == GHOSTTY_SUCCESS);

  GhosttyFormatterFormat emit = GHOSTTY_FORMATTER_FORMAT_PLAIN;
  ghostty_formatter_set(formatter, GHOSTTY_FORMATTER_OPT_EMIT, &emit);
  bool trim = true;
  ghostty_formatter_set(formatter, GHOSTTY_FORMATTER_OPT_TRIM, &trim);

  uint8_t *buf = NULL;
  size_t len = 0;
  result = ghostty_formatter_format_alloc(formatter, NULL, &buf, &len);
  assert(result == GHOSTTY_SUCCESS);
  fwrite(buf, 1, len, stdout);
  printf("\n");

  ghostty_free(NULL, buf, len);
  ghostty_formatter_free(formatter);
  ghostty_terminal_free(terminal);
  return 0;
}

ghostty_terminal_vt_write()は失敗せず、戻り値もありません。不正なシーケンスが来ても端末側で処理されるので、PTYから読んだバイト列をそのまま渡せます。3行目の\x1b[1;1Hはカーソルを左上に戻すため、出力では1行目が「Top-left corner」で上書きされます。

フォーマッタで画面をプレーンテキストに変換する用途と解放の順序

上のコードのフォーマッタは、端末の現在の画面を文字列として取り出す仕組みです。出力の形式はプレーンテキストのほか、オプションで切り替えられます。公式ガイドは、フォーマッタをスナップショットを取るための手段とし、毎フレームの描画には使わないよう注意しています。

向いているのは、テストでの画面内容の照合やログへの保存です。解放は、フォーマッタ、描画用のオブジェクト、端末の順に行います。フォーマッタは端末を借りて動くため、端末を先に解放してはいけません。ghostty_formatter_format_alloc()で得たバッファは、確保に使ったのと同じアロケータを指定してghostty_free()で返します。

毎フレームの描画ループで使うレンダーステートと変更行だけを読む仕組み

画面に表示するアプリでは、レンダーステートを使います。毎フレーム、ghostty_render_state_update()で端末の状態を取り込み、変更のあった行だけをghostty_render_state_row_iterator_next_dirty()で順に読み、描き終えたらghostty_render_state_clean()で変更済みの印を消します。端末を読むのは最初の取り込みだけです。

各セルからは、太字などのスタイルをGHOSTTY_RENDER_STATE_ROW_CELLS_DATA_STYLEで、文字をUTF-8の書記素としてGHOSTTY_RENDER_STATE_ROW_CELLS_DATA_GRAPHEMES_UTF8で取り出します。約1,500行のCで端末を作る公式の例ghostlingが、このループにウィンドウとPTYを組み合わせた完成形として参考になります。

JetBrains IDEやNeovimの採用事例から見える置き換えの効果

JetBrains IDE 2026.3でJediTermから置き換わった処理の範囲

JetBrainsの公式ブログによると、2026.3からIDE内蔵のターミナルがlibghosttyで動きます。長年使ってきたJediTermを置き換え、解析と端末の状態をlibghosttyが、描画と上位の機能をIDEが受け持つ分担です。2026.3のEAPビルドでは既定で有効になっています。

Kittyキーボードプロトコルへの対応で、Claude CodeやCodexのようなCLIのAIエージェントにShift+Enterが改行として届くようになりました。JediTermが無視または誤読していた約50の制御シーケンスにも対応し、ncursesの文字の繰り返しやコロン区切りのSGR色指定での表示崩れが直っています。

Neovimの:terminalでlibvtermを置き換えるPRの状況とリフロー問題

Neovimでは、組み込みの:terminalが使っているlibvtermをlibghostty-vtへ置き換えるプルリクエスト#39773が出ています。初期版はメンテナーの承認を得ていますが、2026年11月10日時点ではマージされていません。依存ライブラリのタグ付きリリースが待たれていたため、1.0の公開で障害の1つが外れた段階です。

この置き換えで、ウィンドウの大きさを変えたときにスクロールバックの行が折り返し直されない、10年来のIssue #4997が閉じられる予定です。レビューでは、Neovim 0.13のリリース後に取り込む方針が示されています。Neovimの現行版への移行はNeovim 0.12系への移行手順を参照してください。

WebAssembly版のghostty-webと各言語のバインディング

ブラウザで使う場合は、Coderが公開しているghostty-webが、libghosttyのWebAssembly版にxterm.js互換のAPIをかぶせています。公式のWebAssemblyモジュールは、小さいほうでも全機能を有効にして1MB未満です。RustからWebAssemblyを扱う基本はRustでWebAssemblyを実装する手順にまとめています。

バインディングはRust・Go・Swift・Python・.NETなど多くの言語で作られ、awesome-libghosttyには100を超えるプロジェクトが載っています。AIコーディングエージェントを並べて動かすherdrも、発表で採用例に挙がっています。

libghostty-vtを採用する条件とxterm.jsのままでよい場面

自社のデスクトップアプリやCLIツールに端末を組み込むとき採用する条件

ネイティブのアプリに端末の表示を新しく組み込むなら、libghostty-vtを採用します。理由は、C ABIの互換が1.x系で約束されたこと、スレッドを作らずアロケータも差し替えられるため既存のイベントループに載せやすいこと、Kittyキーボードプロトコルのような新しいTUIの前提に対応していることです。発表では、4コア・8GBのLinuxサーバーで、シェルが動く端末を1万個同時に動かした検証も示されています。

既存の端末部品でAIエージェントのCLIの表示が崩れているなら、JetBrainsと同じく描画を手元に残し、解析と状態管理だけを差し替えます。

ブラウザ上でxterm.jsが問題なく動いている場合は置き換えを見送る

Webの管理画面でxterm.jsを使い、表示の崩れも利用者の不満も無いなら、置き換えは見送ります。ghostty-webはxterm.js互換をうたっていますが、Coderによる別プロジェクトで、libghostty-vt本体の1.x系の互換の約束はブラウザ側のAPIまでは及びません。WebAssemblyの読み込みが増え、ビルドの手順も変わります。効果が見えないまま交換するのは過剰です。

C以外の言語のバインディングも多くは第三者製です。採用前に、1.0.0へ追従しているかをリポジトリで確かめてください。

Zig 0.17の固定とスナップショット形式の非保証が運用に与える影響

運用で効くのはビルド環境です。Zigの版はABIの保証の外にあるため、CIのイメージにZig 0.17を固定し、libghostty-vtを上げるたびに要求されるZigの版を確かめる手順を決めておきます。

もう1つはスナップショットです。Stabilityのページによると、スナップショット関数はC ABIに含まれますが、生成されるバイト列の形式は版ごとに変わりえます。セッションをディスクへ保存して復元する設計なら、版を上げると古いスナップショットが読めなくなる前提で組んでください。

AIエージェントのCLI出力を画面状態として扱う使い方と相談先

端末アプリを作らない会社でも、libghostty-vtが役に立つ場面があります。AIエージェントにCLIツールを操作させると、出力には色やカーソル移動のエスケープシーケンスが混ざり、そのままでは画面に何が表示されているかを判定できません。バイト列をlibghostty-vtに流し込み、フォーマッタでプレーンテキストに変換すれば、人が見ている画面と同じ文字列をエージェントやテストに渡せます。

エージェントにどのコマンドまで実行させ、出力のどこを判断に使うかは、権限設計と一緒に決める必要があります。業務システムとAIエージェントの接続を含めた設計は、一創のAIエージェント開発でも相談を受けています。

よくある質問

libghosttyを調べ始めた段階でよく出る疑問をまとめました。

libghosttyは商用の製品に組み込んで使えますか?

使えます。libghostty-vtのライセンスはMITで、商用製品への組み込みと再配布を認めるものです。発表によると、コンパイル時に取り込まれるsimdutf・Google Highway・Wuffsなどの依存にもコピーレフトのコードは含まれず、各依存の版とSPDXライセンスが機械で読める一覧として配布物に入っています。製品に同梱するときは、MITの著作権表示をライセンス文書に含めてください。

Ghosttyアプリを入れなくてもlibghostty-vtだけを使えますか?

使えます。libghostty-vtはGhosttyアプリとは別のリリースサイクルで、専用のtarballとして配布されています。ビルドに要るのはZig 0.17とCコンパイラだけです。

WindowsのGhosttyアプリとlibghostty-vtの対応状況は同じですか?

同じではありません。libghostty-vtはWindowsのx86_64でCIのテストまで行われ、DLLとインポートライブラリが作られます。一方、GhosttyアプリのREADMEが対象として挙げているのはmacOSとLinux(GTK)で、2026年11月時点で公式のWindows版アプリは提供されていません。Windowsで端末を使いたいだけなら、WezTermの導入と設定のように既存のアプリを選ぶほうが早道です。

libvtermからlibghostty-vtへ移ると何が良くなりますか?

新しいTUIやAIエージェントのCLIが使う制御シーケンスへの対応範囲が広がります。JetBrainsの例では、IDEのテーマに合わせてダークモードとライトモードを問い合わせる制御シーケンスへの応答も加わりました。Neovimでは、スクロールバックの折り返し直しが目的の1つです。

libghostty-vtの版を上げるときに確認することは何ですか?

1.x系の中であれば、組み込む側のコードを直さずに上げられるのが約束です。確認するのは、要求されるZigの版が変わっていないか、GHOSTTY_DEPRECATEDが付いた関数を使っていないか、スナップショットを保存していないかの3点です。2026年11月10日時点の最新は1.0.0で、配布サーバーに1.0.1や1.1.0はまだありません。

関連記事

お気に入りに入れた記事の一覧

一創の公式 SNS

X では毎朝の新着記事と IT ニュースの速報を、YouTube・TikTok・Instagram・LinkedIn・Facebook では記事の解説動画を配信しています。

この記事は以下の記事からリンクされています

資料請求

今日のトレンド記事 直近 24 時間で、いつもより多く読まれている記事

  1. 2026.11.09 テックブログ エディオン不正アクセス第2報:カード番号の対象確認とログ・決済画面の改ざん対策
  2. 2025.04.30 テックブログ IMSIキャッチャー(偽基地局)とは?2Gフォールバックの手口と日本での対策
  3. 2026.11.10 テックブログ ニトリの情報漏洩:最大3,762万件の対象確認となりすまし連絡の見分け方
  4. 2026.11.10 テックブログ Claude Fable 5.2とは:料金・破壊的変更4点とFable 5.1からの移行手順【2026年11月】
  5. 2024.07.11 コラム Sakana AI創業者3人の経歴と会社概要|伊藤錬・デイビッド ハ・ライオン ジョーンズ

RELATED POSTS 関連記事

目次