Project Setup
This page covers the Cargo.toml patterns you need when consuming
FrankenTUI from your own project. It also documents the per-crate
feature flags and the release-profile exception for ftui-extras.
Read this after installation and hello-tick. If you want to contribute to the FrankenTUI workspace itself (not depend on it), see dev loop.
Until the remaining 17 crates reach crates.io, the expected setup is a
workspace path dependency on the FrankenTUI checkout sitting next to
your project. The three crates already on crates.io (ftui-core,
ftui-layout, ftui-i18n) can be pulled from the registry, but for the
full stack you want path deps.
Mental model
The ftui facade crate re-exports what most consumers need. If you want
finer control — say, to skip ftui-widgets and build your own widget
library on top of ftui-render — depend on the individual crates
directly.
Minimal Cargo.toml
path dependency
Recommended while the workspace is still moving:
[package]
name = "my-tui-app"
version = "0.1.0"
edition = "2024"
[dependencies]
ftui = { path = "../frankentui/crates/ftui" }
[profile.release]
opt-level = "z"
lto = true
codegen-units = 1
panic = "abort"
strip = true
# IMPORTANT: keep opt-level = 3 for ftui-extras if you use the VFX
# rasterizer. Dropping this loses ~10× on VFX frame cost.
[profile.release.package.ftui-extras]
opt-level = 3Rust toolchain
FrankenTUI requires nightly Rust. Pin it in your own project so
contributors don’t hit mysterious -Z errors:
[toolchain]
channel = "nightly"
components = ["rust-src", "rustfmt", "clippy"]Release profile
FrankenTUI’s own workspace uses a size-optimized release profile with a single package-level override. The override is load-bearing — copy it into your own project if you use visual effects:
[profile.release]
opt-level = "z" # Optimize for size
lto = true # Link-time optimization
codegen-units = 1 # Better cross-module inlining
panic = "abort" # Smaller binary, no unwinding overhead
strip = true # Remove debug symbols
[profile.release.package.ftui-extras]
opt-level = 3Dropping opt-level = 3 for ftui-extras means the VFX rasterizer
inner loops stop auto-vectorizing. The Gray-Scott, metaballs, and
fractal effects become roughly 10× slower per frame. See
design decisions.
Feature flags
Most FrankenTUI crates have small, orthogonal feature flags. Default
features are [] — nothing is pulled in unless you ask.
| Crate | Feature | What it enables |
|---|---|---|
ftui-core | tracing | Structured spans for terminal lifecycle |
ftui-core | tracing-json | JSON output via tracing-subscriber |
ftui-render | tracing | Performance spans for diff / presenter |
ftui-runtime | tracing | Runtime loop instrumentation |
ftui-runtime | telemetry | OpenTelemetry export (OTLP) |
Enable per-crate in your own Cargo.toml:
[dependencies]
ftui-core = { path = "../frankentui/crates/ftui-core", features = ["tracing"] }
ftui-runtime = { path = "../frankentui/crates/ftui-runtime", features = ["tracing", "telemetry"] }When a feature is off, the relevant dependencies are excluded entirely.
When telemetry is on but OTEL env vars are unset, overhead is a single
startup check. See docs/telemetry.md in the workspace for integration
patterns.
Workspace dependencies inside your own multi-crate project
If your project is itself a workspace, put FrankenTUI deps in the
workspace root and consume them with workspace = true:
[workspace]
members = ["crates/*"]
[workspace.dependencies]
ftui = { path = "../frankentui/crates/ftui" }
ftui-core = { path = "../frankentui/crates/ftui-core" }
ftui-runtime = { path = "../frankentui/crates/ftui-runtime" }
ftui-widgets = { path = "../frankentui/crates/ftui-widgets" }
[profile.release]
opt-level = "z"
lto = true
codegen-units = 1
panic = "abort"
strip = true
[profile.release.package.ftui-extras]
opt-level = 3[dependencies]
ftui = { workspace = true }This matches the pattern FrankenTUI itself uses. It keeps version pinning in one place.
Unsafe policy
FrankenTUI’s render, runtime, and layout crates declare
#![forbid(unsafe_code)]. If you build on top of them, consider doing
the same in your own crate. It’s a cheap audit signal and a reminder
that the pipeline does not need unsafe to be fast.
Build & test
From your project root:
cargo check --all-targets
cargo test
cargo clippy --all-targets -- -D warnings
cargo fmt --checkIf you’re consuming FrankenTUI via path deps, the first build is slow because Cargo has to compile the whole FrankenTUI workspace. Subsequent builds are incremental.
Pitfalls
Don’t mix published and path deps for the same crate. If you
depend on ftui-core = "0.3" in one crate and ftui-core = {path = ...}
in another, Cargo will see two distinct versions and cross-crate types
will not unify. Pick one source per crate, consistently across your
workspace.
Don’t forget the release-profile override for ftui-extras. If
you copy the workspace release profile but drop the package override,
the VFX rasterizer will compile at opt-level = "z" and the visual
effects demos will look janky.
Don’t add features to ftui-* in your own Cargo.toml that aren’t
listed in their Cargo.toml. FrankenTUI’s feature set is small on
purpose. If you need something that isn’t there, file a bug before
patching it locally.