# Streaming Text

> Animate handwriting as text streams in from an API or LLM, with the pen catching up to the stream as tokens arrive.

Source: https://tegaki.ink/guides/streaming/

Tegaki can animate text as it arrives from a streaming API, as in an AI chat interface.

## Approach

Use uncontrolled mode: it follows the growing text and writes new characters as they arrive. The `catchUp` option speeds up playback when there's buffered text, so the animation stays close to the stream without jumping.

**React**

```tsx
import { TegakiRenderer } from 'tegaki';

function StreamingMessage({ text, font }) {
  return (
    <TegakiRenderer
      font={font}
      time={{ mode: 'uncontrolled', speed: 4, catchUp: 0.5 }}
    >
      {text}
    </TegakiRenderer>
  );
}
```

**Svelte**

```svelte
<script>
  import { TegakiRenderer } from 'tegaki/svelte';
  let { text, font } = $props();
</script>

<TegakiRenderer
  {font}
  {text}
  time={{ mode: 'uncontrolled', speed: 4, catchUp: 0.5 }}
/>
```

**Vue**

```vue
<script setup>
import { TegakiRenderer } from 'tegaki/vue';
const props = defineProps<{ text: string; font: any }>();
</script>

<template>
  <TegakiRenderer
    :font="props.font"
    :text="props.text"
    :time="{ mode: 'uncontrolled', speed: 4, catchUp: 0.5 }"
  />
</template>
```

**Vanilla JS**

```js
import { TegakiEngine } from 'tegaki/core';

const engine = new TegakiEngine(container, {
  font: bundle,
  time: { mode: 'uncontrolled', speed: 4, catchUp: 0.5 },
});

// As chunks arrive:
engine.update({ text: accumulatedText });
```

Update `text` as chunks arrive from your API. The renderer writes whatever is new.

### Tuning

- **`speed`**: base playback speed multiplier (default `1`). Higher values write faster.
- **`catchUp`**: how hard the animation speeds up to close the gap when text arrives faster than it can be drawn. `0` disables catch-up (default). Typical range: `0.2` to `2`.

## Live demo

See the streaming chat on the [homepage](https://tegaki.ink/#stream) for a live example.
