No description
  • TypeScript 52.5%
  • Svelte 43.7%
  • CSS 1.7%
  • HTML 1.6%
  • Dockerfile 0.2%
  • Other 0.2%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-09-10 19:39:09 -04:00
.githooks run bun run check on git push and enforce no errors 2026-01-14 20:50:08 +00:00
.github Update runner configuration in docker-publish.yml 2026-02-12 17:18:30 -05:00
.vscode add github repo link in account settings & type fixes 2026-01-08 08:54:13 +00:00
documentaton image gen studio & mobile improvements 2026-03-17 00:58:36 +00:00
drizzle v2.1.0 2026-09-03 20:35:16 -04:00
e2e init 2025-06-13 14:14:24 +01:00
icons update default models, add grok icon, add default models reset 2026-04-14 00:15:04 +00:00
landing landing page 2026-07-30 14:08:42 -04:00
scripts fix sqlite-postgres migration script 2026-07-29 15:45:03 -04:00
src prompt bar fix 2026-09-10 19:39:09 -04:00
static fix error popups 2026-09-10 17:12:13 -04:00
.dockerignore update default models, add grok icon, add default models reset 2026-04-14 00:15:04 +00:00
.env.example small fixes 2026-09-10 19:16:32 -04:00
.gitignore fix error popups 2026-09-10 17:12:13 -04:00
.npmrc init 2025-06-13 14:14:24 +01:00
.prettierignore mobile stuff 2025-06-16 07:07:37 -05:00
.prettierrc api keys (#3) 2025-06-14 04:40:01 -07:00
AGENTS.md update analytics for api usage (forgot to stage untracked) 2026-01-13 13:59:19 -05:00
api-docs.md v2.1.0 2026-09-03 20:35:16 -04:00
bun.lock fix better auth and bump deps 2026-09-10 16:28:02 -04:00
CLAUDE.md image gen studio & mobile improvements 2026-03-17 00:58:36 +00:00
docker-compose-local.yml migrate to postgres from sqlite 2026-07-28 22:41:06 -04:00
docker-compose.yml migrate to postgres from sqlite 2026-07-28 22:41:06 -04:00
Dockerfile v2.1.0 2026-09-03 20:35:16 -04:00
drizzle.config.ts migrate to postgres from sqlite 2026-07-28 22:41:06 -04:00
eslint.config.js add more icons 2025-06-18 11:05:28 +01:00
gemini.md Create gemini.md 2026-01-09 07:02:56 -06:00
image.png landing page 2026-07-30 14:08:42 -04:00
jsrepo.json enable/disable mutation 2025-06-14 09:28:12 -05:00
LICENSE improve reasoning UI dropdown & fix typecheck error 2025-12-30 17:56:08 +00:00
package.json fix better auth and bump deps 2026-09-10 16:28:02 -04:00
playwright.config.ts api keys (#3) 2025-06-14 04:40:01 -07:00
README.md Update README 2026-09-03 20:45:45 -04:00
svelte.config.js v2 2026-07-29 01:51:21 -04:00
tsconfig.json Merge branch 'main' into model-list 2025-06-16 13:37:19 -05:00
vite.config.ts migrate to postgres from sqlite 2026-07-28 22:41:06 -04:00
vitest-setup-client.ts api keys (#3) 2025-06-14 04:40:01 -07:00

nanochat

Open-source, self-hostable chat client for Nano-GPT.

nanochat screenshot

Contents

Native apps

Platform Project Notes
Android nanochat-android
iOS nanochat-ios TestFlight beta

Quick start with Docker

Compose brings up its own Postgres and wires DATABASE_URL for the app, so there is nothing to provision. Data lives in ./data.

git clone https://github.com/nanogpt-community/nanochat.git
cd nanochat
cp .env.example .env
# edit .env: set POSTGRES_PASSWORD and BETTER_AUTH_SECRET at minimum
docker compose up

The app is served on port 3432. Database migrations run automatically on every start.

Running with Bun

You need Bun and a Postgres 14+ database.

git clone https://github.com/nanogpt-community/nanochat.git
cd nanochat
cp .env.example .env
# edit .env: point DATABASE_URL at your database
bun install
bun run db:migrate
bun run dev

Run bun run db:migrate again after pulling updates that change the schema.

Upgrading from the SQLite release

Older versions stored everything in data/nanochat.db. To move that data into Postgres:

  1. Point DATABASE_URL at a new, empty Postgres database.
  2. Run bun run db:migrate to create the schema.
  3. Run bun run db:migrate-from-sqlite, passing a path if your database is not at data/nanochat.db.
  4. Start the app, confirm your chats are there, then archive the old .db file.

On Docker, mount the old data directory into the container and run the same steps inside it:

docker compose exec app bun run db:migrate
docker compose exec app bun run db:migrate-from-sqlite /app/data/nanochat.db

The copy is idempotent (on conflict do nothing), so it is safe to re-run. Tables that did not exist in your old release are skipped. Uploaded files in data/uploads are untouched; keep that directory mounted.

Reverse proxy

Streaming responses and file uploads need larger buffers than the nginx defaults. Add this to your server block:

proxy_buffer_size 256k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
client_max_body_size 50M;

Features

nanochat started as a fork and has since replaced most of the stack: Convex became Postgres with Drizzle, Yarn became Bun, OpenRouter became Nano-GPT, and everything ships as a Docker image. Everything below is built on the Nano-GPT API.

Chat

  • Web search with a choice of provider: Linkup, Tavily, Exa, Kagi, Perplexity, Valyu, and Brave (standard, Pro, and Research). Standard and deep search modes, plus per-provider options such as Exa depth and Kagi source.
  • URL scraping: paste a link and its content is added to the context.
  • YouTube transcripts: video links are transcribed automatically at $0.01 per transcript. Thanks to thejudge22.
  • Follow-up questions: two or three contextual suggestions after each reply, generated by a background model and stored with the message. Click one to insert it. Toggle in settings.
  • Assistants: named system prompts with a default model, web search mode, and search provider.
  • Projects: group chats with shared instructions and attached files, with editor and viewer members.
  • Rules: reusable instructions applied always or on demand with @rule_name in a message.
  • Provider selection: for models served by several providers on Nano-GPT, pick one per model, set preferred and excluded providers, and fall back automatically.
  • MCP servers: connect your own remote MCP servers and let the model call their tools.
  • Model benchmarks from Artificial Analysis in the model picker: intelligence, coding, math, and speed for LLMs, ELO and rank for image models. Requires ARTIFICIAL_ANALYSIS_API_KEY.
  • Analytics: per-model usage, cost, and speed tracking, plus response ratings.
  • Themes: configurable color themes inspired by T3 Chat.

Memory

  • Persistent memory: a background model extracts durable facts about you after each exchange and injects them into every chat. Memories are listed in settings where you can edit, add, or delete them.
  • Auto-compaction: when a conversation nears the model's context limit, older messages are summarized so the chat can keep going. The threshold is adjustable, and any conversation can be compacted manually.

Media

  • Image generation in chat and in the Studio, with text-to-image and image-to-image. The Studio has a searchable model picker with vendor, mode, subscription, and price filters.
  • Video generation in chat and in the Studio, with text-to-video and image-to-video. Finished clips are saved to My Stuff.
  • Text-to-speech: OpenAI TTS-1 and HD, Kokoro, and ElevenLabs voices, with playback speed from 0.25x to 4x.
  • Speech-to-text: Whisper Large V3, Wizper, and ElevenLabs via the microphone button.
  • My Stuff: every generated or attached file in one place.

Integrations and account

  • KaraKeep: save conversations as bookmarks to your KaraKeep instance. Thanks to jcrabapple.
  • Passkeys for sign-in (requires HTTPS) and optional OIDC single sign-on.
  • Developer API keys for the HTTP API. See api-docs.md.
  • Scheduled tasks: run a prompt on a cron, interval, or one-off schedule.

URL parameters and shortcuts

Pre-configure a chat from the URL. Useful for bookmarks and browser "bang" shortcuts.

Parameter Description Example
q Pre-fills the chat input ?q=Explain quantum physics
model Selects the model ?model=z-ai/glm-5.3
model_provider Selects the provider, or auto to clear ?model_provider=cerebras
search Web search mode: off, standard, deep ?search=deep
search_provider linkup, tavily, exa, kagi, perplexity, valyu, Brave modes ?search_provider=brave-research
search_context_size low, medium, high ?search_context_size=high
search_exa_depth fast, auto, neural, deep ?search_exa_depth=neural
search_kagi_source web, news, search ?search_kagi_source=news
search_valyu_search_type all, web ?search_valyu_search_type=web
projectId Opens the chat inside a project ?projectId=123

Example bang URL for a browser search engine:

https://nanochat.app/chat?model=z-ai/glm-5.3&search=deep&q=%s

Environment variables

Copy .env.example and fill in what you need. Only the first group is required.

Required

Variable Description
DATABASE_URL Postgres connection string. Set automatically by Docker Compose from POSTGRES_PASSWORD.
POSTGRES_PASSWORD Password for the bundled Compose database
BETTER_AUTH_SECRET Session encryption secret
BETTER_AUTH_URL Public base URL, e.g. https://chat.example.com
ENCRYPTION_KEY Encrypts stored API keys and secrets. Generate with openssl rand -base64 32 and never change it.

Nano-GPT

Variable Description
NANOGPT_API_KEY Shared key used for users who have not added their own
NANOGPT_BASE_URL Override the API base URL, for proxies
SUBSCRIPTION_MODELS_ONLY Restrict shared-key users to subscription-included models
DAILY_MESSAGE_LIMIT Daily quota for shared-key users across chat, media, and utility calls. 0 is unlimited
DISABLE_WEB_ON_SERVER_KEY_WITH_SUBSCRIPTION_ONLY Also turn off web search and scraping for shared-key users

Optional

Variable Description
DISABLE_SIGNUPS Set to true to stop new account creation
BETTER_AUTH_TRUSTED_ORIGINS Comma-separated extra origins allowed to authenticate
SSO_PROVIDER_ID, SSO_DOMAIN, SSO_OIDC_ISSUER, SSO_OIDC_CLIENT_ID, SSO_OIDC_CLIENT_SECRET, SSO_LABEL OIDC single sign-on button on the login page
ARTIFICIAL_ANALYSIS_API_KEY Model benchmarks in the picker. Free key at artificialanalysis.ai
API_KEY_HASH_SECRET Dedicated secret for developer key lookup hashes. Defaults to ENCRYPTION_KEY or BETTER_AUTH_SECRET
BODY_SIZE_LIMIT Request body limit in bytes for uploads. Default in the example is 50 MB
USER_STORAGE_QUOTA_MB Per-user upload cap. Defaults to 2048 with open signups, unlimited when signups are disabled
MIN_FREE_DISK_MB Refuse uploads that would leave less than this free. Default 512
ALLOW_PRIVATE_INTEGRATIONS Let MCP servers and KaraKeep point at LAN addresses. Defaults to allowed when signups are disabled

Secrets at rest

Provider keys, developer API keys, MCP tokens, and other stored secrets are encrypted with AES-256-GCM using ENCRYPTION_KEY. Developer API keys are also indexed by a keyed lookup hash, so authenticating a request never decrypts the key table.

  • ENCRYPTION_KEY must be set before creating any stored secret.
  • Upgrading from a release that stored keys in plaintext: run bun run scripts/migrate-encrypt-api-keys.ts once. Details in scripts/README-API-KEY-ENCRYPTION.md.
  • Lookup hashes migrate themselves on startup.

Tech stack

SvelteKit with Svelte 5, Tailwind CSS, Postgres with Drizzle ORM, Better Auth, Bun, and Docker. Nano-GPT is the only AI provider.

Contributing

  1. Fork the repository.
  2. Create a feature branch.
  3. Make your changes.
  4. Open a pull request.

License

MIT. See LICENSE.