Ultralytics LLM provides a lightweight, production-ready JavaScript chat client for integrating AI-powered conversations into web applications. Built for jsDelivr CDN delivery with zero dependencies.
โ ๏ธ Experimental Development: The chat widget ships as a CDN-readychat.min.jsbundle and as part of theultralytics-llmPython package published on PyPI. Track tagged releases for production deployments and reserve@mainfor testing nightly changes.Ecosystem: This repo hosts both the in-browser chat widget and the Python scaffolding we use for backend workflows. The widget is production ready, while the Python client remains a lightweight placeholder until the managed API is released.
Load the chat widget via jsDelivr CDN:
<!-- Latest stable release (recommended for production) -->
<script src="https://cdn.jsdelivr.net/gh/ultralytics/llm@latest/js/chat.min.js"></script>
<!-- Specific version (guaranteed stability) -->
<script src="https://cdn.jsdelivr.net/gh/ultralytics/[email protected]/js/chat.min.js"></script>
<!-- Main branch (experimental, for testing) -->
<script src="https://cdn.jsdelivr.net/gh/ultralytics/llm@main/js/chat.min.js"></script>CDN Links:
- ๐ Browse files: jsdelivr.com/package/gh/ultralytics/llm
- ๐ View stats: Check download counts and version usage
- ๐ท๏ธ Latest release:
https://cdn.jsdelivr.net/gh/ultralytics/llm@latest/js/chat.min.js - ๐ฌ Main branch:
https://cdn.jsdelivr.net/gh/ultralytics/llm@main/js/chat.min.js
Versioning Strategy:
@latest- Always points to the newest tagged release (cache purged on new releases)@v0.0.1- Specific version tags (permanent cache, high reliability)@main- Latest development code (12-hour cache, auto-purged on push)
Note: For production, use
@latestor pin to a specific version tag. The@mainbranch is for testing and may contain breaking changes.
<!DOCTYPE html>
<html>
<head>
<title>Ultralytics Chat</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
</head>
<body>
<script src="https://cdn.jsdelivr.net/gh/ultralytics/llm@latest/js/chat.min.js"></script>
<script>
const chat = new UltralyticsChat({
apiUrl: "https://your-api-endpoint.com/api/chat",
branding: {
name: "My AI Assistant",
tagline: "Ask me anything!",
pillText: "Chat with AI",
},
theme: {
primary: "#042AFF",
yellow: "#E1FF25",
},
});
</script>
</body>
</html>- ๐ฏ Zero Dependencies: Standalone vanilla JavaScript (~1000 lines), no frameworks required
- ๐ฑ Mobile Optimized: Full iOS & Android support with orientation handling, safe area insets, and back button integration
- ๐ Dark Mode: Automatic theme switching based on system preferences
- ๐ป Responsive: Desktop modal and mobile full-screen layouts (WebKit, Blink, Gecko)
- โก Streaming: Real-time SSE response streaming with abort support
- ๐ Search Mode: Built-in documentation search capability
- ๐พ Session Management: Persistent conversation history via localStorage
- โฟ Accessible: WCAG compliant with ARIA labels and keyboard navigation
- ๐จ Customizable: Full theme and branding control
- ๐ Security: XSS protection with HTML escaping, input length limits
const chat = new UltralyticsChat({
// API Configuration
apiUrl: "/api/chat", // Chat endpoint that streams SSE
maxMessageLength: 10000, // Character limit enforced per user message
// Branding
branding: {
name: "AI Assistant", // Assistant name
tagline: "How can I help?", // Tagline text
logo: "https://...", // Header logo URL
logomark: "https://...", // Pill button logo URL
logoUrl: "https://example.com", // Link when header logo is clicked
pillText: "Ask AI", // Pill button text
},
// Theme Colors
theme: {
primary: "#042AFF", // Primary brand color
dark: "#111F68", // Dark theme accent
accent: "#E1FF25", // Highlight color (falls back to theme.yellow)
text: "#0b0b0f", // Text color
},
// Welcome Message
welcome: {
title: "Hi!",
message: "How can I help you today?",
chatExamples: ["What is YOLO11?", "How do I train a model?"],
searchExamples: ["YOLO quickstart", "model training parameters"],
},
// UI Text
ui: {
placeholder: "Ask anythingโฆ",
copyText: "Copy thread",
downloadText: "Download thread",
clearText: "New chat",
},
});UltralyticsChat automatically injects document context (title, URL, description, path) into each request so your backend can provide page-aware responses without extra work on the integrator side.
Your backend should implement:
POST /api/chat
Content-Type: application/json
{
"messages": [{"role": "user", "content": "Hello"}],
"session_id": "optional-session-id",
"context": {
"url": "https://example.com/docs/widget",
"title": "Docs page title",
"description": "Meta description text",
"path": "/docs/widget"
},
"edit_index": 3 // optional when user edits a previous turn
}
Response: Server-Sent Events (SSE)
data: {"content": "Hello! "}
data: {"content": "How can "}
data: {"content": "I help?"}
data: [DONE]
Headers:
X-Session-ID: session-uuid (for persistence)
Content-Type: text/event-stream
When the widget is switched to Search mode it will call the same base URL with /search replacing /chat via POST /api/search and expects a JSON body { "results": [{ title, url, text, score }] }.
- โ Safe area insets for notched devices
- โ Keyboard handling with auto-resize
- โ Home indicator padding
- โ Smooth scrolling optimization
- โ Back button integration (History API)
- โ Dynamic viewport height (address bar handling)
- โ Touch action optimization
- โ Gesture navigation support
- โ Split-screen and multi-window modes
- โ Portrait/landscape orientation changes
- โ Full-screen mobile modal (no horizontal scroll)
- โ Background scroll lock when open
- โ Keyboard shortcuts (desktop: Cmd/Ctrl+K, ESC)
npm install -g terser
terser js/chat.js -o js/chat.min.js -c -m# Serve examples locally
python -m http.server 8000
# Open http://localhost:8000/examples/js/chat.htmlTested and working on:
- โ Chrome/Edge 90+ (Blink)
- โ Safari 14+ (WebKit)
- โ Firefox 88+ (Gecko)
- โ Mobile Safari (iOS 12+)
- โ Chrome Mobile (Android 8+)
- โ Samsung Internet (Android 8+)
- Chat widget with streaming
- Dark mode support
- Search mode
- Session persistence
- Production-ready security & performance
- Full mobile support (iOS & Android)
- File upload support
- Voice input
- Multi-language support
- Official v1.0.0 release
We plan to open-source our Python components once mature:
-
LLMClientclass for Claude/OpenAI/etc. - FastAPI server implementation
- Async streaming support
- Tool/function calling
- RAG integration with vector databases
- Session management utilities
- Rate limiting & caching
- API reference for the widget and backend contracts:
docs/API.md - Product announcements and tutorials: docs.ultralytics.com (LLM section rolling out alongside SDK updates)
Ultralytics thrives on community collaboration! While this repo is currently experimental, we welcome:
- Bug Reports: Found an issue? Report it on GitHub Issues
- Feature Requests: Have an idea? Share it via GitHub Issues
- Pull Requests: Want to contribute? Please read our Contributing Guide first
- Feedback: Share your experience in our Discord or Community Forums
A heartfelt thank you ๐ to all our contributors!
Ultralytics offers two licensing options:
- AGPL-3.0 License: Ideal for students, researchers, and enthusiasts passionate about open collaboration. This OSI-approved open-source license promotes transparency and community involvement. See the LICENSE file for details.
- Enterprise License: For commercial applications, this license permits seamless integration of Ultralytics software into commercial products, bypassing AGPL-3.0 copyleft requirements. Inquire about an Ultralytics Enterprise License.
For bug reports or feature suggestions related to this repo or other Ultralytics projects, please use GitHub Issues. For general questions, discussions, and community support, join our Discord server!










