Skip to main content

flet-terminal

Download Flet Terminal PyPI Flet

A native, GPU-accelerated terminal control for Flet, built on top of xterm.dart.

flet-terminal provides high-performance VT100/ANSI terminal emulation across Windows, Linux, macOS, Android, and Web, utilizing low-latency binary DataChannel streaming to render thousands of lines per second without UI freezing.

Fully compatible with Flet 0.86's declarative component model (@ft.component, @ft.observable, use_state, use_effect) — including frozen-control safety via the built-in thaw() context manager.


Download Flet Terminal

Try the standalone Flet Terminal desktop application directly on your OS:

Platform Download Notes
🪟 Windows (x64) FletTerminal_windows_x64.zip Portable Windows executable (.exe)
🐧 Linux (x86_64) FletTerminal_linux_x86_64.tar.gz Universal Linux tarball (tar -xzf)
📦 All Releases View Releases Page Changelog and release notes

Features

  • High-Throughput Binary Streaming: Routes terminal data over Flet DataChannel directly to the xterm.dart canvas, bypassing string/MsgPack serialization overhead.
  • Cross-Platform Compatibility: Full feature parity across Desktop (pty / winpty), Mobile (Android), and Web (WASM / Pyodide).
  • Declarative-First Design: Built for Flet 0.86's React-like component model. All internal mutations use thaw() to safely update frozen controls inside declarative trees.
  • Responsive Mobile Wrapper & Zoom Controls: MobileTerminal includes zoom_in(), zoom_out(), reset_zoom(), and a customizable virtual accessory keyboard (ESC, TAB, CTRL, ALT, arrows) with sticky modifier toggles and collapsible state.
  • Reactive CTRL/ALT Modifiers: Sticky modifier buttons are @ft.component instances subscribed to an @ft.observable ModifierState — they repaint instantly on toggle, reset, or external state change.
  • Real Cursor Blink: A Dart-side Timer.periodic toggles cursorVisibleMode + notifyListeners() for true blink (upstream xterm 4.0.0 has no built-in blink).
  • 4 Built-in Themes: Dracula, JetBrains Dark, Matrix Green, and Colab Light (Material light palette with orange cursor). Settings popup displays accurate checkmarks that update live.
  • Interactive Search & Selection: Built-in search bar with match counter, scrollback control, and clipboard integration (select_all, copy_selection, paste, clear_selection).
  • Frozen-Control Safety: The thaw() context manager (exported from flet_terminal.frozen_support) temporarily lifts Flet's _frozen flag so imperative mutations work inside declarative trees — the same pattern Flet uses internally in _before_update_safe.

Installation

Install via pip:

pip install flet-terminal

Or using uv:

uv add flet-terminal

Quickstart

1. Declarative App (Recommended — Flet 0.86)

import flet as ft
from flet_terminal import MobileTerminal, BUILTIN_THEMES


@ft.component
def App():
    page = ft.context.page
    mt, _ = ft.use_state(lambda: MobileTerminal(
        show_extra_keys=True,
        show_search=False,
        show_settings=True,
        scrollback=10000,
        font_family="JetBrains Mono",
        font_size=13.0,
        cursor_blink=True,
        theme=BUILTIN_THEMES["JetBrains Dark"],
        expand=True,
    ))

    def on_bytes(payload: bytes):
        # Echo back or forward to a PTY / remote shell
        mt.send_bytes(payload)

    ft.use_effect(lambda: mt.set_on_bytes(on_bytes), [])

    return ft.Column(controls=[mt], spacing=0, expand=True)


def main(page: ft.Page):
    page.title = "My Terminal"
    page.theme_mode = ft.ThemeMode.DARK
    page.padding = 0
    page.render(App)


ft.run(main)

2. Basic Terminal (Terminal)

import flet as ft
from flet_terminal import Terminal, BUILTIN_THEMES


def main(page: ft.Page):
    page.theme_mode = ft.ThemeMode.DARK

    term = Terminal(
        scrollback=10000,
        font_family="JetBrains Mono",
        font_size=13.0,
        cursor_blink=True,
        theme=BUILTIN_THEMES["Dracula"],
        expand=True,
    )

    def on_terminal_input(data: bytes):
        term.send_bytes(data)

    term.set_on_bytes(on_terminal_input)
    page.add(term)
    term.write("\x1b[1;32mWelcome to FletTerminal!\x1b[0m\r\n> ")


ft.run(main)

3. Imperative Construction Inside Async Tasks

If you build MobileTerminal outside a component render (e.g. inside page.run_task), wrap construction in a throwaway renderer so the internal @ft.component buttons can instantiate:

from flet.components.component import Renderer

with Renderer().with_context():
    mt = MobileTerminal(theme=BUILTIN_THEMES["JetBrains Dark"], expand=True)

Reactivity is unaffected — Component.update() creates its own renderer on every re-render.


API Reference

Terminal Properties

Property Type Default Description
scrollback int 10000 Maximum number of scrollback lines retained in the ring buffer.
font_family str "JetBrains Mono" Monospace font family for rendering text.
font_size float 13.0 Font point size.
cursor_style str "block" Cursor shape. Currently only "block" is supported (underline/bar removed due to upstream xterm 4.0.0 painter bug).
cursor_blink bool True Whether the terminal cursor blinks (real Dart-side timer).
theme dict None Dictionary mapping ANSI color keys to hex colors.
read_only bool False When True, disables user keyboard input into the terminal canvas.
auto_focus bool True Automatically focuses the terminal when mounted.

Terminal Methods

Method Arguments Description
send_bytes(payload) bytes Sends binary data directly over the DataChannel to the terminal canvas.
write(data) str | bytes Writes text or escape sequences to the terminal.
clear() Clears the terminal scrollback and visible screen buffer.
focus() Requests keyboard focus on the terminal control.
search(query, start, direction) str, int, str Highlights and selects matching text in the scrollback buffer.
select_all() Selects all text currently in the buffer.
clear_selection() Clears any active selection.
paste() Pastes clipboard content into the terminal.

Terminal Events

Event Handler Description
on_data Callable[[ft.ControlEvent], None] Triggered when string-based text input occurs.
on_resize Callable[[ft.ControlEvent], None] Fired when dimensions change. Event data contains JSON {"cols": int, "rows": int}.
on_title_change Callable[[ft.ControlEvent], None] Triggered when OSC 0/2 title escape sequences are received.
on_bell Callable[[ft.ControlEvent], None] Triggered when the bell character (\a / 0x07) is received.
on_selection_change Callable[[ft.ControlEvent], None] Fired when selection or search matches update.
on_shortcut Callable[[ShortcutEvent], None] Fired when a built-in host shortcut is pressed while the terminal has focus. The combo is consumed on the Dart side — it never reaches the PTY. e.shortcut carries the machine name. Active only when a handler is set.

Built-in shortcuts (on_shortcut)

Combination e.shortcut value
Ctrl/Cmd+Shift+T new_terminal
Ctrl/Cmd+Shift+W close_terminal
Ctrl/Cmd+Shift+1+9 switch_terminal_1switch_terminal_9
Ctrl/Cmd+Shift+F toggle_search
Ctrl/Cmd+Shift+L clear
Ctrl/Cmd+Shift+C copy
Ctrl/Cmd+Shift+V paste
Ctrl/Cmd+Shift+= zoom_in
Ctrl/Cmd+Shift+- zoom_out
Ctrl/Cmd+Shift+0 zoom_reset
Ctrl/Cmd+PageUp / PageDown prev_terminal / next_terminal
F1 help

MobileTerminal Additional Methods & Properties

Method / Property Description
set_theme(name) Switch to a built-in theme by name.
set_cursor_style(style) Set cursor style (currently "block" only).
toggle_cursor_blink() Toggle cursor blink on/off.
zoom_in(step=1.0) Increase font size.
zoom_out(step=1.0) Decrease font size.
reset_zoom() Reset to default font size.
toggle_search() Show/hide the built-in search bar.
copy_selection() Copy selected text to clipboard.
paste() Paste clipboard into terminal.
select_all() / clear_selection() Selection helpers.
send_bytes(payload) / write(data) / clear() / focus() Inherited from Terminal.
set_on_bytes(handler) Register the input handler.
Read-only properties
font_size Current font size.
cursor_blink Current blink state.
cursor_style Current cursor style.
theme_name Active theme name (or None).
show_search Whether search bar is visible (settable).
ctrl_active / alt_active Sticky modifier state (settable).

ExtraKeysBar Constructor

Parameter Type Default Description
on_send_payload Callable[[bytes], None] required Called with the final byte payload after modifier processing.
on_modifier_change Callable[[bool, bool], None] required Called with (ctrl, alt) when sticky state changes.
show_settings bool True Show the gear icon settings popup.
on_set_theme Callable[[str], None] None Theme preset callback.
on_set_cursor Callable[[str], None] None Cursor style callback.
on_toggle_blink Callable[[], None] None Blink toggle callback.
on_toggle_search Callable[[], None] None Search toggle callback.
on_copy / on_paste / on_select_all / on_clear Callable[[], None] None Clipboard/buffer callbacks.
keys list[tuple[str, bytes | None]] DEFAULT_EXTRA_KEYS Custom key layout. None payload = modifier key.

Built-in Themes

from flet_terminal import BUILTIN_THEMES, get_theme

# Available: "Dracula", "JetBrains Dark", "Matrix Green", "Colab Light"
my_theme = get_theme("Dracula")
Theme Background Cursor Best for
Dracula #1E1F29 #FF79C6 (pink) Dark mode default
JetBrains Dark #1E1E2E #F5E0DC (warm white) Dark mode (Catppuccin-inspired)
Matrix Green #0D1117 #00FF66 (green) Retro / hacker aesthetic
Colab Light #FFFFFF #F97316 (orange) Light mode / follows app theme

Frozen-Control Support

Flet 0.86's declarative renderer stamps _frozen = True on all component-rendered controls. Imperative mutations (.update(), property assignment) raise RuntimeError: Frozen controls cannot be updated.

flet_terminal handles this internally via thaw():

from flet_terminal.frozen_support import thaw

with thaw(some_control):
    some_control.style = new_style
    some_control.update()

All MobileTerminal setters (set_theme, zoom_in, toggle_search, etc.) and ExtraKeysBar mutations already use thaw() internally — no extra wrapping needed by consumers.


License

This project is licensed under the MIT License. See LICENSE for details.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

flet_terminal-0.3.8.tar.gz (31.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

flet_terminal-0.3.8-py3-none-any.whl (32.0 kB view details)

Uploaded Python 3

File details

Details for the file flet_terminal-0.3.8.tar.gz.

File metadata

  • Download URL: flet_terminal-0.3.8.tar.gz
  • Upload date:
  • Size: 31.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for flet_terminal-0.3.8.tar.gz
Algorithm Hash digest
SHA256 5653a0b5686b044a8e4fdef471d523da8ae593ebf3acaf326910cfd543ec0cda
MD5 6eb17cb53c7780174027dc92c744a9a0
BLAKE2b-256 4b3d955d4fe61d6958232a692606bdefb6de424945efa46f5e22d338d2b5b033

See more details on using hashes here.

Provenance

The following attestation bundles were made for flet_terminal-0.3.8.tar.gz:

Publisher: publish.yml on Nwokike/flet-terminal

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file flet_terminal-0.3.8-py3-none-any.whl.

File metadata

  • Download URL: flet_terminal-0.3.8-py3-none-any.whl
  • Upload date:
  • Size: 32.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for flet_terminal-0.3.8-py3-none-any.whl
Algorithm Hash digest
SHA256 32e94024b7f4583f5bd2fdc146bb399ade198391fb7e35c54e66ab0ae7b017e4
MD5 9d9559dff2d5c296400e7cc751e9e4ef
BLAKE2b-256 3fad52ee2df6df008714b4cac372067ece2ed23a18506191e031b77b7dc9af61

See more details on using hashes here.

Provenance

The following attestation bundles were made for flet_terminal-0.3.8-py3-none-any.whl:

Publisher: publish.yml on Nwokike/flet-terminal

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.3.8 This release

2 files

0.3.7

2 files

0.3.6

2 files

0.3.5

2 files

0.3.4

2 files

0.3.3

2 files

0.3.2

2 files

0.3.1

2 files

0.2.2

2 files

0.2.1

2 files

0.2.0

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page