Skip to content

Renderer

The renderer is the output abstraction in Klix. It gives the rest of the framework a small semantic surface for printing and screen clearing without exposing rich-specific details everywhere.

See also:

Why It Exists

Not every terminal environment is a good match for full rich output. Klix uses a renderer layer so the rest of the framework can say:

  • print this text
  • use this semantic color
  • clear the screen

and let the renderer decide how to do that.

Renderer Types

Current renderer classes:

  • RichRenderer
  • FallbackRenderer
  • CIRenderer

The selection happens in klix.compat.get_renderer().

RichRenderer

This is the normal interactive path. It:

  • creates a rich.console.Console
  • resolves semantic theme names like accent and error
  • prints styled output through rich

Example:

python
session.ui.print("Saved.", color="success", bold=True)

If rich is active, that becomes styled output through the console.

FallbackRenderer

Fallback mode prints plain text and clears with escape sequences. It is intentionally minimal.

Use it as the baseline behavior when:

  • colors are not reliable
  • the terminal is very limited
  • you care more about robustness than presentation

CIRenderer

CIRenderer currently inherits from FallbackRenderer. It exists as a distinct mode because CI and pipes are a meaningful behavior boundary in the framework.

In practice, CI mode affects both:

  • output rendering
  • input behavior

See Input Engine.

Color Resolution

Renderers accept either:

  • raw color values
  • semantic names from ThemeConfig

For example:

python
session.ui.print("Warning", color="warning")
session.ui.print("Custom", color="#FFAA00")

Current Limitations

The renderer layer is intentionally narrow:

  • it is not a full layout engine
  • it does not own complex stateful screen management
  • rich widgets are built above it in session.ui.output

That is a good thing. It keeps the boundary clean.

Pitfalls

Writing component code against rich.console.Console directly everywhere

If you skip the renderer surface entirely, your code becomes harder to run in fallback environments.

Treating CIRenderer as just visual fallback

It is also a signal that input should become non-interactive.

Released under the MIT License.