A universal UI library that renders the same widget tree to terminals (ANSI
escapes), graphical surfaces (DRM/X11), and in-memory buffers (headless).
Operates in two modes: as an embeddable shared library (libfilly.so)
callable directly from C, Python, Go, or Node.js, and as a standalone
daemon speaking a versioned JSON/MessagePack protocol over Unix sockets.
One library. Every surface. Two ways to use it.
Designed for operating system installers, system configuration tools, and any project needing interactive prompts that work identically over SSH, on a raw TTY, or on a graphical desktop.
Programs link against libfilly.so and call the C API directly. No socket,
no daemon, no serialization overhead.
┌──────────────────────┐
│ Host Application │
│ (C, Python, Go, │
│ Node.js) │
└──────────┬───────────┘
│ direct function calls
┌──────────▼───────────┐
│ libfilly.so │
│ ┌─────────────────┐ │
│ │ Session API │ │
│ │ Widget Engine │ │
│ │ FIL Evaluator │ │
│ │ Theme Engine │ │
│ │ Backend (T/G/H)│ │
│ │ Plugin Loader │ │
│ └─────────────────┘ │
└──────────────────────┘
The daemon binary links libfilly.so and adds a Unix socket accept loop.
Clients communicate via JSON/MessagePack over Unix sockets.
┌──────────┐ ┌───────────┐ ┌──────────┐
│filly send│ │filly relay│ │C client │
└────┬─────┘ └─────┬─────┘ └────┬─────┘
│ │ │
└──────────┬───┴──────────────┘
│ JSON / MessagePack over Unix socket
┌────────▼──────────┐
│ filly daemon │
│ (thin wrapper) │
│ ┌──────────────┐ │
│ │ libfilly.so │ │
│ └──────────────┘ │
└───────────────────┘
dialog and ncurses work but look like 1995 — no centering, no theming, no composability.
gum is excellent for simple shell scripts but has no persistent state, no composite widgets, no daemon mode, no graphical backend.
forge-tui (Rust) proved a TUI toolkit could be fast and beautiful but was terminal-only with no plugin system.
forge-gui (Python/GTK4) shared the same protocol but was a completely separate codebase. Maintaining two implementations of every widget was unsustainable.
FILLY merges both into a single ANSI C codebase with pluggable backends.
One library. Every surface. Zero dependencies beyond a C compiler and libsodium.
- 42 widget types — menus, inputs, checklists, file pickers, text editors, progress bars, disk partitioners, color pickers, terminal emulator, macro recorder, images, canvas, markdown, plots, and more
- Three backends — terminal (ANSI + termios), graphical (DRM/X11), headless (in-memory buffer for CI)
- Dual wire formats — NDJSON (default) and MessagePack (negotiated)
- Embeddable library —
libfilly.sowith public C API, session management, FIL scripting, direct widget execution - Daemon mode — persistent Unix socket listener with session checkpointing, inactivity timeout, client threading, rate limiting
- Plugin system — load custom widgets from
.sofiles; Ed25519 signature verification via libsodium; sandboxed execution (seccomp/pledge/capsicum) - Theme engine — 10 built-in JSON themes with variable resolution, colour arithmetic functions, widget selectors, inheritance, transitions, animations, and live reload
- Animation engine — keyframe-based with 9 easing functions, per-property interpolation, GPU transforms, TUI-safe animation subset
- GUI builder —
filly-buildvisual widget composer with canvas, connection graph editor, property editor, validation pipeline, and C code generation - FIL scripting language — embedded English-like DSL for widget sequencing, validation, conditional visibility, style definitions, animation control, and keybindings
- Client libraries — C client, Python, Go, Node.js
- CLI tools —
filly oneshot,filly send,filly build,filly relay,filly daemon,filly inspect,filly profile,filly eval - Accessibility — AT-SPI bridge for screen readers, high-contrast and large-print themes, keyboard navigation
- Portability — Linux, FreeBSD, OpenBSD via
filly-port/abstraction layer - Test suite — behavioral tests, pixel snapshot tests, fuzzer, fault injection, Valgrind CI
- Zero external runtime dependencies — just libsodium
make
./filly oneshot '{"widget":"msg","params":{"title":"Hello","message":"World"}}'
./filly daemon &
./filly send '{"widget":"msg","params":{"title":"Hello","message":"World"}}'
./filly eval 'set store.os to Artix'#include "filly.h"
#include "filly_session.h"
int main(void) {
filly_init(FILLY_BACKEND_AUTO);
FillySession *s = filly_session_create();
filly_session_run_json(
s,
"{\"widget\":\"msg\",\"params\":{\"title\":\"Hello\",\"message\":\"World\"}}"
);
filly_session_free(s);
filly_shutdown();
return 0;
}from filly import Client
c = Client()
c.send('{"widget":"msg","params":{"title":"Hello","message":"World"}}')FILLY/
├── src/
│ ├── cli/ # Thin CLI wrappers
│ │ └── main.c
│ ├── daemon/ # Daemon binary — socket accept loop
│ │ ├── daemon.c
│ │ └── daemon.h
│ ├── builder/ # GUI builder
│ └── libfilly/ # The library
│ ├── public/ # Public API headers
│ │ ├── filly.h
│ │ ├── filly_types.h
│ │ ├── filly_session.h
│ │ ├── filly_eval.h
│ │ ├── filly_client.h
│ │ └── filly_plugin.h
│ ├── engine/ # Engine
│ │ ├── lifecycle/
│ │ ├── backend/
│ │ ├── session/
│ │ ├── render/
│ │ ├── widget/
│ │ ├── util/
│ │ ├── accessibility/
│ │ ├── recorder/
│ │ ├── relay/
│ │ ├── client/
│ │ └── server/
│ ├── widgets/ # 42 widget implementations
│ ├── backend/ # Rendering backends
│ │ ├── terminal/
│ │ ├── headless/
│ │ ├── gcore/
│ │ └── socket/
│ ├── protocol/ # JSON, schema, MessagePack
│ ├── script/ # FIL interpreter, AST, runtime bridge
│ ├── filly-port/ # Platform abstraction
│ ├── plugin/ # Plugin loader + security
│ └── themes/ # 10 theme JSON files
├── plugins/ # Plugin .so source files
├── bindings/ # Language bindings (Python, Go, Node.js)
├── test/ # Test suite
├── tools/ # genkey, sign, verify
└── Makefile
Licensed under the IRX License 1.0
© Volk 2026
See LICENSE.
The Optional Endorsement Clause (Section 9) applies to FILLY. Applications built with FILLY, widgets rendered through FILLY, and artifacts generated using FILLY are not considered modified versions of FILLY itself. You do not need to license your application under IRX to use FILLY as a library or daemon.