Getting Started

This guide walks you through embedding TWrite into a GPUI application from scratch.

1. System Prerequisites

GPUI renders natively using Vulkan or Metal, with Wayland/X11 on Linux. On Linux systems, install the windowing and font development packages:

sudo apt-get install -y pkg-config libfontconfig1-dev libwayland-dev \
  libx11-xcb-dev libxkbcommon-x11-dev libxkbcommon-dev

2. Add Dependencies to Cargo.toml

Add twrite and GPUI to your application manifest:

[package]
name = "my-editor-app"
version = "0.1.0"
edition = "2024"

[dependencies]
gpui = "0.2"
twrite = "0.9"

# Optional: To enable the full Markdown battery, use:
# twrite = { version = "0.9", features = ["markdown"] }

# Wayland-only (or otherwise trimmed) backends: official `gpui` folds the old
# gpui_platform crate into itself, so select features on both lines.
# gpui = { version = "0.2", default-features = false, features = ["wayland"] }
# twrite = { version = "0.9", default-features = false, features = ["wayland"] }

3. Your First Editor Application

Create src/main.rs with the following minimal app:

use gpui::*;
use twrite::Editor;

struct AppView {
    editor: Entity<Editor>,
}

impl Render for AppView {
    fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
        div()
            .size_full()
            .bg(rgb(0x1e1e2e))
            .child(self.editor.clone())
    }
}

fn main() {
    Application::new().run(|cx: &mut App| {
        let bounds = Bounds::centered(None, size(px(800.0), px(600.0)), cx);
        cx.open_window(
            WindowOptions {
                window_bounds: Some(WindowBounds::Windowed(bounds)),
                titlebar: Some(TitlebarOptions {
                    title: Some("My First TWrite Editor".into()),
                    ..Default::default()
                }),
                ..Default::default()
            },
            |_window, cx| {
                let editor = cx.new(|cx| {
                    let mut ed = Editor::new("Hello from TWrite!\nStart typing here...\n", cx);
                    ed.config.line_numbers = true;
                    ed
                });
                cx.new(|_cx| AppView { editor })
            },
        )
        .unwrap();
    });
}

Run your application:

cargo run

You now have a fully functional text editor window with smooth scrolling, text selection, undo/redo (Ctrl+Z / Ctrl+Y), and line numbers.

4. Next Steps

Check out the step-by-step recipes: