{"id":29016906,"url":"https://github.com/sougata-github/ai-chat-app","last_synced_at":"2025-06-25T23:00:39.823Z","repository":{"id":298061968,"uuid":"998728901","full_name":"sougata-github/ai-chat-app","owner":"sougata-github","description":"A modern ai-chat app built using Next.js","archived":false,"fork":false,"pushed_at":"2025-06-24T15:10:22.000Z","size":866,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-06-24T15:37:34.318Z","etag":null,"topics":["ai-chat-application","ai-chatbot","better-auth","gemini","neondb","nextjs","prisma","shadcn-ui","tailwindcss","trpc","typescript","vercel-ai-sdk"],"latest_commit_sha":null,"homepage":"https://ai-chat-app-gemini.vercel.app","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sougata-github.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-06-09T06:44:59.000Z","updated_at":"2025-06-24T15:10:25.000Z","dependencies_parsed_at":"2025-06-09T07:58:04.480Z","dependency_job_id":null,"html_url":"https://github.com/sougata-github/ai-chat-app","commit_stats":null,"previous_names":["sougata-github/ai-chat-app"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/sougata-github/ai-chat-app","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sougata-github%2Fai-chat-app","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sougata-github%2Fai-chat-app/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sougata-github%2Fai-chat-app/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sougata-github%2Fai-chat-app/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sougata-github","download_url":"https://codeload.github.com/sougata-github/ai-chat-app/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sougata-github%2Fai-chat-app/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261967008,"owners_count":23237658,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai-chat-application","ai-chatbot","better-auth","gemini","neondb","nextjs","prisma","shadcn-ui","tailwindcss","trpc","typescript","vercel-ai-sdk"],"created_at":"2025-06-25T23:00:22.425Z","updated_at":"2025-06-25T23:00:39.805Z","avatar_url":"https://github.com/sougata-github.png","language":"TypeScript","readme":"## Features (MVP)\n\n- Auth (Better Auth) ✅\n\n  - can chat without sign-in (guest mode)\n  - based on `isAnonymous` status, we will have rate limits\n  - 8 user messages in total across all chats when anonymous\n  - 20 user messages when not anonymous\n  - 2 images for both logged-in or not\n  - message limit resets everyday at 5:30am\n  - auth logic in tRPC Context\n  - if no session (logged-out), then new anon session will be created everytime\n  - anon and logged-in sessions will be different so chat info won't be retained across the two\n  - anon sessions will be destroyed once logged-in\n  - If user never logs in then chat info for anon session will be retained\n  - once logged-in the new chat info will be retained thereafter forever\n  - chat useMutation will return limit status on every message when not logged-in (prompt to log in)\n  - chat useMutation will return limit status after only after limit is reached when logged-in\n  - Rate limit check in a separate middleware (in case of mutation)\n\n- User Button (bottom of sidebar - for logged in else render login button)\n\n  - Display message limit info with progress bar\n  - Display user avatar, name and email (only if logged in)\n  - Shortcuts: Ctrl+K to open search (Command component)\n  - Sign Out button\n\n- Sidebar ✅\n\n  - Logo at the top\n  - Create Chat Button -\u003e navigates to `/chat` (no mutation until form is submitted)\n  - Search Chats Button -\u003e opens a dialog with list of 5 recently created chats and when seached displays with chats with searched title\n    (same chats.getMany procedure but if there is search then use that to filter chats)\n  - Archived Chats Button -\u003e opens a dialog with list of Archived chats (Clicking on each chat goes to that specific chat page, but the page will have a header of \"This page currently archived, restore button\", when restore clicked then update mutation (archived = true ) and invalidate chats.getMany -\u003e gets displayed on sidebar again)\n  - Infinite loading of chats (client-component in layout.tsx) (not prefetched) (sorted on the basis of today, last 7 days, older)\n  - Separator\n  - Will have beautiful loading skeleton\n  - Each message will have dropdown with options:\n    - Archive\n    - Delete (Alert Dialog component)\n    - Rename (The chat will become a input component and then onClick will trigger update chat mutation)\n  - Clicking on each chat will navigate to `/chat/chatId`\n  - When a chat gets deleted, the chat below should animate-in (AnimatePresence popLayout)\n  - Render chats which are not `archived=true (server-side)`\n\n- home page\n\n  - generate a uuid()\n  - pass the generated id to ChatView (this is so that we can create a new chat record and route to /chat/chatId)\n  - pass initial messages as empty array since this is the starting point\n  - Render ChatView\n  - Inside ChatView render ChatSuggestions and ChatInput\n  - ChatView is a resuable component\n  - Display ChatSuggestions if no messages else Messages component\n  - /api/chat is a unified api endpoint that checks for an existing chat else creates one\n  - use useChat (but make api call to /api/chat -\u003e for chat creation)\n\n- /chat/chatId\n\n  - Check for existing chat using params id, if not present redirect to /\n  - Fetch existing messages in the chat (server action)\n  - Convert to ai sdk messages\n  - Pass both chatId and ai sdk messages (as initial messages) into ChatView\n  - In ChatView:\n    - use useChat hook for chat interface and making llm calls\n    - since now there are messages, map over them and display MessageItem\n    - looks for changes in chatId to always ensure fresh state\n    - create handleChatSubmit that replaces history state in browser on initial submit\n    - get handleSubmit, messages, loading-state, etc from the hook and pass to Messages Component and ChatInput component\n\n- Flow:\n\n  - One ChatView component and one unified api\n  - will use a combination of useChat and streamText\n  - generate chatId and pass into ChatView and empty initialMessages array\n  - user on home page -\u003e render ChatView -\u003e render Suggestions (since no messages)\n  - submit prompt\n  - url changes to /chat/chatId\n  - api call\n    - check for id, check for messages (at least one should exist (user message))\n    - check for user session\n    - get last message (user prompt)\n    - check if chat exists with the id\n    - if chat does not exist\n      - generate title using generateText\n      - create new chat record with the id, userId and title\n    - if chat exists -\u003e proceed\n    - create user message\n    - convert uiMessages to coreMessages to provide context\n    - stream response using streamText\n    - onFinish -\u003e update db with response\n    - return streamed response\n  - onFinish -\u003e invalidate chats.getMany\n  - messages.length get updated\n  - user message gets appended\n  - response starts streaming\n  - Render Messages and continue chatting\n  - on going to /chat/chatId -\u003e fetch exisiting chat and it's messages\n  - pass to ChatView\n  - Render Messages and continue chatting\n\n- Header (layout.tsx)\n\n- Display theme selection with light and dark mode toggles as well as basic shadcn theme colors (Popover)\n- Share Chat button that generates link -\u003e /domain/share/chatId, copying it displays a toast (Link copied)\n- Share Chat button only for those chats that are not archived\n- /share/chatId page\n\n  - Navigating to shared page will only have the shared chat messages and no textarea (just preview of shared chat)\n\n- Multi-model flow:\n  - use zustand to store current model\n  - store current model in cookies\n  - use cookies to fetch current model/provider in api endpoint\n  - when in image-gen or web-search mode -\u003e disable model selection and default to corresponding models\n\nTodo:\n\n- /chat/chatId page with plain text (getting response and displaying stuff)✅\n- resumable streams\n- Code generation and syntax highlighting, structured outputs\n- Image Generation, Web Search tool, Check Weather tool, multi model setup, scroll hooks (scroll to bottom, auto-scroll)\n- Rate limiting (messages and chats for logged in and guest users)\n- Share page\n- Refinements (Animations, UX improvement)\n- Future updates (tool calling, edit message)\n\n## Tech Stack\n\n- Next.js 15\n- React 19\n- TypeScript\n- TailwindCSS\n- Better Auth\n- tRPC\n- Shadcn-ui\n- Framer Motion\n- Upstash\n- Uploadthing\n- Vercel AI SDK\n- Gemini API\n- Vercel\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsougata-github%2Fai-chat-app","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsougata-github%2Fai-chat-app","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsougata-github%2Fai-chat-app/lists"}