Chainlit: Building Production-Ready Chat UI for LLM Applications
Building a powerful LLM application is not enough. Users need an intuitive and professional chat interface to interact with AI models. However, building a chat UI from scratch requires significant time and effort, from WebSocket handling, state management, to file handling.
Chainlit is a Python framework that allows you to build production-ready chat UIs in minutes. With Chainlit, you can focus on AI logic while getting a beautiful interface with streaming responses, file uploads, and many other features automatically.What Is Chainlit?
Chainlit is an open-source Python framework for building conversational AI chat interfaces. Its key features include:
- Production-Ready Chat UI: Modern interface with markdown support, code highlighting, and file preview
- Streaming Response: Display LLM responses in real-time token by token
- Multi-Step Reasoning: Visualize AI thinking process with step-by-step display
- File Upload & Download: Built-in file handling for documents, images, and more
- User Authentication: Integrated login system with various providers
- Chat History: Storage and recall of previous conversations
- LangChain/LlamaIndex Integration: Native support for popular AI frameworks
- Custom Actions: Interactive buttons and custom actions within chat
- Theming: Customize appearance to match your brand
Installation
Basic Installation
pip install chainlit
Installation with Additional Dependencies
# With LangChain support
pip install chainlit langchain langchain-openai
With LlamaIndex support
pip install chainlit llama-index
Verify Installation
chainlit --version
Running Your First Application
Create a file app.py:
import chainlit as cl
@cl.onmessage
async def main(message: cl.Message):
# Send a simple response
await cl.Message(
content=f"You sent: {message.content}"
).send()
Run with:
chainlit run app.py
Open your browser at http://localhost:8000 and you will see a professional chat interface.
Core Concepts: Decorators and Messages
@cl.onmessage - Main Message Handler
The @cl.onmessage decorator is the main entry point. This function is called every time a user sends a message.
import chainlit as cl
@cl.onmessage
async def handlemessage(message: cl.Message):
# Access message content
userinput = message.content
# Access uploaded files (if any)
files = message.elements
# Process and send response
response = f"Message received: {userinput}"
await cl.Message(content=response).send()
@cl.onchatstart - Chat Initialization
This decorator is called when a new chat session starts. Use it to set up context, models, or greet the user.
import chainlit as cl
@cl.onchatstart
async def start():
# Store state in session
cl.usersession.set("history", [])
# Send welcome message
await cl.Message(
content="Hello! I am an AI assistant. How can I help you?"
).send()
@cl.onmessage
async def main(message: cl.Message):
# Get history from session
history = cl.usersession.get("history")
history.append({"role": "user", "content": message.content})
# Process message...
response = "Response from AI"
history.append({"role": "assistant", "content": response})
cl.usersession.set("history", history)
await cl.Message(content=response).send()
Message Types: Text, Images, and Files
Text Messages with Markdown
@cl.onmessage
async def main(message: cl.Message):
# Chainlit supports full markdown
response = """