# How to Use TuiLoggerWidget Instead of the Smart Widget in tui-logger

> Learn to use TuiLoggerWidget instead of the smart widget in tui-logger. Instantiate TuiLoggerWidget directly and configure it for custom styling and output formatting in your ratatui app.

- Repository: [gin66/tui-logger](https://github.com/gin66/tui-logger)
- Tags: how-to-guide
- Published: 2026-03-02

---

**To use the standard widget instead of the smart widget, instantiate `TuiLoggerWidget` directly with a shared `TuiWidgetState`, configure it with the same builder methods for styling and output formatting, and call its `render` method within your ratatui draw loop.**

The `tui-logger` crate provides two primary widgets for rendering log output in terminal user interfaces built with ratatui. While `TuiLoggerSmartWidget` offers a convenience layout that includes a target selector panel alongside the log view, the standard `TuiLoggerWidget` provides a cleaner implementation when you only need a dedicated log pane without the additional target management UI.

## Architectural Differences Between Standard and Smart Widgets

Understanding the relationship between these components helps clarify when to use each approach.

**`TuiLoggerWidget`** (defined in [`src/widget/standard.rs`](https://github.com/gin66/tui-logger/blob/main/src/widget/standard.rs)) handles the core rendering of log records, including formatting timestamps, log levels, and source locations. It manages scrolling and styling but does not include any target selection interface.

**`TuiLoggerSmartWidget`** (located in [`src/widget/smart.rs`](https://github.com/gin66/tui-logger/blob/main/src/widget/smart.rs)) acts as a thin wrapper that combines a `TuiLoggerWidget` with a `TuiLoggerTargetWidget` (defined in [`src/widget/target.rs`](https://github.com/gin66/tui-logger/blob/main/src/widget/target.rs)). At runtime, it decides whether to display the target selector based on the current widget state, adding extra layout complexity that you may not need.

Both widgets rely on **`TuiWidgetState`** (from [`src/widget/inner.rs`](https://github.com/gin66/tui-logger/blob/main/src/widget/inner.rs)) to hold shared UI state such as scroll position and display filters via an internal `Arc<Mutex<_>>`.

## Minimal Implementation of TuiLoggerWidget

To render a basic log pane without the target selector, create a `TuiWidgetState` instance and pass it to `TuiLoggerWidget` using the builder pattern.

```rust
use ratatui::{
    backend::Backend,
    layout::Rect,
    style::{Color, Style},
    widgets::{Block, Borders, Widget},
    Terminal,
};
use tui_logger::{init_logger, set_default_level, TuiLoggerWidget, TuiWidgetState, LevelFilter};

fn main() -> anyhow::Result<()> {
    // Initialize the logging backend
    init_logger(LevelFilter::Trace)?;
    set_default_level(LevelFilter::Trace);

    // Create shared UI state with default display level
    let mut state = TuiWidgetState::new()
        .set_default_display_level(LevelFilter::Info);

    // Build the standard widget with formatting options
    let log_widget = TuiLoggerWidget::default()
        .block(Block::bordered().title("Standard Log"))
        .style(Style::default().fg(Color::White))
        .output_separator(':')
        .output_timestamp(Some("%H:%M:%S".to_string()))
        .output_level(Some(tui_logger::TuiLoggerLevelOutput::Abbreviated))
        .state(&state);  // Shares the Arc<Mutex<_>> containing scroll position and filters

    // Render inside your ratatui draw loop
    // term.draw(|frame| {
    //     let area = frame.area();
    //     log_widget.render(area, frame.buffer_mut());
    // })?;

    Ok(())
}

```

The `state(&state)` method copies the internal `Arc<Mutex<_>>` into the widget, allowing it to read the shared log buffer and respond to scroll commands. All builder methods available on `TuiLoggerSmartWidget`—including `style_error`, `style_debug`, `output_target`, and `output_file`—work identically on `TuiLoggerWidget`.

## Replacing TuiLoggerSmartWidget in Existing Code

If you are migrating from the smart widget to the standard widget, remove the smart wrapper and call `TuiLoggerWidget` directly. The following example adapts the pattern found in [`examples/demo.rs`](https://github.com/gin66/tui-logger/blob/main/examples/demo.rs) (lines approximately 283-296).

**Before (Smart Widget):**

```rust
TuiLoggerSmartWidget::default()
    .style_error(Style::default().fg(Color::Red))
    .style_debug(Style::default().fg(Color::Green))
    .style_warn(Style::default().fg(Color::Yellow))
    .style_trace(Style::default().fg(Color::Magenta))
    .style_info(Style::default().fg(Color::Cyan))
    .output_separator(':')
    .output_timestamp(Some("%H:%M:%S".to_string()))
    .output_level(Some(TuiLoggerLevelOutput::Abbreviated))
    .output_target(true)
    .output_file(true)
    .output_line(true)
    .state(self.selected_state())
    .render(smart_area, buf);

```

**After (Standard Widget):**

```rust
TuiLoggerWidget::default()
    .block(Block::bordered().title("Standard Log"))
    .style_error(Style::default().fg(Color::Red))
    .style_debug(Style::default().fg(Color::Green))
    .style_warn(Style::default().fg(Color::Yellow))
    .style_trace(Style::default().fg(Color::Magenta))
    .style_info(Style::default().fg(Color::Cyan))
    .output_separator(':')
    .output_timestamp(Some("%H:%M:%S".to_string()))
    .output_level(Some(TuiLoggerLevelOutput::Abbreviated))
    .output_target(true)
    .output_file(true)
    .output_line(true)
    .state(self.selected_state())
    .render(smart_area, buf);

```

This change removes the conditional target selector logic while preserving all formatting and output options. The standard widget renders only the log records according to the layout area you provide.

## Key Source Files for Reference

When working with the standard widget, these implementation files provide authoritative details on behavior and API:

- **[`src/widget/standard.rs`](https://github.com/gin66/tui-logger/blob/main/src/widget/standard.rs)** – Contains the `TuiLoggerWidget` struct and its `Widget` trait implementation, including the builder methods for styling and output configuration.
- **[`src/widget/smart.rs`](https://github.com/gin66/tui-logger/blob/main/src/widget/smart.rs)** – Demonstrates how the smart widget wraps the standard widget and forwards configuration options.
- **[`src/widget/inner.rs`](https://github.com/gin66/tui-logger/blob/main/src/widget/inner.rs)** – Defines `TuiWidgetState` and the internal state management shared between widgets.
- **[`src/widget/target.rs`](https://github.com/gin66/tui-logger/blob/main/src/widget/target.rs)** – Implements `TuiLoggerTargetWidget`, which is excluded when using the standard widget directly.
- **[`examples/demo.rs`](https://github.com/gin66/tui-logger/blob/main/examples/demo.rs)** – Shows side-by-side usage of both widget types in a full application context.

## Summary

- **Use `TuiLoggerWidget`** (from [`src/widget/standard.rs`](https://github.com/gin66/tui-logger/blob/main/src/widget/standard.rs)) when you need a plain log pane without the target selector overhead.
- **Share state** via `TuiWidgetState` passed to the `state()` builder method; this manages scroll position and filtering through an internal `Arc<Mutex<_>>`.
- **Apply identical configuration** using builder methods like `style_error`, `output_timestamp`, `output_target`, and `block` that work the same way on both widget types.
- **Call `render(area, buf)`** directly since `TuiLoggerWidget` implements the ratatui `Widget` trait, fitting seamlessly into any ratatui layout.

## Frequently Asked Questions

### How do I hide the target selector that appears with TuiLoggerSmartWidget?

Switch to `TuiLoggerWidget` instead of `TuiLoggerSmartWidget`. The smart widget explicitly includes `TuiLoggerTargetWidget` to render the target selector panel, while the standard widget in [`src/widget/standard.rs`](https://github.com/gin66/tui-logger/blob/main/src/widget/standard.rs) renders only the log output. Both widgets accept the same state and configuration builders, so migration requires only changing the struct name and adding a `block` if desired.

### Can I use TuiLoggerWidget without TuiWidgetState?

No. The widget requires access to shared UI state to determine scroll position and which log records to display. You must create a `TuiWidgetState` (defined in [`src/widget/inner.rs`](https://github.com/gin66/tui-logger/blob/main/src/widget/inner.rs)) and pass it via the `state(&state)` builder method. This state contains the `Arc<Mutex<TuiWidgetInnerState>>` that the widget needs to access the global log ring buffer.

### What styling options are available for TuiLoggerWidget?

The widget supports per-level styling through methods like `style_error`, `style_warn`, `style_info`, `style_debug`, and `style_trace`, each accepting a ratatui `Style` struct. You can also configure the separator character with `output_separator`, timestamp format with `output_timestamp`, and toggle metadata columns like target names, filenames, and line numbers using `output_target`, `output_file`, and `output_line`.

### How do I initialize the logging system before creating the widget?

Call `init_logger` from [`src/logger/api.rs`](https://github.com/gin66/tui-logger/blob/main/src/logger/api.rs) with a `LevelFilter` (such as `LevelFilter::Trace` or `LevelFilter::Info`) before creating any widgets. This sets up the global logger that `TuiLoggerWidget` reads from. You can also use `set_default_level` to control the default verbosity for specific targets before the UI renders.