# Drop-in chat

A complete, streaming chat app from a single <kai-chat> element — the 90% path.

One element gives you the whole experience: a message thread with markdown, reasoning, and tool calls, a composer, and optional header chrome. You bring the model; `<kai-chat>` renders the UI. The thread starts empty with a few starter suggestions — click one to begin, and the reply streams in.

## Wire it up

Start with an empty thread and a few `suggestions`. The chips render in the empty state and disappear once the conversation has a message, so they read as conversation starters. Assign both in JavaScript (arrays can't be HTML attributes), then handle `kai-submit`: append the user's turn, add an empty assistant message, and grow its `parts` as tokens arrive.

```html
<kai-chat id="chat" chat-title="Assistant" placeholder="Ask anything…"></kai-chat>

<script type="module">

  await customElements.whenDefined('kai-chat');

  const chat = document.getElementById('chat');
  chat.messages = [];
  chat.suggestions = [
    'What makes AI/UI different from rolling my own?',
    'Show me a streaming example',
  ];

  chat.addEventListener('kai-submit', async (e) => {
    const prompt = e.detail.value;
    const aId = crypto.randomUUID();
    // append the user turn + an empty assistant message
    chat.messages = [
      ...chat.messages,
      { id: crypto.randomUUID(), role: 'user', parts: [{ type: 'text', text: prompt }] },
      { id: aId, role: 'assistant', parts: [] },
    ];
    chat.loading = true;

    // stream tokens from your backend into the assistant message
    let answer = '';
    for await (const token of streamFromYourModel(prompt)) {
      answer += token;
      chat.messages = chat.messages.map((m) =>
        m.id === aId ? { ...m, parts: [{ type: 'text', text: answer }] } : m,
      );
    }
    chat.loading = false;
  });
</script>
```

The key move is reassigning `chat.messages` to a **new array** on each token — that's what drives the re-render.

## Next steps

- **[Installation](/guides/installation/)** and your **[framework](/guides/frameworks/overview/)** — register and use `<kai-chat>` anywhere.
- **[Streaming recipe](/guides/recipes/streaming/)** — parsing SSE and driving the loop from a real backend.
- **[`kai-chat` reference](/components/chat/)** — every prop and event (model switcher, context meter, suggestions, slash commands, voice).
- **[Compose your own shell](/patterns/compose-your-own/)** — when you need more control than one element gives.
