Live App β’ Repository β’ Features β’ Quick Start β’ Environment β’ API Routes β’ Deploy
AiKit News is a modern AI search and research app built with Next.js, ChatJimmy, and Exa. It can answer directly, search the live web, run multi-step Deep Research, render weather cards, read text/code attachments, keep local chat history, and show per-response generation stats.
Example stats:
241 Tokens 0.018s 13,514 TPSPowered by:
- ChatJimmy answers using
llama3.1-8B - Free shared ChatJimmy config prefilled for quick demos
- Generation stats footer with completion tokens, decode time, and TPS
- Exa web search with titles, URLs, highlights, and page text
- Inline citation pills using clean
[1],[2],[3]markers with source context - Deep Research mode that searches, synthesizes, follows up, and writes a cited final answer
- Weather tool for live conditions and short forecast cards
- Text/code file attachments with token counting and context-safe limits
- Tool settings for Search, Weather, custom system prompt, and
top_k - Regenerate and response versions so older answers remain navigable
- Conversation search with highlighted matches and match navigation
- Copy actions for full messages and individual code blocks
- Auto-generated chat titles for cleaner history
- IndexedDB local chat history for saved conversations
- Light, dark, and system themes with refined source hover states
- Markdown rendering with GFM tables, code highlighting, math, and KaTeX
- Responsive app shell with sidebar history and mobile-friendly controls
- Portless dev script for Vercel Portless workflows
- Vercel and Cloudflare-ready scripts
| Layer | Tech |
|---|---|
| Framework | Next.js 16 App Router |
| UI | React 19, Tailwind CSS 4, Framer Motion |
| Language | TypeScript |
| AI backend | ChatJimmy OpenAI-compatible API |
| Search | Exa API |
| Weather | Open-Meteo based weather helper |
| Markdown | react-markdown, remark-gfm, remark-math, rehype-katex, rehype-highlight |
| Local storage | IndexedDB |
| Deployment | Vercel, OpenNext Cloudflare |
- Node.js 20+
- npm
- Exa API key for web search and Deep Research
git clone https://github.com/tanu360/aikit-news.git
cd aikit-news
npm install
cp .env.example .env.localAdd your Exa key to .env.local, then run:
npm run devOpen:
http://localhost:3000If you use Vercel Portless:
npm run dev:portlessAiKit needs an Exa key for search. ChatJimmy is prefilled with the free shared key below.
EXA_API_KEY=your_exa_api_key_here
CHATJIMMY_API_URL=https://jimmy.aikit.club/v1/chat/completions
CHATJIMMY_API_KEY=tarun-dummy
CHATJIMMY_MODEL=llama3.1-8B
NEXT_PUBLIC_MODEL_NAME=llama3.1-8B
NEXT_PUBLIC_SITE_URL=https://news.aikit.club| Variable | Required | Scope | Purpose |
|---|---|---|---|
EXA_API_KEY |
Yes | Server | Used by /api/search and /api/deep-research |
CHATJIMMY_API_URL |
Yes | Server | OpenAI-compatible ChatJimmy completion endpoint |
CHATJIMMY_API_KEY |
Yes | Server | ChatJimmy API key or shared demo key |
CHATJIMMY_MODEL |
Yes | Server | Model sent to ChatJimmy |
NEXT_PUBLIC_MODEL_NAME |
No | Browser | Model label shown in the input UI |
NEXT_PUBLIC_SITE_URL |
No | Browser/server metadata | Canonical, Open Graph, and Twitter metadata origin |
Use this exact change if your .env.local still has placeholders:
-CHATJIMMY_API_URL=your_chatjimmy_api_url_here
-CHATJIMMY_API_KEY=your_chatjimmy_api_key_here
-CHATJIMMY_MODEL=llama3.1-8B
+CHATJIMMY_API_URL=https://jimmy.aikit.club/v1/chat/completions
+CHATJIMMY_API_KEY=tarun-dummy
+CHATJIMMY_MODEL=llama3.1-8Btarun-dummy is intentionally shared as a free ChatJimmy key for people trying AiKit News. You can swap it for your own ChatJimmy-compatible endpoint, or run the proxy from tanu360/chatjimmy-reverse-api.
- Open exa.ai or the Exa dashboard.
- Sign in or create an account.
- Open the API keys section.
- Create a new API key.
- Put it in
.env.local:
EXA_API_KEY=your_real_exa_api_key_hereExa is only called from server-side API routes. Keep it in .env.local and do not expose it as a NEXT_PUBLIC_ variable.
User prompt
|
v
Next.js chat UI
|
+--> Direct answer
| |
| v
| /api/chat -> ChatJimmy answer
|
+--> Search answer
| |
| v
| Router -> /api/search -> Exa -> /api/chat -> cited answer
|
+--> Weather
| |
| v
| ChatJimmy tool call -> weather helper -> weather card + answer
|
+--> Deep Research
|
v
/api/deep-research -> search tree -> synthesis -> final cited answerAiKit reads ChatJimmy usage metadata and calculates decode time with:
Decode Time = completion_tokens / generation_speedThen the UI shows completion tokens, time in seconds, and TPS:
241 Tokens 0.018s 13,514 TPS| Method | Route | What it does |
|---|---|---|
POST |
/api/chat |
Calls ChatJimmy, handles tools, streams UI chunks, emits generation stats |
POST |
/api/search |
Searches Exa with instant results and source text |
POST |
/api/deep-research |
Runs multi-step Exa research and final ChatJimmy synthesis |
GET |
/api/config |
Returns the active model name for the input UI |
POST |
/api/title |
Generates chat titles |
curl http://localhost:3000/api/chat \
-H "Content-Type: application/json" \
-d '{
"mode": "answer",
"messages": [
{ "role": "user", "content": "Explain AI search in simple words" }
]
}'curl http://localhost:3000/api/search \
-H "Content-Type: application/json" \
-d '{
"query": "latest AI search products",
"toolSettings": { "search": true, "weather": false }
}'curl http://localhost:3000/api/deep-research \
-H "Content-Type: application/json" \
-d '{
"query": "How are AI agents changing software development?"
}'Deep Research turns one prompt into a compact research tree:
- Search the original query.
- Synthesize the most useful findings.
- Generate follow-up questions.
- Search the follow-ups.
- Deduplicate sources.
- Write a final answer with citations.
Stream events include:
| Event | Meaning |
|---|---|
step_start |
A research query started |
search_complete |
Exa returned sources |
synthesizing |
ChatJimmy is analyzing the sources |
step_done |
One research step finished |
research_complete |
Source gathering finished |
answer_start |
Final answer generation started |
answer_chunk |
Final answer text chunk |
generation_stats |
Tokens, decode time, and TPS |
all_sources |
Final citation source list |
done |
Research completed |
| Command | Description |
|---|---|
npm run dev |
Start Next.js dev server |
npm run dev:fresh |
Clean caches, then start dev server |
npm run dev:portless |
Clean caches, then run portless run next dev |
npm run build |
Build the Next.js app |
npm run build:fresh |
Clean caches, then build |
npm run start |
Start production server |
npm run lint |
Run ESLint |
npm run build:cloudflare |
Build for Cloudflare with OpenNext |
npm run preview:cloudflare |
Preview Cloudflare build |
npm run deploy:cloudflare |
Deploy with OpenNext Cloudflare tooling |
npm run clean |
Remove build/cache artifacts |
- Push this repo to GitHub.
- Import
tanu360/aikit-newsin Vercel. - Add the environment variables from Environment.
- Deploy.
This repo includes OpenNext Cloudflare support:
open-next.config.tswrangler.jsoncnpm run build:cloudflarenpm run deploy:cloudflare
Add the same environment variables to your Cloudflare deployment before going live.
- Set
NEXT_PUBLIC_SITE_URLto your deployed origin. - Keep
EXA_API_KEYserver-only. - Rotate the shared ChatJimmy key if you operate your own endpoint.
- Run
npm run lint. - Run
npm run build.
- Keep
.env.localprivate. .env.exampleis safe to commit because the ChatJimmy key is intentionally public for demos.- Never put Exa keys in
NEXT_PUBLIC_variables. - Search and weather are tool-controlled, so the model is prompted not to invent live facts when those tools are disabled.
- Treat attached files as user-provided context. Do not upload secrets or private files to a public deployment.
| Problem | Fix |
|---|---|
| Search returns βSearch is not configured.β | Add EXA_API_KEY to .env.local and restart the dev server. |
| Chat returns missing env vars | Make sure CHATJIMMY_API_URL, CHATJIMMY_API_KEY, and CHATJIMMY_MODEL are present. |
| Model label looks wrong | Set NEXT_PUBLIC_MODEL_NAME or CHATJIMMY_MODEL, then restart. |
| Port is already in use | Use npm run dev:portless or start Next on another port. |
| Cloudflare build fails | Run npm run build:cloudflare locally and confirm env vars are available. |
Contributions are welcome.
- Fork the repository.
- Create a feature branch.
- Keep changes focused.
- Run
npm run lintandnpm run build. - Open a pull request with screenshots for UI changes.
- Built by tanu360
- Powered by ChatJimmy
- Search by Exa
- ChatJimmy-compatible backend reference: chatjimmy-reverse-api
MIT License. See LICENSE.
