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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c073dacde3f439236a88b2fbbe563708a5c6c425f8144fe2455a6cc0be8d032b
|
|
| MD5 |
fec8b3b7c3ec93c27dec63c1b09ac589
|
|
| BLAKE2b-256 |
56b00901e39f796fd1d57ec034cb40a44f505c0d9ba61b5a5c06caadf93398f3
|
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0a75264acdf78967516720d12f6caca879d6f7e1062281ec88c5a43ea6b6559a
|
|
| MD5 |
6124f8296610fbf451209272b16cec56
|
|
| BLAKE2b-256 |
66c861e30487e31cd5dcc16b074e794e9660b9a0f733ec8a00e3b6bc7d8ea66a
|