▉Measured Sep 13, 2026

OpenTUI vs BetterTUI
Benchmarks

Every number on this page comes from the published npm packages running identical workloads in fresh processes — no workspace shortcuts, no estimates.

@opentui/core0.5.11VS@bettertui/core0.1.1
10 benchmark apps15 metrics2 frameworks

Overview

What the Numbers Show

Measured results, including where OpenTUI wins. Green badges mark BetterTUI ahead; grey badges mark OpenTUI ahead.

BetterTUI 66%

Deep tree frame (5.1k nodes)

Dirty frame, large-tree benchmark

OpenTUI96.8ms
BetterTUI32.7ms
OpenTUI 29%

Memory on large apps (RSS)

Average across large workloads

OpenTUI206MB
BetterTUI266MB
BetterTUI 66%

Module import time

Average module load, fresh process

OpenTUI41ms
BetterTUI14ms
BetterTUI 211%

Max renderables built

OpenTUI cannot construct the 20k and 50k apps (native cap 16,382)

OpenTUI16,382 (cap)
BetterTUI51,001
OpenTUI 26%

Small-app frame

Hello World / Counter / Dashboard average

OpenTUI0.09ms
BetterTUI0.11ms
OpenTUI 91%

Bundle on disk

Installed package size incl. native binaries

OpenTUI13.1MB
BetterTUI24.9MB

Visual Comparison

Dirty Frame Time Per App

Mean time to apply a bulk update and render a complete frame (logarithmic scale). Shorter bars are better.

OpenTUI
BetterTUI
Hello World
27µs
34µs
Counter
21µs
38µs
Large List
13ms
21ms
Large Table
native renderable cap hit (16,382)
67ms
Large Tree
97ms
33ms
Dashboard
224µs
270µs
Markdown Viewer
986µs
1.09ms
Animation
39µs
43µs
Terminal Scroll
237µs
6.83ms
Stress Test
native renderable cap hit (16,382)
165ms

Log scale — each major grid division is a 10× step in frame time. Bars are not proportional to absolute difference.

Detailed Results

Per-App Breakdown

Each app runs an identical workload in both frameworks. Frame = bulk update + render; update = single-node change + render; RSS = memory after the workload. The verdict column names the faster framework on frame time.

Hello World

Single text node

OpenTUI 26%
OpenTUI
Frame 27µs
Update 19µs
FPS 40472
BetterTUI
Frame 34µs
Update 32µs
FPS 25197

Counter

State + re-render on key

OpenTUI 81%
OpenTUI
Frame 21µs
Update 21µs
FPS 37354
BetterTUI
Frame 38µs
Update 35µs
FPS 23383

Large List

10k text rows in one column

OpenTUI 66%
OpenTUI
Frame 13ms
Update 13ms
FPS 79
BetterTUI
Frame 21ms
Update 21ms
FPS 48

Large Table

1k rows x 20 columns of text cells

OpenTUI limit
OpenTUI
Frame cannot build
Update —
FPS —
BetterTUI
Frame 67ms
Update 76ms
FPS 15

Large Tree

5.1k nodes: 8-level binary box tree with text leaves

BetterTUI 66%
OpenTUI
Frame 97ms
Update 10ms
FPS 10
BetterTUI
Frame 33ms
Update 33ms
FPS 31

Dashboard

Mixed bordered panels, stats, input

OpenTUI 21%
OpenTUI
Frame 224µs
Update 51µs
FPS 5382
BetterTUI
Frame 270µs
Update 246µs
FPS 3314

Markdown Viewer

600 lines of styled text

OpenTUI 11%
OpenTUI
Frame 986µs
Update 509µs
FPS 1045
BetterTUI
Frame 1.09ms
Update 1.10ms
FPS 911

Animation

Text + box size changes every frame

OpenTUI 10%
OpenTUI
Frame 39µs
Update 39µs
FPS 24497
BetterTUI
Frame 43µs
Update 54µs
FPS 9903

Terminal Scroll

2k rows viewport scroll stress

OpenTUI 2780%
OpenTUI
Frame 237µs
Update 212µs
FPS 4954
BetterTUI
Frame 6.83ms
Update 6.82ms
FPS 149

Stress Test

50k text nodes

OpenTUI limit
OpenTUI
Frame cannot build
Update —
FPS —
BetterTUI
Frame 165ms
Update 166ms
FPS 6

Measured Pipeline

What a Frame Costs

Every stage below is measured on the dashboard app — import and startup from a fresh process, then per-frame costs from timed render passes. No stage is estimated.

Import
OpenTUI30.5ms
BetterTUI11.0ms

Module load, fresh process

Startup
OpenTUI9.0ms
BetterTUI5.7ms

Renderer + mount + first frame

Keypress → frame
OpenTUI79µs
BetterTUI260µs

Real input pipeline to update

Single update
OpenTUI51µs
BetterTUI246µs

One node change + render

Bulk dirty frame
OpenTUI224µs
BetterTUI270µs

All stats mutated + render

Clean frame
OpenTUI37µs
BetterTUI1µs

Render with no changes

Interactive

Explore the Data

Pick a metric and a benchmark app to see how BetterTUI compares to OpenTUI in real time.

Selected metric

Dirty Framems

Lower is better

Time to apply a bulk update and render the resulting frame.

Shorter bars are better.

Click to change

Click the menu to compare another benchmark workload.

10 benchmark apps
OpenTUI96.83ms
BetterTUI32.67ms

BetterTUI: 66% lower

BetterTUI records 32.67ms compared with 96.83ms.

BetterTUI: 66% lower

Values are medians across sampled frames and repeated fresh processes.

Methodology

How the Benchmarks Run

Both frameworks are installed from the public npm registry — no workspace links — and measured in the same headless terminal on the same machine.

Generated
Sep 13, 2026, 10:52 AM UTC
Runtime
bun 1.4.2
Machine
Apple M4 · arm64
OS
darwin 25.6.0
Terminal
120×40 headless
Packages
@opentui/core@0.5.11 · @bettertui/core@0.1.1

Benchmark Apps (10)

01
Hello World
Single text node
02
Counter
State + re-render on key
03
Large List
10k text rows in one column
04
Large Table
1k rows x 20 columns of text cells
05
Large Tree
5.1k nodes: 8-level binary box tree with text leaves
06
Dashboard
Mixed bordered panels, stats, input
07
Markdown Viewer
600 lines of styled text
08
Animation
Text + box size changes every frame
09
Terminal Scroll
2k rows viewport scroll stress
10
Stress Test
50k text nodes

Metrics Collected (15)

Import Time
Module load in a fresh process
Startup Time
Renderer creation + app build + first frame
Clean Frame
Render pass with no state changes
Dirty Frame
Bulk mutation + full frame render
Single Update
One node change + render
Input Latency
Keypress through the input pipeline to frame
Scroll Latency
Scroll step to rendered frame
FPS
Sustained dirty-frame rate over a burst window
Smoothness
Share of burst frames within the 16.67ms budget
CPU Usage
Process CPU during the burst (100 = one core)
Memory RSS
Resident set after the workload
Memory Heap
JS heap used after the workload
Terminal Throughput
Terminal cells pushed per second
Render Mem Cost
RSS growth across the burst window
Bundle Size
Installed package size on disk

Protocol

Each framework×app pair runs in its own fresh process. After 20 warmup frames, sample counts adapt to the measured frame cost (slow apps get fewer samples, capped by a per-phase time budget). Input latency drives each framework’s real input pipeline through mock key events; FPS, smoothness, and CPU come from a sustained burst of back-to-back dirty frames. Memory is read after a forced GC. Everything is timed with performance.now() around each framework’s own test-renderer step.

Read the full methodology report →

Reproducible on your machine

Run the benchmarks yourself

Clone the repo, run the same public packages, and inspect every result locally.

Run locally
pnpm --filter @bettertui/benchmark-comparison bench

No workspace links or hidden shortcuts.