Model or dataset
FranciscoMoretti/chat-js avatar
FranciscoMoretti/chat-js

ChatJS: a Next.js chat starter that ships auth, 120+ models and resumable streams

Production-ready AI chat. Start here and make it your own. Formerly Sparka AI

1,198 stars122 forksTypeScriptApache-2.0

At a glance

What is it?
ChatJS is an Apache-2.0 monorepo that scaffolds a full AI chat application with authentication, multi-provider model access and resumable streaming. It is a strong starting point for teams that want the surrounding infrastructure handled, and a poor fit for anyone who only needs a thin model-calling wrapper.
Who is it for?
Adopt ChatJS if you are building a chat product on Next.js and want authentication, model routing, attachments and resumable streams already wired together, and you accept PostgreSQL, Redis and Vercel Blob as part of the deployment. Do not adopt it if you only need a thin wrapper around one provider's SDK, or if you cannot run Redis, since the README ties resumable streams to it.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 1 day ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The scaffolding problem ChatJS is aimed at

Building a chat interface is a weekend. Building the parts around it is a quarter. Authentication with multiple providers, streaming that survives a page refresh, file attachments, conversation branching, public share links, and a model layer that spans several vendors: each of these is a separate integration with its own failure modes. ChatJS exists to remove that repetition. The README states the goal directly: "Stop rebuilding the same AI chat infrastructure." That is the specific problem. The intended audience is a small product team or a solo developer who has decided the chat surface itself is not the differentiator, and who would rather spend effort on whatever sits on top of it. The feature list is broad on purpose: 120+ models, GitHub/Google/anonymous auth, drag-and-drop attachments, resumable streams, branching, sharing, web search, image generation, sandboxed code execution, MCP support and an Electron desktop build. A team evaluating this should read that list as the scope of the commitment, not as a menu. You are adopting a monorepo, not a library.

What the monorepo actually contains

The repository is split into four workspaces. apps/chat is the Next.js chat application and the piece you would fork or extend. apps/site is the landing page at chatjs.dev. apps/docs is the documentation site, built with something the README calls Blume. packages/cli is the interactive scaffold, published to npm as @chat-js/cli. That separation matters for maintenance: the CLI is versioned independently, which is why the recent release list shows @chat-js/cli@0.8.0, 0.7.0 and 0.6.5 rather than repository-wide tags. Releases are driven by Changesets across the whole repo, with public packages publishing to npm and desktop installers for @chat-js/electron going to GitHub Releases. The practical consequence is that the scaffold and the app it generates can drift, so the CLI version you pin determines what you actually get. The stack underneath is conventional for this generation of Next.js work: App Router with React Server Components, TypeScript throughout, the AI SDK for model calls, Vercel AI Gateway as the unified model layer, Better Auth, Drizzle ORM against PostgreSQL, Redis for caching and resumable streams, Vercel Blob for file storage, tRPC with Zod for the API boundary, Zustand for client state, and Langfuse for LLM observability. Nothing here is exotic. That is the point: the value is in the assembly, not in any single dependency choice.

How a message travels through the system

The README does not publish an architecture diagram, so the data flow has to be inferred from the stack list and the feature descriptions. What can be stated with confidence is the shape. A request enters through the Next.js App Router in apps/chat. The tRPC layer with Zod validation sits at the API boundary, which means procedure inputs are schema-checked before anything downstream runs. Model calls go through the AI SDK, which routes to Vercel AI Gateway rather than to individual provider SDKs. That gateway is what makes the "120+ Models: Claude, GPT, Gemini, Grok via one API" claim possible: one credential and one calling convention instead of four vendor integrations. Persistence goes through Drizzle ORM into PostgreSQL, which is where conversations, branches and share links would live. Files go to Vercel Blob. Redis carries the resumable stream state, and the README lists it as "Caching & resumable streams," which is the clearest signal that resumption depends on Redis specifically and is not optional if you want that feature. Authentication is Better Auth, supporting GitHub, Google and anonymous sessions. Observability is split between Langfuse for LLM traces and Vercel Analytics for web traffic. The one architectural claim worth flagging as unverified from the supplied material is code execution. The README says "Run code snippets in sandbox" but does not name the sandbox provider or describe the isolation model. Treat that as a gap to investigate before relying on it.

Getting a project running with the CLI

The entry point is a single command from the README: npx @chat-js/cli@latest create my-app. The CLI is interactive rather than flag-driven, at least as documented. It "walks you through gateway, features, and auth choices, generates chat.config.ts, and lists the env vars required by your selections." So the sequence is: run the command, answer the prompts, receive a generated chat.config.ts describing your gateway, feature and auth selections, and then populate the environment variables the CLI prints. That last step is the real work, and the CLI is doing you a favour by enumerating it rather than leaving you to read source. For local development inside the repository itself, the README gives bun commands: bun dev to run the chat app, bun dev:docs for the docs, bun lint for workspace linting, bun test:types for the chat app typecheck, and bun dev:info to print the app URLs assigned to the current worktree. That last one is worth internalizing. The README is explicit: set CHATJS_DEV_SLOT in .env.worktree.local to reserve a stable range of ten ports per worktree, where chat uses offset 0, Electron uses offset 1 and the site uses offset 2, all configured in .worktree-env.json. The instruction is to run bun dev:info rather than assume a port. If you are running several worktrees at once, ignoring that file means port collisions. Note also that .env.worktree.local is git-ignored and kept separate from Vercel-managed .env.local, so the two do not overwrite each other.

The infrastructure you inherit, and what it costs to run

This is the section that decides most adoption questions. ChatJS is not a self-contained binary. Running the full feature set means PostgreSQL for persistence, Redis for caching and resumable streams, and Vercel Blob for attachments. The README lists all three as core stack components, not optional add-ons. If your deployment target cannot provide Redis, the resumable stream feature is the one that breaks, and that feature is one of the more distinctive things here: continuing generation after a page refresh is genuinely harder to build than it looks. The same applies to Blob storage if you want drag-and-drop attachments, and to PostgreSQL if you want branching and share links, since those are persistence features by nature. The model layer adds a second dependency: Vercel AI Gateway. That is what delivers the 120+ model claim, and it is also a coupling. If you later want to call providers directly, you are rewriting the model layer rather than changing a config value. On observability, Langfuse is in the stack list, which means LLM traces leave your infrastructure unless you self-host it. Teams with data residency constraints should confirm where Langfuse and Vercel Analytics send data before committing. None of this is unreasonable for a production chat product. It is unreasonable for a prototype you want to run on a laptop with no external services.

Where ChatJS is the wrong tool

The clearest mismatch is scope. If what you need is a function that takes a message array and returns a streamed completion, ChatJS is roughly two orders of magnitude more code than that. The AI SDK alone does the job, and adding a Next.js monorepo with PostgreSQL, Redis, Blob storage and a gateway on top of it means you now maintain infrastructure you did not need. The second mismatch is provider strategy. ChatJS routes through Vercel AI Gateway, and the README frames the 120+ model count as the benefit. If your product is built around one provider's specific capabilities, particularly features that the gateway abstracts away or does not expose, the unified layer becomes an obstacle rather than a convenience. The third is the desktop story. The README says you can "Package as a native macOS, Windows, or Linux app with Electron," and the worktree port layout reserves an Electron offset, so the support is real. But an Electron wrapper around a Next.js app with server-side rendering, tRPC and a PostgreSQL connection is not the same as a native desktop application. Expect to think hard about where the server runs. Finally, the documentation gap around code execution is a genuine limitation of what is published: "Run code snippets in sandbox" without naming the sandbox or its isolation guarantees is not enough to make a security decision on.

How it compares with assembling the pieces yourself

The obvious alternative is not a competing chat starter. It is starting from create-next-app and adding the AI SDK, Better Auth and Drizzle yourself, one at a time. The difference in approach is real and worth stating plainly. ChatJS makes the integration decisions for you and ships them already connected: the gateway is wired to the AI SDK, the auth provider is wired to the session model, the tRPC procedures are wired to Drizzle queries. You inherit a working system and remove what you do not want. The do-it-yourself route gives you exactly the dependencies you chose and nothing else, at the cost of writing every seam yourself, including the ones that are tedious rather than interesting, such as resumable stream state in Redis. A second alternative is a hosted chat product you configure rather than fork. That trades all maintenance for a loss of control over the interface and the data path, and it is the right call when the chat surface truly is a commodity for you. The honest framing is that ChatJS sits between those two: more control than a hosted product, less assembly than a from-scratch build, and a larger dependency footprint than either if you only needed part of what it offers.

Licence, upgrades and what to check before you fork

The repository is Apache-2.0. That is a permissive licence, and it permits commercial use and modification, but this is not legal advice and the terms that matter to you depend on how you redistribute the work. If you fork apps/chat into a closed product, read the licence text and the NOTICE handling requirements yourself rather than relying on a summary. On upgrades, the Changesets workflow is the mechanism to understand. Releases are driven by Changesets for the whole repository, contributors add a changeset per releasable package, and a generated version PR is merged from the Changesets workflow. Public packages such as @chat-js/cli publish to npm; desktop installers for @chat-js/electron publish to GitHub Releases. The consequence for you is that the CLI is versioned on its own track, so pinning @chat-js/cli@0.8.0 rather than @latest makes your scaffold reproducible. Once you have generated an app, the CLI's job is done and you own the code, so upstream changes to apps/chat do not reach you automatically. That cuts both ways: no forced migrations, and no free fixes either. Before adopting, check three things against the live repository rather than this description: which environment variables the CLI actually lists for your gateway and auth choices, whether the sandbox behind code execution meets your isolation requirements, and whether your deployment target can supply Redis and Blob storage, since resumable streams and attachments depend on them.

Editorial conclusion

Adopt ChatJS if you are building a chat product on Next.js and want authentication, model routing, attachments and resumable streams already wired together, and you accept PostgreSQL, Redis and Vercel Blob as part of the deployment. Do not adopt it if you only need a thin wrapper around one provider's SDK, or if you cannot run Redis, since the README ties resumable streams to it. Verify first that the CLI's generated chat.config.ts matches the providers you actually intend to pay for, and confirm your target deployment can supply every environment variable the CLI lists for your selections.

Official sources

  1. FranciscoMoretti/chat-js on GitHub
  2. License: Apache-2.0
  3. Project website
  4. README
  5. Releases
Community notes

Community notes