Skip to content

Advanced Customization

Advanced customization is ratatui-kit’s escape hatch, not the starting point for learning the framework. React places these topics under Escape Hatches, and Vue keeps composition reuse, plugins, and rendering mechanisms in later chapters. ratatui-kit follows the same principle: compose built-in components, hooks, input layers, and Router first; drop down to custom abilities only once the framework boundaries are clear.

Compose first

Start by composing business state, input exclusivity, modals, lists, and long text with existing components and hooks. If composition solves it, do not rush into handwritten runtime capability.

Keep boundaries clear

Custom hooks own logic reuse, Providers own scoped dependencies, and handwritten Components own drawing and layout. Do not let one abstraction take over everything at once.

Keep the test surface

Advanced examples still need to run with cargo run --example ... and produce real VHS recordings. Docs should not describe an imagined API.

ProblemPreferred pathContinue reading
Multiple components repeat the same state, derived data, or event handlingWrite a compositional use_* functionCustom Hook
A subtree needs the same theme, workspace, service handle, or permission contextWrap a Provider / ContextProviderCustom Provider
Existing built-in components do not cover a ratatui widget or stateful widgetHandwrite Component::drawNative Widget Bridging
Child regions are no longer ordinary flex splitsOverride calc_children_areasRender Loop
You need to understand why state is preserved or why events do not pass throughReturn to the core model firstComponent Model / Input Layers

Many requirements that look like “framework extension” are really scope mistakes:

  • Keep page-private state in use_state first; do not default to Atom.
  • Use Provider for cross-subtree configuration; do not use process-wide global state just because props travel far.
  • Use built-in components for modals, search inputs, and confirmation flows; do not reinvent input exclusivity.
  • Use use_memo for derived data; do not copy it into a second mutable state value.
  • Draw during draw; do not trigger reactive writes there.

If one custom abstraction needs to change the state model, input model, layout model, and drawing model at the same time, it is usually not small enough yet. Split the problem into testable hooks, providers, or components first, then decide whether a framework-level API is needed.

Every advanced tutorial here follows the same constraints:

  • It has real source code under examples/advanced/.
  • It has a stable command such as cargo run --example custom_hook.
  • It has a VHS tape under docs/tapes/.
  • It has real runtime media under docs/public/recordings/.
  • The docs show the running result before explaining abstraction boundaries.
  • If the docs reveal awkward API or unclear semantics, fix the framework first and then update the docs.

You can start with Custom Hook. It is the most common and lowest-risk extension style, and the best place to extract experience from business code.