A "Slack"-like team chat demo built with Next.js 16.3 Cache Components, React 19, Tailwind CSS v4, and Prisma 7. The app is available in equivalent TanStack Query and SWR implementations.
The architecture follows the Next.js App Architecture skill and the Component Architecture for React Server Components blog post.
Both implementations demonstrate the same client data patterns:
- Client-only Suspense: Workspace search and
@mentionautocomplete keep their inputs interactive while results load behind local Suspense boundaries. - Server-seeded live data: Channel messages, thread replies, users, and unread state render on the server before the client cache takes over.
Related guide work: Client-side data fetching guide PR
- Cache Components cache reusable server reads with
'use cache', name the data withcacheTag, and set its lifetime withcacheLife, so repeated reads come from the cache until a tag is invalidated. The session-aware current-user read uses'use cache: private'. - Partial Prefetching prefetches one shared App Shell per route. Channel and navigation links with
prefetch={true}also resolve their URL data, including the cached content behind it while uncached data streams after navigation. - Hover-triggered prefetch delays URL-specific prefetches for channels and threads until pointer, focus, or touch intent, avoiding a separate prefetch for every destination in view.
- Server Functions send messages, add reactions, mark activity as read, and update channel groups on the server. They invalidate only the affected cache tags with
updateTag. - React Compiler memoizes components and hooks automatically, so the code needs no manual
useMemooruseCallback. - View Transitions pin persistent navigation and composer UI while cross-fading content as it streams in from Suspense.
- Async React keeps the UI interactive during server work with
Suspense,useOptimistic,useTransition,useActionState, anduse.
Huddle runs on Postgres, so set DATABASE_URL in .env.local and then run the following commands.
pnpm install
pnpm run prisma.push
pnpm run prisma.seed
pnpm run devOpen http://localhost:3000 in your browser. You can browse the data with pnpm run prisma.studio, or wipe and re-seed the database with pnpm run prisma.reset.
Run locally without Postgres
Drop this prompt into your agent to swap the datasource for SQLite:
Set up Huddle to run locally on SQLite instead of Postgres. Keep both database adapter stacks installed so the production Postgres setup remains available. Swap
provider = "postgresql"toprovider = "sqlite"inprisma/schema.prisma. Replace@prisma/adapter-pgwith@prisma/adapter-better-sqlite3inlib/prisma-client.tsandprisma/seed.ts, usingnew PrismaBetterSqlite3({ url })whereurlisprocess.env.DATABASE_URLwith thefile:prefix stripped. WriteDATABASE_URL=file:./prisma/dev.dbto.env.local, then runpnpm run prisma.pushandpnpm run prisma.seed.
The schema is otherwise identical, so the rest of the app behaves the same as production.
The end-to-end tests use @next/playwright with the instant() API to guard initial loads and client navigations, and they run in CI.
pnpm test:e2e- Next.js 16.3: App Router, Cache Components, Server Functions
- React 19 with React Compiler: Suspense, View Transitions,
useOptimistic - TanStack Query or SWR for client-owned message state
- TypeScript and Tailwind CSS v4
- Prisma 7 on PostgreSQL (Neon)
- Ariakit for the accessible mention combobox