An event companion app exploring Async React, Cache Components, and streaming with Next.js 16, React 19, Tailwind CSS, Prisma, and shadcn/ui.
Built with Next.js 16, React 19, Tailwind CSS v4, shadcn/ui (Base UI), and Prisma.
pnpm install
pnpm run prisma.push
pnpm run prisma.seed
pnpm run devOpen http://localhost:3000 in your browser.
app/ # Pages and layouts
components/
common/ # Shared utility components
design/ # Action prop components
ui/ # shadcn/ui primitives
data/
actions/ # Server Actions
queries/ # Data fetching with cache()
types/ # Shared types derived from query return types
lib/ # Utility functions and hooks
prisma/ # Schema and seed data
- components/ui — shadcn/ui components. Add with
npx shadcn@latest add <component-name> - components/design — Components that expose action props and handle async coordination internally (BottomNav, ToggleGroup, SubmitButton)
- components/common — Shared utility components without complex async logic
Every route folder should contain everything it needs. Components and functions live at the nearest shared space in the hierarchy.
Naming: PascalCase for components, kebab-case for folders, camelCase for functions/hooks. Suffix transition-based functions with "Action".
Cache Components: Uses cacheComponents: true to statically render server components that don't access dynamic data. Keep pages non-async and push dynamic data access into <Suspense> boundaries to maximize the static shell.
Async React: Replace manual isLoading/isError state with React 19's coordination primitives — useTransition for tracking async work, useOptimistic for instant feedback, Suspense for loading boundaries, and use() for reading promises during render.
- Fetching data — Queries in
data/queries/, wrapped withcache(). Await in Server Components directly. - Mutating data — Server Actions in
data/actions/with"use server". Invalidate withrefresh(). UseuseOptimisticfor instant feedback. - Caching — Add
"use cache"withcacheTag()to pages, components, or functions to include them in the static shell. - Errors —
error.tsxfor boundaries,not-found.tsx+notFound()for 404s.
Uses Prisma with PostgreSQL.
pnpm run prisma.push # Push schema to DB
pnpm run prisma.seed # Seed with session data
pnpm run prisma.studio # Open Prisma StudioUses ESLint and Prettier with format-on-save in VS Code. Configuration in eslint.config.mjs and .prettierrc.
pnpm run buildSee the Next.js deployment docs for more details.