Before contributing, read:
docs/DESIGN_PRINCIPLES.md— Why things are the way they aredocs/ARCHITECTURE.md— How the code is organizeddocs/WIDGETS.md— Which APIs and state types live wheredocs/TESTING.md— How to verify widget and layout behaviordocs/BACKENDS.md— Low-level backend and run-loop contracts
git clone https://github.com/subinium/SuperLightTUI.git
cd superlighttui
cargo test
cargo run --example democargo build
cargo build --features asynccargo test --all-features
cargo clippy --all-features -- -D warningscargo run --example hello
cargo run --example counter
cargo run --example demo
cargo run --example inline
cargo run --example anim
cargo run --example async_demo --features asynccargo fmt -- --check
cargo check --all-features
cargo clippy --all-features -- -D warnings
cargo test --all-features
cargo check --examples --all-features- Use Conventional Commits:
feat:,fix:,refactor:,docs:,chore:,test: - Run the full quality gate above before submitting
- One logical change per PR
- Add examples for new widgets
- The PR template includes a checklist — complete it
- No
unsafecode — enforced by#![forbid(unsafe_code)] - No
unwrap()in functions returningResult— enforced by lint - No
println!()/eprintln!()/dbg!()in library code — enforced by lint - No unnecessary comments — code should be self-documenting
- Use
self.theme.Xfor colors, never hardcode
Follow this checklist when adding a new widget:
- State struct in
widgets.rs— name it{Widget}State, implementDefault - State placement in the matching
src/widgets/*.rsgroup file, then surfaced throughsrc/widgets.rs - Rendering method on
Contextin the matchingsrc/context/widgets_*/subfile (widgets_input/,widgets_display/,widgets_interactive/, orwidgets_viz.rs) - Re-export in
lib.rs - Doc comment (
///) on the public method with usage example - Response pattern — interactive widgets return
Response, display widgets return&mut Self - Focus — call
register_focusable()if the widget accepts keyboard input - Events — consume handled key events so they don't bubble
- Theme — use
self.theme.*for default colors - Example — add to an existing example or create a new one
See docs/DESIGN_PRINCIPLES.md — Error Handling for the full policy.
Summary:
- Use
io::Resultfor fallible operations panic!()only for programmer errors (with descriptive messages)- No custom error types —
io::Erroris sufficient for SLT's error paths
See docs/ARCHITECTURE.md for the full module map and data flow.
User closure → Context collects Commands → build_tree() → flexbox compute → render to Buffer → diff → flush
- Immediate mode: Each frame, the closure runs and describes the UI
- Double buffer: Previous and current buffers are diffed, only changes are flushed
- Flexbox: Row/column layout with gap, grow, shrink
- One-frame delay: Layout-computed data (focus count, scroll bounds, hit areas) feeds back to the next frame via
prev_*fields
Releases are automated via GitHub Actions. To publish a new version:
# 1. Bump version in Cargo.toml
# 2. Update CHANGELOG.md with new section
# 3. Commit and push
git add Cargo.toml Cargo.lock CHANGELOG.md
git commit -m "chore: release vX.Y.Z"
git push
# 4. Tag triggers the release pipeline
git tag vX.Y.Z
git push --tagsThe release workflow (.github/workflows/release.yml) will:
- Run full CI (check, test, clippy, fmt) on stable + MSRV 1.81
- Verify tag matches
Cargo.tomlversion - Publish to crates.io
- Create GitHub Release with notes extracted from CHANGELOG.md
Do not run cargo publish manually — let the workflow handle it.
Core: unicode-width, compact_str. Terminal I/O: crossterm (default feature). Optional: tokio (async), serde, image, qrcode, flate2 (kitty-compress), tree-sitter syntax features.
Do not add new dependencies without discussion. See docs/DESIGN_PRINCIPLES.md — Dependencies.