flterm 0.0.4 copy "flterm: ^0.0.4" to clipboard
flterm: ^0.0.4 copied to clipboard

Flutter terminal widget on top of Ghostty's libghostty-vt engine.

Ghostty's full VT engine, as a Flutter widget

pub package ci

Flutter terminal widget on top of Ghostty's libghostty-vt engine.

Android iOS Linux macOS Web Windows

Overview #

  • Adapts to the host: mouse and keyboard on desktop, touch and soft keyboard on mobile, both on web.
  • TerminalController owns the terminal and connects to a backend (PTY, SSH, socket) via output/resize/bell/title callbacks. Helpers for I/O, selection, focus, scrolling, paste, and mode toggling.
  • Drag, double-click, triple-click, and Alt+drag selection over wide characters (CJK, emoji, VS16, combining marks) with cell-snapped boundaries.
  • Built-in copy, paste, select all, and clear shortcuts with platform-aware defaults. Extend or replace with any Flutter Intent.
  • Themes for ANSI 16, 256-color, and truecolor palettes; cursor; hyperlinks; fonts. Immutable and lerp-able.
  • Links for OSC 8 metadata, text URLs, file paths, and custom regex rules with activation callbacks.

Getting started #

dependencies:
  flterm: ^0.0.4

On web, initialize the wasm module once before mounting any terminal:

import 'package:flterm/flterm.dart';
import 'package:flutter/foundation.dart';

if (kIsWeb) {
  await initializeForWeb(Uri.parse('assets/libghostty.wasm'));
}

Usage #

A TerminalController owns the terminal and talks to your I/O. A TerminalView renders it.

import 'package:flterm/flterm.dart';

final controller = TerminalController()
  ..onOutput = (bytes) => pty.write(bytes)
  ..onResize = (cols, rows) => pty.resize(cols, rows)
  ..onBell = playSound;

ptyOutputStream.listen(controller.write);

TerminalView(
  controller: controller,
  theme: TerminalTheme.dark(),
);

The same controller drives the terminal programmatically:

// I/O
controller.sendText('ls -la\n');

// Selection
controller.selectAll();
print(controller.selectedText());

// Clipboard
controller.paste('hello');

// Reset
controller.clear();

Links are configured on the view. Built-in detection covers OSC 8 metadata, text URLs, and file paths.

TerminalView(
  controller: controller,
  linkSettings: LinkSettings(
    onActivate: (link) {
      if (link.uri case final uri?) openUri(uri);
      if (link.file case final file?) openFile(file);
    },
  ),
);

Custom matchers can add project-specific selectors:

TerminalView(
  controller: controller,
  linkSettings: LinkSettings(
    rules: [
      .regex(
        id: 'issue',
        pattern: RegExp(r'#(\d+)'),
      ),
    ],
    onActivate: (link) {
      if (link.id == 'issue') openIssue(link.text.substring(1));
    },
  ),
);

Note: Idle link styling and custom rules with LinkHighlightMode.always scan visible content after terminal updates. The cost grows with output rate, visible rows, and line length, which can impact rendering performance and frame rate. Avoid always-on or idle highlighting unless that extra scanning is acceptable.

Custom themes are constructed directly:

TerminalView(
  controller: controller,
  theme: TerminalTheme(
    palette: ColorPalette(
      ansiColors: const [/* 16 ANSI colors */],
      background: const Color(0xFF1D1F21),
      foreground: const Color(0xFFC5C8C6),
    ),
    fontFamily: 'JetBrains Mono',
    fontSize: 14,
    cursor: const CursorTheme(shape: CursorShape.bar),
  ),
);

License #

MIT. See LICENSE.

1
likes
160
points
194
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Flutter terminal widget on top of Ghostty's libghostty-vt engine.

Homepage
Repository (GitHub)
View/report issues

Topics

#terminal #terminal-emulator #ghostty #libghostty #vt100

License

MIT (license)

Dependencies

flutter, image, libghostty, meta

More

Packages that depend on flterm