A minimal and playful AI chat application built with vanilla TypeScript, Convex, and Clerk.
The production build of this app was submitted to the T3 Chat Cloneathon and is locked at the June 18th, 2025 PR until the hackathon results are announced.
Development continues on the project. You can try the latest version at https://beta.chat.hawkticehurst.com, and view the source code on the beta branch.
This project follows a unique approach that combines:
- Vanilla Web Standards: No heavy frameworks, pure web APIs
- Modern Developer Experience: TypeScript, hot reload, reactive state
- Component Architecture: Reusable, encapsulated UI components
- Reactive State Management: Signal-based reactivity similar to modern frameworks
- Declarative Templates: HTML-like template syntax with type safety
See the GUIDELINES.md file for a very detailed description of the architectural principles and patterns.
npm installCreate your environment file:
cp .env.local.example .env.localSet your environment variables:
- VITE_CONVEX_URL: Your Convex deployment URL
- VITE_CONVEX_HTTP_URL: Your Convex HTTP actions URL
- VITE_CLERK_PUBLISHABLE_KEY: Your Clerk publishable key
Deploy your Convex backend:
npx convex devThe database schema and functions are pre-configured in the convex/ directory.
- Create a Clerk application at clerk.com
- Enable GitHub OAuth provider (optional)
- Configure your environment variables
- Set up JWT template for Convex integration
Start the development server with hot reload:
npm run devThis runs the frontend on http://localhost:5173 with live reloading.
npm run buildThis application follows an opinionated vanilla web architecture:
- Web Components: Custom elements with reactive state management
- TypeScript: Type-safe development with modern JS features
- Vite: Fast development server and optimized builds
- PostCSS-Nesting: A Vite plugin for enhanced CSS nesting support
- Convex: Serverless backend with real-time database
- HTTP Actions: RESTful API endpoints with Hono.js routing
- Real-time Streaming: Server-sent events for AI responses
- JWT Authentication: Secure auth via Clerk integration
- Persistent Chats: Full CRUD operations for conversations
- AI Integration: OpenRouter API with multiple model support
- Smart Titles: AI-generated chat titles for better organization
All API endpoints are implemented as Convex HTTP actions:
GET /auth/status- Check user authentication status
GET /ai-settings/has-key- Check if user has API key configuredGET /ai-settings/key-status- Get API key validation statusPOST /ai-settings/test-key- Test API key validityPOST /ai-settings/key- Set/update API keyGET /ai-settings/preferences- Get user preferencesPOST /ai-settings/preferences- Update user preferences
GET /chats- Get all user chatsPOST /chats- Create new chatDELETE /chats/:chatId- Delete chatPOST /chats/:chatId/title- Update chat titlePOST /chats/:chatId/generate-title- AI-generate chat title
GET /chats/:chatId/messages- Get chat messagesPOST /chats/:chatId/messages- Send new messagePOST /chats/:chatId/stream- Stream AI response
Usage Tracking (Currently Hidden in App)
GET /usage/summary- Get usage statisticsGET /usage/daily- Get daily usage breakdownGET /usage/monthly- Get monthly usage breakdown
src/
├── components/ # Reusable web components
│ ├── ChatInput.ts # Message input component
│ ├── ChatMain.ts # Main chat interface
│ ├── ChatMessages.ts # Message display component
│ ├── ChatSidebar.ts # Chat navigation sidebar
│ ├── ChatSettings.ts # AI model configuration
│ ├── UsageDashboard.ts # Usage statistics display
│ └── ...
├── stores/ # Global state management
│ └── AuthStore.ts # Authentication state
├── services/ # Business logic services
│ └── titleGenerationService.ts
├── workers/ # Web workers
│ └── titleGenerator.worker.ts
├── App.ts # Main application component
└── main.ts # Application entry point
convex/
├── schema.ts # Database schema definition
├── auth.config.ts # Clerk authentication config
├── chats.ts # Chat management functions
├── messages.ts # Message management functions
├── aiKeys.ts # API key management
├── usage.ts # Usage tracking functions
├── aiStreaming.ts # Real-time streaming logic
├── cryptoActions.ts # Secure server actions
├── http.ts # HTTP action router
├── httpActions/ # Individual HTTP endpoints
└── lib/ # Shared backend utilities
lib/
├── ui/ # UI framework primitives
│ ├── Component.ts # Base web component class
│ ├── signal.ts # Reactive state management
│ ├── html.ts # Template rendering
│ └── ...
├── auth/ # Authentication services
└── config.ts # Application configuration