# prompt-kit
> prompt-kit is a library of customizable, high-quality UI components for AI applications. It provides ready-to-use components for building chat experiences, AI agents, autonomous assistants, and more, with a focus on rapid development and beautiful design.
## Table of Contents
- [Installation](#installation)
- [Introduction](#introduction)
- [Components](#components)
- [Blocks](#blocks)
- [Prompt input](#prompt-input)
- [Code block](#code-block)
- [Markdown](#markdown)
- [Message](#message)
- [Chat container](#chat-container)
- [Scroll button](#scroll-button)
- [Loader](#loader)
- [Prompt suggestion](#prompt-suggestion)
- [Response stream](#response-stream)
- [Reasoning](#reasoning)
- [File upload](#file-upload)
- [Jsx preview](#jsx-preview)
- [Showcase](#showcase)
## Components
import { generateMetadata } from "../utils/metadata"
export const metadata = generateMetadata(
"Introduction",
"Introduction to prompt-kit."
)
**prompt-kit** is a set of customizable, high-quality components built for AI applications, making it easy to design chat experiences, AI agents, autonomous assistants, and more, quickly and beautifully.
**prompt-kit** is built on top of shadcn/ui with the same design principles. But instead of helping you build a component library, it helps you build AI interfaces.
This project is a work in progress, and we're continuously improving and expanding the collection. We'd love to hear your feedback or see your contributions as it evolves!
prompt-kit is open source. Check out the code and contribute on [GitHub](https://github.com/ibelick/prompt-kit).
import { generateMetadata } from "../utils/metadata"
export const metadata = generateMetadata(
"Installation",
"Installation guide for prompt-kit."
)
# Installation
## Prerequisites
Before installing, ensure you have the following:
- [Node.js](https://nodejs.org/en/download/) version **18** or later
- [React](https://react.dev/) version **19** or later
## Install shadcn/ui
First, you'll need to install and configure shadcn/ui in your project. Follow the installation guide at [shadcn/ui documentation](https://ui.shadcn.com/docs/installation).
Once shadcn/ui is set up, you can install **prompt-kit** components using the **shadcn CLI**.
## Using the shadcn CLI
## Usage
After installation, import and start using the components in your project:
import ComponentCodePreview from "@/components/app/component-code-preview"
import { generateMetadata } from "../utils/metadata"
import { PromptInputBasic } from "./prompt-input-basic"
import { PromptInputWithActions } from "./prompt-input-with-actions"
export const metadata = generateMetadata(
"Prompt Input",
"An input field that allows users to enter and submit text to an AI model."
)
# Prompt Input
An input field that allows users to enter and submit text to an AI model.
## Examples
### Prompt Input basic
}
filePath="app/docs/prompt-input/prompt-input-basic.tsx"
classNameComponentContainer="p-8"
/>
### Prompt Input with actions
You can use `PromptInputActions` to add actions with tooltips to the `PromptInput`.
}
filePath="app/docs/prompt-input/prompt-input-with-actions.tsx"
classNameComponentContainer="p-8"
/>
## Installation
CLIManualCopy and paste the following code into your project.Update the import paths to match your project setup.
## Component API
### PromptInput
| Prop | Type | Default | Description |
| :------------ | :---------------------- | :------ | :---------------------------------------------- |
| isLoading | boolean | false | Loading state of the input |
| value | string | | Controlled value of the input |
| onValueChange | (value: string) => void | | Callback when input value changes |
| maxHeight | number \| string | 240 | Maximum height of the textarea in pixels |
| onSubmit | () => void | | Callback when form is submitted (Enter pressed) |
| children | React.ReactNode | | Child components to render |
| className | string | | Additional CSS classes |
### PromptInputTextarea
| Prop | Type | Default | Description |
| :-------------- | :--------------------------------- | :------ | :------------------------------------- |
| disableAutosize | boolean | false | Disable automatic height adjustment |
| className | string | | Additional CSS classes |
| onKeyDown | (e: KeyboardEvent) => void | | Keyboard event handler |
| disabled | boolean | false | Disable the textarea input |
| ...props | `React.ComponentProps<"textarea">` | | All other textarea props are supported |
### PromptInputActions
| Prop | Type | Default | Description |
| :-------- | :------------------------------------- | :------ | :-------------------------------- |
| children | React.ReactNode | | Child components to render |
| className | string | | Additional CSS classes |
| ...props | `React.HTMLAttributes` | | All other div props are supported |
### PromptInputAction
| Prop | Type | Default | Description |
| :-------- | :------------------------------------- | :------ | :---------------------------------------------- |
| tooltip | React.ReactNode | | Content to show in the tooltip |
| children | React.ReactNode | | Child component to trigger the tooltip |
| className | string | | Additional CSS classes for the tooltip |
| side | "top" \| "bottom" \| "left" \| "right" | "top" | Position of the tooltip relative to the trigger |
| disabled | boolean | false | Disable the tooltip trigger |
| ...props | `React.ComponentProps` | | All other Tooltip component props are supported |
import ComponentCodePreview from "@/components/app/component-code-preview"
import { generateMetadata } from "../utils/metadata"
import { CodeBlockBasic } from "./code-block-basic"
import { CodeBlockCSS } from "./code-block-css"
import { CodeBlockNord } from "./code-block-nord"
import { CodeBlockPython } from "./code-block-python"
import { CodeBlockThemed } from "./code-block-themed"
import { CodeBlockWithHeader } from "./code-block-with-header"
export const metadata = generateMetadata(
"Code Block",
"A component for displaying code snippets with syntax highlighting and customizable styling."
)
# Code Block
A component for displaying code snippets with syntax highlighting and customizable styling.
## Examples
### Basic Code Block
}
filePath="app/docs/code-block/code-block-basic.tsx"
classNameComponentContainer="p-8"
/>
### Code Block with Header
You can use `CodeBlockGroup` to add a header with metadata and actions to your code blocks.
}
filePath="app/docs/code-block/code-block-with-header.tsx"
classNameComponentContainer="p-8"
/>
### Different Languages
You can highlight code in various languages by changing the `language` prop.
#### Python Example
}
filePath="app/docs/code-block/code-block-python.tsx"
classNameComponentContainer="p-8"
/>
#### CSS Example
}
filePath="app/docs/code-block/code-block-css.tsx"
classNameComponentContainer="p-8"
/>
### Different Themes
Shiki supports many popular themes. Here are some examples:
#### GitHub Dark Theme
}
filePath="app/docs/code-block/code-block-themed.tsx"
classNameComponentContainer="p-8"
/>
#### Nord Theme
}
filePath="app/docs/code-block/code-block-nord.tsx"
classNameComponentContainer="p-8"
/>
## Installation
CLIManualCopy and paste the following code into your project.Install the required dependencies.Update the import paths to match your project setup.
## Component API
### CodeBlock
| Prop | Type | Default | Description |
| :-------- | :-------------------------------- | :------ | :------------------------- |
| children | React.ReactNode | | Child components to render |
| className | string | | Additional CSS classes |
| ...props | `React.HTMLProps` | | All other div props |
### CodeBlockCode
| Prop | Type | Default | Description |
| :-------- | :-------------------------------- | :------------- | :----------------------------------- |
| code | string | | The code to display and highlight |
| language | string | "tsx" | The language for syntax highlighting |
| theme | string | "github-light" | The theme for syntax highlighting |
| className | string | | Additional CSS classes |
| ...props | `React.HTMLProps` | | All other div props |
### CodeBlockGroup
| Prop | Type | Default | Description |
| :-------- | :------------------------------------- | :------ | :------------------------- |
| children | React.ReactNode | | Child components to render |
| className | string | | Additional CSS classes |
| ...props | `React.HTMLAttributes` | | All other div props |
## Usage with Markdown
The `CodeBlock` component is used internally by the `Markdown` component to render code blocks in markdown content. When used within the `Markdown` component, code blocks are automatically wrapped with the `not-prose` class to prevent conflicts with prose styling.
{markdownContent}
}`}
language="tsx"
/>
## Tailwind Typography and not-prose
The `CodeBlock` component includes the `not-prose` class by default to prevent Tailwind Typography's prose styling from affecting code blocks. This is important when using the [@tailwindcss/typography](https://github.com/tailwindlabs/tailwindcss-typography) plugin, which provides beautiful typography defaults but can interfere with code block styling.
Since code blocks are styled with Shiki for syntax highlighting, they should not inherit Tailwind Typography styles. The `not-prose` class ensures that code blocks maintain their intended appearance regardless of the surrounding typography context.
My Content
This content has prose styling applied.
{/* The CodeBlock has not-prose to prevent prose styling */}
`}
language="tsx"
/>
## Customizing Syntax Highlighting
The `CodeBlockCode` component uses [Shiki](https://shiki.matsu.io/) for syntax highlighting. You can customize the theme by passing a different theme name to the `theme` prop.
Shiki supports many popular themes including:
- github-light (default)
- github-dark
- dracula
- nord
- and more.
For a complete list of supported themes, refer to the [Shiki documentation](https://github.com/shikijs/shiki/blob/main/docs/themes.md).
import ComponentCodePreview from "@/components/app/component-code-preview"
import { generateMetadata } from "../utils/metadata"
import { MarkdownBasic } from "./markdown-basic"
import { MarkdownCustomComponents } from "./markdown-custom-components"
export const metadata = generateMetadata(
"Markdown",
"A component for rendering Markdown content with support for GitHub Flavored Markdown (GFM) and custom component styling."
)
# Markdown
A component for rendering Markdown content with support for GitHub Flavored Markdown (GFM) and custom component styling.
## Examples
### Basic Markdown
Render basic Markdown with support for bold, italics, lists, code blocks and more.
}
filePath="app/docs/markdown/markdown-basic.tsx"
classNameComponentContainer="p-8"
disableNotProse
/>
### Markdown with Custom Components
You can customize how different Markdown elements are rendered by providing custom components.
}
filePath="app/docs/markdown/markdown-custom-components.tsx"
classNameComponentContainer="p-8"
/>
## Installation
CLIManualCopy and paste the following code into your project.Install the required dependencies.Update the import paths to match your project setup.
## Component API
### Markdown
| Prop | Type | Default | Description |
| :--------- | :------------------------------------------- | :----------------- | :---------------------------------------------- |
| children | string | | Markdown content to render |
| className | string | | Additional CSS classes |
| components | `Partial` | INITIAL_COMPONENTS | Custom components to override default rendering |
| ...props | `React.ComponentProps` | | All other ReactMarkdown props |
## Performance Optimization
The Markdown component employs advanced memoization techniques to optimize rendering performance, especially in streaming AI response scenarios. This approach is crucial when rendering chat interfaces where new tokens are continuously streamed.
### How Memoization Works
Our implementation:
1. Splits Markdown content into discrete semantic blocks using the `marked` library
2. Memoizes each block individually with React's `memo`
3. Only re-renders blocks that have actually changed when new content arrives
4. Preserves already rendered blocks to prevent unnecessary re-parsing and re-rendering
This pattern significantly improves performance in chat applications by preventing the entire message history from re-rendering with each new token, which becomes increasingly important as conversations grow longer.
For AI chat interfaces using streaming responses, always provide a unique `id` prop (typically the message ID) to ensure proper block caching:
{message.content}`}
language="tsx"
/>
This memoization implementation is based on the [Vercel AI SDK Cookbook](https://sdk.vercel.ai/cookbook/next/markdown-chatbot-with-memoization) with enhancements for better React integration.
## Customizing Components
You can customize how different Markdown elements are rendered by providing a `components` prop. This is an object where keys are HTML element names and values are React components.
{children}
,
a: ({ href, children }) => {children},
// ... other components
}
{markdownContent}
`} language="tsx" />
## Supported Markdown Features
The Markdown component uses [react-markdown](https://github.com/remarkjs/react-markdown) with [remark-gfm](https://github.com/remarkjs/remark-gfm) to support GitHub Flavored Markdown, which includes:
- Tables
- Strikethrough
- Tasklists
- Literal URLs
- Footnotes
Additionally, the component includes built-in code block highlighting through the `CodeBlock` component.
## Styling with Tailwind Typography
For the best typography styling experience, we recommend using the [@tailwindcss/typography](https://github.com/tailwindlabs/tailwindcss-typography) plugin. This plugin provides a set of `prose` classes that add beautiful typographic defaults to your markdown content.
When using the Markdown component with Tailwind Typography, you can apply the `prose` class:
{markdownContent}`}
language="tsx"
/>
### Handling Code Blocks
As you've seen in our examples, code blocks within prose content can sometimes cause styling conflicts. The Tailwind Typography plugin provides a `not-prose` class to exclude elements from prose styling:
My Content
Regular content with prose styling...
`} language="tsx" />
import ComponentCodePreview from "@/components/app/component-code-preview"
import { generateMetadata } from "../utils/metadata"
import { MessageBasic } from "./message-basic"
import { MessageWithActions } from "./message-with-actions"
import { MessageWithMarkdown } from "./message-with-markdown"
export const metadata = generateMetadata(
"Message",
"A component for displaying messages in a conversation interface, with support for avatars, markdown content, and interactive actions."
)
# Message
A component for displaying messages in a conversation interface, with support for avatars, markdown content, and interactive actions.
## Examples
### Basic Message
}
filePath="app/docs/message/message-basic.tsx"
classNameComponentContainer="p-8"
/>
### Message with Markdown
The `markdown` prop enables rendering content as [Markdown](/docs/markdown), perfect for rich text formatting in messages.
}
filePath="app/docs/message/message-with-markdown.tsx"
classNameComponentContainer="p-8"
disableNotProse
/>
### Message with Actions
You can use `MessageActions` and `MessageAction` to add interactive elements to your messages.
}
filePath="app/docs/message/message-with-actions.tsx"
classNameComponentContainer="p-8"
/>
## Installation
CLIManualCopy and paste the following code into your project.Update the import paths to match your project setup.
## Component API
### Message
| Prop | Type | Default | Description |
| :-------- | :-------------------------------- | :------ | :------------------------- |
| children | React.ReactNode | | Child components to render |
| className | string | | Additional CSS classes |
| ...props | `React.HTMLProps` | | All other div props |
### MessageAvatar
| Prop | Type | Default | Description |
| :-------- | :----- | :------ | :------------------------------------- |
| src | string | | URL of the avatar image |
| alt | string | | Alt text for the avatar image |
| fallback | string | | Text to display if image fails to load |
| delayMs | number | | Delay before showing fallback (in ms) |
| className | string | | Additional CSS classes |
### MessageContent
| Prop | Type | Default | Description |
| :-------- | :-------------------------------- | :------ | :------------------------------------ |
| children | React.ReactNode | | Content to display in the message |
| markdown | boolean | false | Whether to render content as markdown |
| className | string | | Additional CSS classes |
| ...props | `React.HTMLProps` | | All other div props |
### MessageActions
| Prop | Type | Default | Description |
| :-------- | :-------------------------------- | :------ | :------------------------- |
| children | React.ReactNode | | Child components to render |
| className | string | | Additional CSS classes |
| ...props | `React.HTMLProps` | | All other div props |
### MessageAction
| Prop | Type | Default | Description |
| :-------- | :------------------------------------- | :------ | :---------------------------------------------- |
| tooltip | React.ReactNode | | Content to show in the tooltip |
| children | React.ReactNode | | Child component to trigger the tooltip |
| className | string | | Additional CSS classes for the tooltip |
| side | "top" \| "bottom" \| "left" \| "right" | "top" | Position of the tooltip relative to the trigger |
| ...props | `React.ComponentProps` | | All other Tooltip component props |
import ComponentCodePreview from "@/components/app/component-code-preview"
import { generateMetadata } from "../utils/metadata"
import { ChatBasic } from "./chat-basic"
import { ChatWithCustomScroll } from "./chat-with-custom-scroll"
export const metadata = generateMetadata(
"Chat Container",
"A component for creating chat interfaces with intelligent auto-scrolling behavior, designed to provide a smooth and responsive user experience in conversation interfaces."
)
# Chat Container
A component for creating chat interfaces with intelligent auto-scrolling behavior, designed to provide a smooth and responsive user experience in conversation interfaces.
## Examples
### Chat with Custom Scroll Behavior
Customize the auto-scroll behavior by toggling the auto-scroll feature on or off. This example demonstrates how to give users control over the scrolling behavior.
}
filePath="app/docs/chat-container/chat-with-custom-scroll.tsx"
classNameComponentContainer="p-0"
/>
### Streaming Text Example
A chat container that demonstrates text streaming with automatic scrolling. Click the "Show Streaming" button to see a simulated streaming response with the smart auto-scroll behavior in action.
}
filePath="app/docs/chat-container/chat-basic.tsx"
classNameComponentContainer="p-0"
/>
## Installation
CLIManualCopy and paste the following code into your project.Update the import paths to match your project setup.
## Component API
### ChatContainer
| Prop | Type | Default | Description |
| :---------- | :------------------------------------- | :------ | :---------------------------------------------------------- |
| children | React.ReactNode | | Child components to render inside the container |
| className | string | | Additional CSS classes |
| autoScroll | boolean | true | Whether to automatically scroll to bottom on content change |
| scrollToRef | React.RefObject\ | | Optional custom reference for scroll target |
| ...props | React.HTMLAttributes\ | | All other div props |
## Auto-Scroll Behavior
The component implements sophisticated scrolling logic to provide a natural user experience:
- **New Messages**: Automatically scrolls to the bottom when new messages are added
- **Content Updates**: Scrolls to follow streaming content when already at the bottom
- **User Control**:
- Temporarily disables auto-scrolling when users scroll up or use mouse wheel up
- Maintains scroll position during content updates when user has scrolled up
- Supports touch interactions by tracking touch start/move/end events
- **Resume Auto-Scroll**: Re-enables auto-scrolling when users scroll back to the bottom
## Using with ScrollButton
The ChatContainer pairs well with the ScrollButton component to provide a complete chat interface experience:
(null)
const bottomRef = useRef(null)
return (
{/* Your chat messages here */}
)
}`}
language="tsx"
/>
## Performance Considerations
The ChatContainer component is optimized for performance in chat applications:
1. Uses passive event listeners to avoid blocking the main thread
2. Implements efficient scroll detection with browser-native APIs
3. Uses `requestAnimationFrame` for smooth scrolling animations
For large chat histories, consider implementing virtualization or pagination to maintain performance.
import ComponentCodePreview from "@/components/app/component-code-preview"
import { generateMetadata } from "../utils/metadata"
import { ScrollButtonBasic } from "./scroll-button-basic"
import { ScrollButtonCustom } from "./scroll-button-custom"
import { ScrollButtonWithChat } from "./scroll-button-with-chat"
export const metadata = generateMetadata(
"Scroll Button",
"A floating button component that appears when users scroll up in a container, allowing them to quickly return to the bottom of the content with a single click."
)
# Scroll Button
A floating button component that appears when users scroll up in a container, allowing them to quickly return to the bottom of the content with a single click.
## Examples
### Basic Scroll Button
A simple implementation of the scroll button that appears when scrolling up and disappears when at the bottom of the container.
}
filePath="app/docs/scroll-button/scroll-button-basic.tsx"
classNameComponentContainer="p-0"
/>
### Custom Scroll Button
Customize the appearance and behavior of the scroll button with different variants, sizes, and threshold values.
}
filePath="app/docs/scroll-button/scroll-button-custom.tsx"
classNameComponentContainer="p-0"
/>
### With Chat Container
The ScrollButton works perfectly with ChatContainer for chat interfaces, providing an easy way for users to navigate long conversations.
}
filePath="app/docs/scroll-button/scroll-button-with-chat.tsx"
classNameComponentContainer="p-0"
/>
## Installation
CLIManualCopy and paste the following code into your project.Update the import paths to match your project setup.
## Component API
### ScrollButton
| Prop | Type | Default | Description |
| :----------- | :---------------------------------------------- | :-------- | :--------------------------------------------------- |
| scrollRef | React.RefObject\ | | Reference to the element to scroll to |
| containerRef | React.RefObject\ | | Reference to the scrollable container |
| className | string | | Additional CSS classes |
| threshold | number | 50 | Distance from bottom (in px) to show/hide the button |
| variant | "default" \| "outline" \| "ghost" \| etc. | "outline" | Button variant from your UI button component |
| size | "default" \| "sm" \| "lg" \| etc. | "sm" | Button size from your UI button component |
| ...props | React.ButtonHTMLAttributes\ | | All other button props |
import ComponentCodePreview from "@/components/app/component-code-preview"
import { generateMetadata } from "../utils/metadata"
import { LoaderBasic } from "./loader-basic"
import { LoaderSizes } from "./loader-sizes"
import { LoaderWithText } from "./loader-with-text"
export const metadata = generateMetadata(
"Loader",
"A loading component with multiple variants to indicate processing states and provide visual feedback to users during wait times."
)
# Loader
A loading component with multiple variants to indicate processing states and provide visual feedback to users during wait times.
## Examples
### Basic Loader
Showcasing all available loader variants with default settings.
}
filePath="app/docs/loader/loader-basic.tsx"
classNameComponentContainer="p-0"
/>
### Loader Sizes
Customize the size of any loader variant with predefined size options.
}
filePath="app/docs/loader/loader-sizes.tsx"
classNameComponentContainer="p-0"
/>
### Loader With Text
Some loader variants support displaying custom text while loading.
}
filePath="app/docs/loader/loader-with-text.tsx"
classNameComponentContainer="p-0 min-h-auto items-start"
/>
## Installation
CLIManual
_Note: If you are using Tailwind CSS v4, you may have to grab the keyframes and add them to your global.css file manually. Check manual installation for more details._
Copy and paste the following into your global.css file.Copy and paste the following code into your project.Update the import paths to match your project setup.
## Component API
### Loader
| Prop | Type | Default | Description |
| :-------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------ | :--------- | :--------------------------------------- |
| variant | "circular" \| "classic" \| "pulse" \| "pulse-dot" \| "dots" \| "typing" \| "wave" \| "bars" \| "terminal" \| "text-blink" \| "text-shimmer" \| "loading-dots" | "circular" | The visual style of the loader |
| size | "sm" \| "md" \| "lg" | "md" | The size of the loader |
| text | string | | Text to display (for supported variants) |
| className | string | | Additional CSS classes |
import ComponentCodePreview from "@/components/app/component-code-preview"
import { generateMetadata } from "../utils/metadata"
import { PromptSuggestionBasic } from "./prompt-suggestion-basic"
import { PromptSuggestionHighlight } from "./prompt-suggestion-highlight"
import { PromptSuggestionVariants } from "./prompt-suggestion-variants"
export const metadata = generateMetadata(
"Prompt Suggestion",
"A component for implementing interactive prompt suggestions in AI interfaces. The PromptSuggestion component offers two distinct modes: Normal Mode and Highlight Mode."
)
# Prompt Suggestion
A component for implementing interactive prompt suggestions in AI interfaces. The PromptSuggestion component offers two distinct modes:
- **Normal Mode**: Renders clickable, pill-shaped buttons ideal for suggesting quick prompts in chat interfaces
- **Highlight Mode**: Provides text highlighting to highlight a part of the suggestion
## Examples
### Basic Usage
Display clickable prompt suggestions that users can select to populate an input field. You can easily use it with the [PromptInput](/docs/prompt-input) component.
}
filePath="app/docs/prompt-suggestion/prompt-suggestion-basic.tsx"
classNameComponentContainer="p-8"
/>
### Highlighted Prompt Suggestions
Implement prompt suggestions with search term highlighting. It's perfect to showcase a list of related prompts.
}
filePath="app/docs/prompt-suggestion/prompt-suggestion-highlight.tsx"
classNameComponentContainer="p-8"
/>
### Complete Chat Interface
Build a full-featured chat interface with dynamic prompt suggestions that switch between both modes.
}
filePath="app/docs/prompt-suggestion/prompt-suggestion-variants.tsx"
classNameComponentContainer="p-8 h-[500px]"
/>
## Installation
CLIManualCopy and paste the following code into your project.Update the import paths to match your project setup.
## Component API
### PromptSuggestion
| Prop | Type | Default | Description |
| :-------- | :------------------------------------------------- | :-------- | :----------------------------------------------------------------------------- |
| children | React.ReactNode | | Content to display in the suggestion button |
| variant | "default" \| "destructive" \| "outline" \| "ghost" | "outline" | Visual variant of the button (normal mode) or "ghost" (highlight mode) |
| size | "default" \| "sm" \| "lg" \| "icon" | "lg" | Size of the button (normal mode) or "sm" (highlight mode) |
| highlight | string | undefined | When provided, enables highlight mode and highlights this text within children |
| className | string | | Additional CSS classes |
| ...props | ButtonHTMLAttributes | | All other button HTML attributes (including onClick) |
import ComponentCodePreview from "@/components/app/component-code-preview"
import { generateMetadata } from "../utils/metadata"
import { ResponseStreamFade } from "./response-stream-fade"
import { ResponseStreamTypewriter } from "./response-stream-typewriter"
import { ResponseStreamWithMarkdown } from "./response-stream-with-markdown"
import { UseTextStreamExample } from "./use-text-stream-example"
export const metadata = generateMetadata(
"Response Stream",
"A component for displaying text with streaming animations, perfect for chat interfaces, AI responses, or any text that should appear progressively."
)
# Response Stream
A component for displaying text with streaming animations, perfect for chat interfaces, AI responses, or any text that should appear progressively.
## Examples
### Typewriter Mode
The default mode that types out text character by character, simulating a typing effect.
}
filePath="app/docs/response-stream/response-stream-typewriter.tsx"
classNameComponentContainer="p-8 justify-start items-start min-h-[150px]"
hasReTrigger
/>
### Fade Mode
The fade mode reveals text word by word with a smooth fade-in animation.
}
filePath="app/docs/response-stream/response-stream-fade.tsx"
classNameComponentContainer="p-8 justify-start items-start min-h-[150px]"
hasReTrigger
/>
### With Markdown
ResponseStream can be combined with the Markdown component to create rich, animated content, for that you need to use the `useTextStream` hook directly.
Note: If you want to use mode="fade", you need to manually render the segments with appropriate CSS animations.
It can be hard to get it done with markdown, the way is to write a custom `remarkPlugins`. We have a demo but it's a bit too experimental to be included here, happy to receive a PR if you have a good solution.
}
filePath="app/docs/response-stream/response-stream-with-markdown.tsx"
classNameComponentContainer="p-8 justify-start items-start min-h-[400px]"
disableNotProse
hasReTrigger
/>
### Using the useTextStream Hook with fade mode
When using the useTextStream hook with `fade` mode, you need to manually render the segments with appropriate CSS animations.
}
filePath="app/docs/response-stream/use-text-stream-example.tsx"
classNameComponentContainer="p-8 justify-start items-start min-h-[200px]"
hasReTrigger
/>
## Installation
CLIManualCopy and paste the following code into your project.Update the import paths to match your project setup.
## Component API
### ResponseStream
| Prop | Type | Default | Description |
| :----------------- | :-------------------------------- | :----------- | :----------------------------------------------------------- |
| textStream | string \| AsyncIterable\ | | The text to stream or an async iterable of text chunks |
| mode | "typewriter" \| "fade" | "typewriter" | The animation mode to use |
| speed | number | 20 | Speed from 1-100, where 1 is slowest and 100 is fastest |
| className | string | "" | Additional CSS classes |
| onComplete | () => void | | Callback function when streaming is complete |
| as | string | "div" | Element type to render |
| fadeDuration | number | | Custom fade duration in ms (overrides speed) |
| segmentDelay | number | | Custom delay between segments in ms (overrides speed) |
| characterChunkSize | number | | Custom characters per frame for typewriter (overrides speed) |
### useTextStream Hook
#### Parameters
| Parameter | Type | Default | Description |
| :----------------- | :-------------------------------- | :----------- | :----------------------------------------------------------- |
| textStream | string \| AsyncIterable\ | | The text to stream or an async iterable of text chunks |
| speed | number | 20 | Speed from 1-100, where 1 is slowest and 100 is fastest |
| mode | "typewriter" \| "fade" | "typewriter" | The animation mode to use |
| onComplete | () => void | | Callback function when streaming is complete |
| fadeDuration | number | | Custom fade duration in ms (overrides speed) |
| segmentDelay | number | | Custom delay between segments in ms (overrides speed) |
| characterChunkSize | number | | Custom characters per frame for typewriter (overrides speed) |
| onError | (error: unknown) => void | | Callback function when an error occurs |
#### Return Value
| Property | Type | Description |
| :-------------- | :---------------------------------- | :---------------------------------------- |
| displayedText | string | The current text being displayed |
| isComplete | boolean | Whether streaming is complete |
| segments | `{ text: string; index: number }[]` | Text segments for fade mode |
| getFadeDuration | () => number | Function to get the current fade duration |
| getSegmentDelay | () => number | Function to get the current segment delay |
| reset | () => void | Function to reset the streaming state |
| startStreaming | () => void | Function to start or restart streaming |
| pause | () => void | Function to pause streaming |
| resume | () => void | Function to resume streaming |
import ComponentCodePreview from "@/components/app/component-code-preview"
import { generateMetadata } from "../utils/metadata"
import { ReasoningBasic } from "./reasoning-basic"
import { ReasoningControlled } from "./reasoning-controlled"
import { ReasoningWithAIResponse } from "./reasoning-with-ai-response"
import { ReasoningWithCustomStyling } from "./reasoning-with-custom-styling"
export const metadata = generateMetadata(
"Reasoning",
"A component for displaying collapsible reasoning or thought process content, perfect for AI applications that need to show their 'thinking' or step-by-step explanations."
)
# Reasoning
A component for displaying collapsible reasoning or thought process content, perfect for AI applications that need to show their "thinking" or step-by-step explanations.
## Examples
### Basic Usage
The most basic implementation of the Reasoning component with collapsible content.
}
filePath="app/docs/reasoning/reasoning-basic.tsx"
classNameComponentContainer="p-8 justify-start items-start min-h-[200px]"
hasReTrigger
/>
### With AI Response
Combine with the ResponseStream component to show streaming AI reasoning content.
}
filePath="app/docs/reasoning/reasoning-with-ai-response.tsx"
classNameComponentContainer="p-8 justify-start items-start min-h-[250px]"
hasReTrigger
/>
### Controlled Component
Control the open state programmatically for advanced use cases.
}
filePath="app/docs/reasoning/reasoning-controlled.tsx"
classNameComponentContainer="p-8 justify-start items-start min-h-[250px]"
hasReTrigger
/>
### Custom Styling
Customize the appearance of the Reasoning component to match your application's design.
You can also use markdown in the ReasoningResponse component to style the content.
}
filePath="app/docs/reasoning/reasoning-with-custom-styling.tsx"
hasReTrigger
disableNotProse
/>
## Installation
CLIManualCopy and paste the following code into your project.Update the import paths to match your project setup.
## Component API
### Reasoning
| Prop | Type | Default | Description |
| :----------- | :---------------------- | :------ | :-------------------------------------------------- |
| children | React.ReactNode | | The content of the component |
| className | string | | Additional CSS classes |
| open | boolean | | Control the open state (makes component controlled) |
| onOpenChange | (open: boolean) => void | | Callback when open state changes |
### ReasoningTrigger
| Prop | Type | Default | Description |
| :-------- | :-------------- | :------ | :--------------------------- |
| children | React.ReactNode | | The content of the trigger |
| className | string | | Additional CSS classes |
| ...props | HTMLAttributes | | Additional HTML button props |
### ReasoningContent
| Prop | Type | Default | Description |
| :-------- | :-------------- | :------ | :-------------------------- |
| children | React.ReactNode | | The content to be displayed |
| className | string | | Additional CSS classes |
| ...props | HTMLAttributes | | Additional HTML div props |
### ReasoningResponse
| Prop | Type | Default | Description |
| :-------- | :-------------------------------- | :------ | :-------------------------------------------------- |
| text | string \| AsyncIterable\ | | The text to display or stream |
| className | string | | Additional CSS classes |
| ...props | ResponseStreamProps | | Additional ResponseStream props (except textStream) |
import ComponentCodePreview from "@/components/app/component-code-preview"
import { generateMetadata } from "../utils/metadata"
import { CustomFileUpload } from "./custom-file-upload"
export const metadata = generateMetadata(
"File Upload",
"A component for creating drag-and-drop file upload interfaces with support for single or multiple files, custom triggers, and visual feedback during file dragging operations."
)
# File Upload
A component for creating drag-and-drop file upload interfaces with support for single or multiple files, custom triggers, and visual feedback during file dragging operations.
## Examples
### File Upload with Prompt Input
You can combine the file upload component with the [Prompt Input](/docs/prompt-input) component to create a full-featured input component with file upload support. You can try to drop a file to see the visual feedback.
}
filePath="app/docs/file-upload/custom-file-upload.tsx"
classNameComponentContainer="p-8"
/>
## Installation
CLIManualCopy and paste the following code into your project.Update the import paths to match your project setup.
## Component API
### FileUpload
| Prop | Type | Default | Description |
| :----------- | :---------------------- | :------ | :--------------------------------------- |
| onFilesAdded | (files: File[]) => void | | Function called when files are added |
| children | React.ReactNode | | Child components |
| multiple | boolean | true | Allow selection of multiple files |
| accept | string | | File types to accept (e.g., ".jpg,.png") |
### FileUploadTrigger
| Prop | Type | Default | Description |
| :-------- | :----------------------------------------- | :------ | :------------------------------- |
| asChild | boolean | false | Use child element as the trigger |
| className | string | | Additional CSS classes |
| children | React.ReactNode | | Child components |
| ...props | `React.ComponentPropsWithoutRef<"button">` | | All other button props |
### FileUploadContent
| Prop | Type | Default | Description |
| :-------- | :------------------------------------- | :------ | :--------------------- |
| className | string | | Additional CSS classes |
| ...props | `React.HTMLAttributes` | | All other div props |
import ComponentCodePreview from "@/components/app/component-code-preview"
import { generateMetadata } from "../utils/metadata"
import { JSXPreviewBasic } from "./jsx-preview-basic"
import { JSXPreviewStreaming } from "./jsx-preview-streaming"
export const metadata = generateMetadata(
"JSX Preview",
"A component for rendering JSX strings as React components, with support for streaming content and automatic tag completion."
)
# JSX Preview
A component for rendering JSX strings as React components, with support for streaming content and automatic tag completion.
## Examples
### Basic JSX Preview
The `JSXPreview` component can render JSX strings directly into React components.
}
filePath="app/docs/jsx-preview/jsx-preview-basic.tsx"
classNameComponentContainer="p-8"
/>
### Streaming JSX Preview
The `isStreaming` prop enables real-time rendering of JSX as it's being streamed, with automatic tag completion.
}
filePath="app/docs/jsx-preview/jsx-preview-streaming.tsx"
classNameComponentContainer="p-8"
hasReTrigger
/>
## Installation
CLIManualCopy and paste the following code into your project.Update the import paths to match your project setup.
## Component API
### JSXPreview
| Prop | Type | Default | Description |
| :---------- | :--------------- | :------ | :------------------------------------------------------------------- |
| jsx | string | | The JSX string to render |
| isStreaming | boolean | false | Whether the JSX is being streamed (enables automatic tag completion) |
| className | string | | Additional CSS classes |
| ...props | `JsxParserProps` | | All other props from `react-jsx-parser` |
## Showcase
Check out these example implementations using prompt-kit components:
- [zola.chat](https://zola.chat/): Open-source AI chat app built with prompt-kit components
import { Button } from "@/components/ui/button"
import { ArrowRightIcon } from "lucide-react"
import Image from "next/image"
import Link from "next/link"
import { generateMetadata } from "../utils/metadata"
export const metadata = generateMetadata("Showcase", "Showcase for prompt-kit.")
const projects = [
{
title: "zola.chat",
href: "https://zola.chat",
thumbnail: "https://www.zola.chat/cover_zola.webp",
},
{
title: "emojis.com",
href: "https://emojis.com",
thumbnail: "https://attic.sh/_static/emojis/ai-emoji-generator/og.jpg",
},
{
title: "ottogrid.ai",
href: "https://ottogrid.ai",
thumbnail: "https://ottogrid.ai/opengraph-image.png?2ca0b60807e14ef5",
},
{
title: "aiagent.app",
href: "https://aiagent.app",
thumbnail:
"https://aiagent.app/opengraph-image.png?opengraph-image.e8b1925a.png",
},
{
title: "www.findappgaps.com",
href: "https://www.findappgaps.com",
thumbnail:
"https://www.findappgaps.com/opengraph-image.png?fd2d072fb61c49f3",
},
{
title: "faithbase.ai",
href: "https://faithbase.ai",
thumbnail: "https://faithbase.ai/opengraph.jpg",
},
]
export default function Showcase() {
return (
Showcase
Building something great with prompt-kit?
We'd love to feature your project here.
{projects.map((project) => (
{project.title}
Visit {project.title}
))}
)
}
## Blocks
Building blocks for AI apps. Clean, composable blocks built with shadcn/ui and prompt-kit. Use them to ship faster, works with any React framework.
Available blocks:
- **Prompt input with actions**: `components/blocks/prompt-input-with-actions.tsx`
- **Prompt input with suggestions**: `components/blocks/prompt-input-with-suggestions.tsx`
- **Prompt input with autocomplete**: `components/blocks/prompt-input-with-autocomplete.tsx`
- **Basic full conversation**: `components/blocks/basic-full-conversation.tsx`
- **Conversation with avatars**: `components/blocks/conversation-with-avatars.tsx`
- **Conversation with actions**: `components/blocks/conversation-with-actions.tsx`
- **Conversation with scroll to bottom**: `components/blocks/conversation-with-scroll-to-bottom.tsx`
- **Conversation with prompt input**: `components/blocks/conversation-with-prompt-input.tsx`
- **Sidebar with chat history**: `components/blocks/sidebar-with-chat-history.tsx`
- **Full chat app**: `components/blocks/full-chat-app.tsx`
All blocks are available at [prompt-kit.com/blocks](https://www.prompt-kit.com/blocks).
## Resources
- [GitHub Repository](https://github.com/ibelick/prompt-kit): Source code and issues
- [Installation Guide](https://www.prompt-kit.com/docs/installation): Detailed installation instructions
- [Component Documentation](https://www.prompt-kit.com/docs): Complete component API documentation
- [Blocks](https://www.prompt-kit.com/blocks): Building blocks for AI apps
- [shadcn/ui Documentation](https://ui.shadcn.com): Documentation for the underlying UI component system
- [Next.js Documentation](https://nextjs.org/docs): Documentation for the Next.js framework
- [Tailwind CSS Documentation](https://tailwindcss.com/docs): Documentation for the Tailwind CSS framework