Skip to main content

Build terminal UIs with Python using React-like components and flexbox layout. A 1:1 port of Ink.

Project description

PyInk

Build terminal UIs with Python using React-like components and flexbox layout.

A 1:1 Python port of Ink.

Install

pip install pyink

Or with uv:

uv add pyink

Usage

from pyink import component, render, Box, Text
from pyink.hooks import use_state, use_input, use_app

@component
def counter():
    count, set_count = use_state(0)
    app = use_app()

    def handle_input(input_str, key):
        if key.up_arrow:
            set_count(lambda c: c + 1)
        elif key.down_arrow:
            set_count(lambda c: max(0, c - 1))
        elif input_str == "q":
            app.exit()

    use_input(handle_input)

    return Box(
        Text(f"Counter: {count}", color="cyan", bold=True),
        Box(
            Text("Up/Down to change, q to quit", dim_color=True),
            margin_top=1,
        ),
        flex_direction="column",
        padding=1,
        border_style="round",
    )

render(counter())

Components

Box

Flexbox container, like <div>. Supports all flexbox props:

Box(
    *children,
    flex_direction="row",       # row | column | row-reverse | column-reverse
    justify_content="center",   # flex-start | center | flex-end | space-between | space-around | space-evenly
    align_items="stretch",      # flex-start | center | flex-end | stretch | baseline
    padding=1,                  # padding on all sides
    margin_top=1,               # individual margin
    border_style="round",       # single | double | round | bold | classic
    border_color="green",       # named color, hex, or rgb
    width=40,
    height=10,
    overflow="hidden",
)

Text

Text with styling:

Text("Hello", color="green", bold=True, italic=True, underline=True, strikethrough=True, dim_color=True, inverse=True)

Spacer

Fills available space (like flex: 1):

Box(Text("Left"), Spacer(), Text("Right"), flex_direction="row")

Static

Render items once (for logs, completed tasks):

Static(items=completed, render_item=lambda item, i: Text(f"Done: {item}"))

Transform

Transform text output per line:

Transform(Text("hello"), transform=lambda text, idx: text.upper())

Hooks

Hook Description
use_state(initial) Local state, returns (value, setter)
use_effect(fn, deps) Side effects with cleanup
use_input(handler) Keyboard input
use_app() App lifecycle (exit())
use_focus() Tab-based focus
use_focus_manager() Programmatic focus control
use_animation(interval=100) Frame animation
use_window_size() Terminal dimensions
use_ref(initial) Mutable ref
use_memo(fn, deps) Memoized value
use_paste(handler) Paste events
use_stdout() / use_stderr() / use_stdin() Stream access
use_cursor() Cursor position
use_box_metrics(ref) Element measurements
use_is_screen_reader_enabled() Accessibility detection

Examples

uv run python -m pyink.examples.counter
uv run python -m pyink.examples.chat
uv run python -m pyink.examples.dashboard
uv run python -m pyink.examples.select_input
uv run python -m pyink.examples.use_animation
uv run python -m pyink.examples.borders
uv run python -m pyink.examples.alternate_screen
uv run python -m pyink.examples.use_focus
uv run python -m pyink.examples.table
uv run python -m pyink.examples.justify_content
uv run python -m pyink.examples.terminal_resize

Acknowledgements

PyInk is a Python port of Ink by Vadim Demedes. All credit for the architecture and design goes to the Ink team.

Project details


Download files

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

Source Distribution

pyinklib-0.0.1.tar.gz (78.8 kB view details)

Uploaded Source

Built Distribution

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

pyinklib-0.0.1-py3-none-any.whl (61.1 kB view details)

Uploaded Python 3

File details

Details for the file pyinklib-0.0.1.tar.gz.

File metadata

  • Download URL: pyinklib-0.0.1.tar.gz
  • Upload date:
  • Size: 78.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.15

File hashes

Hashes for pyinklib-0.0.1.tar.gz
Algorithm Hash digest
SHA256 c073dacde3f439236a88b2fbbe563708a5c6c425f8144fe2455a6cc0be8d032b
MD5 fec8b3b7c3ec93c27dec63c1b09ac589
BLAKE2b-256 56b00901e39f796fd1d57ec034cb40a44f505c0d9ba61b5a5c06caadf93398f3

See more details on using hashes here.

File details

Details for the file pyinklib-0.0.1-py3-none-any.whl.

File metadata

  • Download URL: pyinklib-0.0.1-py3-none-any.whl
  • Upload date:
  • Size: 61.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.15

File hashes

Hashes for pyinklib-0.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 0a75264acdf78967516720d12f6caca879d6f7e1062281ec88c5a43ea6b6559a
MD5 6124f8296610fbf451209272b16cec56
BLAKE2b-256 66c861e30487e31cd5dcc16b074e794e9660b9a0f733ec8a00e3b6bc7d8ea66a

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page