# Getting Started URL: /docs/ink Build AI chat interfaces for the terminal with @assistant-ui/react-ink. Quick Start \[#quick-start] The fastest way to get started with assistant-ui for the terminal. Create a new project \[#create-a-new-project] ```sh npx assistant-ui@latest create --ink my-chat-app cd my-chat-app ``` Install dependencies \[#install-dependencies] ```sh pnpm install ``` Start the app \[#start-the-app] ```sh pnpm dev ``` Manual Setup \[#manual-setup] If you prefer to add assistant-ui to an existing Node.js project, follow these steps. Install dependencies \[#install-dependencies-1] ```sh npm install @assistant-ui/react-ink @assistant-ui/react-ink-markdown ink react ``` Create a chat model adapter \[#create-a-chat-model-adapter] Define how your app communicates with your AI backend. This example uses a simple streaming adapter: ```ts title="adapters/my-chat-adapter.ts" import type { ChatModelAdapter } from "@assistant-ui/react-ink"; export const myChatAdapter: ChatModelAdapter = { async *run({ messages, abortSignal }) { const response = await fetch("http://localhost:3000/api/chat", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ messages }), signal: abortSignal, }); const reader = response.body?.getReader(); if (!reader) throw new Error("No response body"); const decoder = new TextDecoder(); let fullText = ""; while (true) { const { done, value } = await reader.read(); if (done) break; const chunk = decoder.decode(value, { stream: true }); fullText += chunk; yield { content: [{ type: "text", text: fullText }] }; } }, }; ``` This is the same `ChatModelAdapter` interface used in `@assistant-ui/react` and `@assistant-ui/react-native`. If you already have an adapter, you can reuse it as-is. Set up the runtime \[#set-up-the-runtime] ```tsx title="app.tsx" import { Box, Text } from "ink"; import { AssistantProvider, useLocalRuntime, } from "@assistant-ui/react-ink"; import { myChatAdapter } from "./adapters/my-chat-adapter.js"; export function App() { const runtime = useLocalRuntime(myChatAdapter); return ( My Terminal Chat {/* your chat UI */} ); } ``` Build your chat UI \[#build-your-chat-ui] Use primitives to compose your terminal chat interface: ```tsx title="components/thread.tsx" import { Box, Text } from "ink"; import { ThreadRoot, ThreadMessages, ThreadEmpty, ComposerInput, useThreadIsRunning, } from "@assistant-ui/react-ink"; import type { ThreadMessage } from "@assistant-ui/react-ink"; import { MarkdownText } from "@assistant-ui/react-ink-markdown"; const Message = ({ message }: { message: ThreadMessage }) => { const isUser = message.role === "user"; const text = message.content .filter((p) => p.type === "text") .map((p) => ("text" in p ? p.text : "")) .join(""); if (isUser) { return ( You: {text} ); } return ( AI: ); }; const StatusIndicator = () => { const isRunning = useThreadIsRunning(); if (!isRunning) return null; return ( Thinking... ); }; export const Thread = () => { return ( No messages yet. Start typing below! } /> {"> "} ); }; ``` Render with Ink \[#render-with-ink] ```tsx title="index.tsx" import { render } from "ink"; import { App } from "./app.js"; render(); ``` What's Next? \[#whats-next]