This release is a pre-release and may not be stable for production use.
xnano
A fun, fast and incredibly flexible terminal UI library for Python, built on ratatui.
Packages
The repository is a uv workspace with three installable backends and a small xnano metapackage. The native packages can also be installed and used independently.
| Distribution | Import | Purpose |
|---|---|---|
xnano |
xnano.v1 (legacy API) |
Metapackage; v1 compatibility API is opt-in. |
xnano-core |
xnano._xnano_core |
Rust-backed terminal buffers, widgets, layout, state, input, runtime and effects. |
xnano-audio |
xnano_audio |
Audio synthesis, playback, capture and beat-based melodies. |
xnano-image |
xnano_image |
Image and animation decoding, processing and terminal-cell conversion. |
Install
Install the full xnano distribution with pip or uv:
pip install xnano
# or
uv add xnano
Install only a backend when you need a smaller dependency set:
pip install xnano-core
pip install xnano-audio
pip install xnano-image
The core package also provides audio, image, and all extras for installing those backends alongside xnano-core. On Linux, audio device playback requires ALSA; synthesis and melody scheduling work without an audio device.
Quick start: draw without a terminal
The core API builds buffers from operations. Rendering a buffer to text is useful for scripts and tests and does not take over the terminal.
from xnano._xnano_core import Border, Buffer, Write
card = Buffer(width=16, height=3)
card.update(Border('rounded'), Write('hello, xnano', x=2, y=1))
print(card.render(format='text'))
Quick start: run a mounted buffer
An offscreen runtime exercises layout and frame rendering without terminal I/O. Use Runtime.live() when the application should own a real terminal.
from xnano._xnano_core import Buffer, Runtime, Write
with Runtime.offscreen(width=20, height=3) as runtime:
buffer = Buffer()
runtime.mount(buffer, geometry='inherit')
buffer.update(Write('hello from xnano'))
runtime.step()
print(runtime.snapshot().lines()[0])
The runtime also routes keyboard and mouse input, manages focus and state, and advances effects against its frame clock. See the getting started guide and API reference.
Audio melodies
xnano-audio describes notes in beats, converts them to seconds through a tempo map, and schedules notes over clock windows. This makes melody timing independent of the terminal render loop; an application can use the same monotonic clock for UI animation and audio scheduling.
from xnano_audio import TerminalMelody, TerminalTempoMap
melody = (
TerminalMelody(tempo_map=TerminalTempoMap(120))
.appended_note('C4', duration_beats=1)
.appended_note('G4', duration_beats=1)
)
# Query a half-second window on the same monotonic clock used by the UI.
print(melody.scheduled_between(0.0, 0.5))
Images and animations
Decode an image and convert it to terminal cells with xnano-image:
from xnano_image import TerminalImage, cell_grid_to_ansi
image = TerminalImage.open('photo.png')
print(cell_grid_to_ansi(image.to_cell_grid(40)))
The image package returns a portable cell-grid representation that the core can draw with its cell-grid widgets. It also supports animated formats and conversion to a cell animation.
The v1 API
The previous declarative API remains available from xnano.v1; the main xnano package does not import it unless requested. Existing applications can migrate incrementally while new code uses the Rust-backed core.
from xnano.v1 import BaseGrid, Context, Field, Terminal, on_keyboard
class Counter(BaseGrid, direction='vertical', gap=1):
label: str = Field(default='Count: 0', height=3, border='rounded')
count: int = Field(default=0, state=True)
@on_keyboard('up')
def increment(self) -> None:
self.count += 1
self.label = f'Count: {self.count}'
@on_keyboard('q')
def quit(self, context: Context) -> None:
context.terminal.request_exit()
Terminal().run(Counter())
The restored legacy documentation is under docs/v1. The v1 API is maintained as a compatibility layer; new core capabilities are documented in the current guides and API reference.
Development
The repository uses a uv workspace and Rust workspace. From the repository root, uv sync --all-extras installs the development environment and make help lists common build, test, lint, type-check, docs and release commands. Read CONTRIBUTING.md before opening a change.
License
xnano is released under the MIT License.
Metadata
Release files for xnano 2.0.0b1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| xnano-2.0.0b1.tar.gz | 11.0 MB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| xnano-2.0.0b1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 11.0 MB
Release files / xnano-2.0.0b1.tar.gz
| Download URL | xnano-2.0.0b1.tar.gz |
|---|---|
| Size | 11.0 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c597ce23c857bb75b6447c1eeff2808283c8dd03505fea5ddd1d36fb187a1210
|
|
BLAKE2b-256 checksum How to use checksums |
b2da65da43c8c1934d8cd577e29c525665ef976db2d6b054084fd2ddf368f56b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.13.0 {"installer":{"name":"uv","version":"0.13.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / xnano-2.0.0b1-py3-none-any.whl
| Download URL | xnano-2.0.0b1-py3-none-any.whl |
|---|---|
| Size | 5.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b5ba5be7a3693572db9754cc6f13c69bb45b594911212ab5bda18df5be3a146c
|
|
BLAKE2b-256 checksum How to use checksums |
c1db31aff62c93f807f46537873cb0ec1f7461622771f2f210176bcda2826465
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.13.0 {"installer":{"name":"uv","version":"0.13.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Security for xnano 2.0.0b1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.