---
url: https://listr2.kilic.dev/renderer/custom.md
---

# {{ $frontmatter.title }}

You can create a custom renderer that is fit for your application.

## Implement or Extend the Default *Listr* Renderer

<<< @../../examples/docs/renderer/custom/create-renderer.ts#create

::: info

For Javascript, since you cannot implement `ListrRenderer`, you can extend either the *SilentRenderer* or `ListrBaseRenderer`.

:::

## Utilizing the *Task*

Take a look at *DefaultRenderer* since it is implemented this way.

::: details  Code Example

<<< @../../packages/listr2/src/renderer/default/renderer.ts

:::

## Utilizing the Events

*Listr* and its *Task* fires many events to indicate the task status. *Task* depending on what is currently done will fire [ListrTaskState](/api/listr2/enumerations/ListrTaskState.html) and [ListrTaskEventType](/api/listr2/enumerations/ListrTaskEventType.html) through [ListrTaskEventManager](/api/listr2/classes/ListrTaskEventManager.html) which you can subscribe to.

Take a look at *SimpleRenderer* or *VerboseRenderer* since it is implemented this way.

A renderer that buffers per-task output — as the *DefaultRenderer* does for its output bar and bottom bar — subscribes to the individual *Task* through `task.on(...)`, reacting to [`ListrTaskEventType`](/api/listr2/enumerations/ListrTaskEventType.html) events such as `OUTPUT`, `OUTPUT_RESET`, `STATE` and `PROMPT`.

::: details  Code Example

<<< @../../packages/listr2/src/renderer/simple/renderer.ts

:::

::: details  Code Example

<<< @../../packages/listr2/src/renderer/verbose/renderer.ts

:::

## Using Render Hooks

Additional to listening to the events, another singleton hook that comes from the root *Listr* is `events`. This provides some generic events like [`ListrEventType.SHOULD_REFRESH_RENDER`](/api/listr2/enumerations/ListrEventType.html#should-refresh-render) which can be used to trigger an update on an updating renderer.

These `events` can be the third optional variable of a given renderer while using it is always optional.

```typescript
export class MyAmazingRenderer implements ListrRenderer {
  constructor(
    private readonly tasks: ListrDefaultRendererTasks,
    private readonly options: ListrDefaultRendererOptions,
    private readonly events: ListrEventManager
  ) {}
}
```

These events can be later listened to trigger an update.

```typescript
this.events.on(ListrEventType.SHOULD_REFRESH_RENDER, () => {
  this.update()
})
```

## Using a Custom Renderer

You can tell Listr to use your custom renderer by setting the `renderer` option in *Listr* to your custom renderer.

<<< @../../examples/docs/renderer/custom/create-renderer.ts#run
