Architecture Overview
OpenTUI’s architecture consists of three main layers:TypeScript Layer
- High-level components and APIs
- Event handling and state management
- React/Solid bindings
- Application logic
FFI Layer
- Bun’s native FFI for zero-overhead calls
- Type-safe bindings with bun-ffi-structs
- Efficient data transfer between layers
Zig Core
- Low-level rendering primitives
- Optimized buffer management
- UTF-8 and grapheme processing
- Text buffer and rope data structures
- ANSI escape sequence generation
Core Components
The Zig core provides several key modules:Renderer (renderer.zig)
Core rendering engine that manages:- Frame buffer operations
- Diff-based rendering
- ANSI sequence generation
- Cursor management
- Terminal state
Buffer (buffer.zig)
Optimized buffer management:- Zero-copy operations
- Efficient memory layout
- Color and attribute storage
- Character-level manipulation
Text Buffer (text-buffer.zig)
High-performance text editing:- Line-based text storage
- Efficient insertions/deletions
- Selection handling
- Syntax highlighting support
- Viewport management
Rope (rope.zig)
Efficient string data structure:- Fast insertions at any position
- Memory-efficient for large texts
- Supports markers and ranges
- Used by text buffer internally
UTF-8 Processing (utf8.zig)
- Unicode grapheme clustering
- Width calculation (wcwidth)
- ZWJ (Zero Width Joiner) handling
- Emoji support
- East Asian width detection
Native Span Feed (native-span-feed.zig)
Stream-based rendering:- Efficient ANSI processing
- Chunk-based data flow
- Zero-copy where possible
- Async-friendly
Building from Source
Prerequisites
Bun Install Bun (JavaScript runtime):Clone Repository
Build Native Core
Build the Zig native libraries:- Native Zig code to shared libraries
- For your current platform (x64/arm64, Linux/macOS/Windows)
- Optimized for release by default
Build for Development
Development builds include debug symbols:Build for All Platforms
Cross-compile for all supported platforms:- x86_64-linux
- aarch64-linux
- x86_64-macos (Intel)
- aarch64-macos (Apple Silicon)
- x86_64-windows
- aarch64-windows
Build Specific Platform
Build System (build.zig)
OpenTUI uses Zig’s build system:Build Options
Build Steps
Filter Tests
TypeScript-Only Changes
FFI Layer
The FFI layer uses Bun’s native FFI for calling Zig functions from TypeScript.Loading the Library
FFI Function Signature
Passing Structures
Use bun-ffi-structs for complex data:Calling Native Functions
Memory Management
The native core manages its own memory:Development Workflow
1. Changing TypeScript Code
2. Changing Zig Code
3. Running Tests
4. Benchmarking
Local Development Linking
Link your local OpenTUI to another project:Options
@opentui/core@opentui/reactor@opentui/solid(if specified)- Peer dependencies (yoga-layout, react, solid-js, etc.)
- Subdependencies like
opentui-spinner(with —subdeps)
Debugging Native Code
Enable FFI Debug Logging
Use Debug Build
Debug with LLDB/GDB
Memory Debugging
Enable GPA safety checks:- Memory allocations
- Leaks
- Double-frees
- Use-after-free
Key Zig Modules
The native core includes:- lib.zig - Main FFI exports
- renderer.zig - Core rendering engine
- buffer.zig - Frame buffer management
- text-buffer.zig - Text editor buffer
- rope.zig - Rope data structure
- utf8.zig - UTF-8 and grapheme processing
- terminal.zig - Terminal capabilities
- ansi.zig - ANSI escape sequences
- grapheme.zig - Grapheme boundary detection
- editor-view.zig - Editor viewport
- edit-buffer.zig - Edit operations
- syntax-style.zig - Syntax highlighting
- event-bus.zig - Native event system
- logger.zig - Native logging
- native-span-feed.zig - Stream rendering
Dependencies
The Zig core uses:- uucode - Unicode data (grapheme breaks, widths, emoji)
- std - Zig standard library
build.zig.zon:
Performance Considerations
Zero-Copy Operations
The FFI layer uses pointers to avoid copying:Batch Operations
Batch FFI calls to reduce overhead:Memory Pooling
The native core uses memory pools for:- Render buffers
- Text segments
- Rope nodes
- Event objects
Contributing to Native Core
When contributing Zig code:-
Follow style guide
- Use Zig fmt:
zig fmt src/ - Follow existing naming conventions
- Add tests for new features
- Use Zig fmt:
-
Write tests
-
Benchmark performance
-
Update FFI bindings
- Export new functions in lib.zig
- Add TypeScript bindings
- Update type definitions
-
Document behavior
- Add comments for public APIs
- Update relevant docs
Next Steps
Performance
Learn performance optimization
Testing
Test your TUI applications