React + shadcn/ui

A Vite + React 19 client wired to the Phoenix backend, with shadcn/ui components installed via the official CLI. Pick this when you prefer React, want shadcn’s component library, or are bringing existing React skill to a Phoenix backend.

Install

npx tostada-cli create MyApp --variant react-shadcn

Or interactively pick React + shadcn/ui at the variant prompt.

What happens

  1. CLI downloads the Tostada shared base (server/, Makefile, scripts/)
  2. CLI copies the React template into client/ — Vite + React 19 + TypeScript + Tailwind
  3. CLI runs npx shadcn@latest add --yes button card input form dialog inside client/, populating src/components/ui/
  4. CLI runs mix deps.get + npm install (unless --no-install)

The components.json shadcn config ships in the template, so the shadcn init step is skipped — you can run npx shadcn@latest add <component> later to extend.

What you get

In client/:

  • React 19 + TypeScript + Vite 7
  • Tailwind CSS 3 + tailwindcss-animate
  • shadcn/ui components: Button, Card, Input, Form, Dialog (in src/components/ui/)
  • Lucide React for icons
  • src/lib/socket.ts — Phoenix socket helper with a framework-agnostic subscribe API (no React-specific bindings; usable from hooks or providers)
  • src/lib/utils.ts — shadcn’s cn() helper
  • A minimal App.tsx landing page with shadcn <Button> auth links
  • Strict TypeScript with project references (tsconfig.app.json + tsconfig.node.json)

In server/:

  • The shared Phoenix backend (identical across all variants)

Vite + proxy + build

The React Vite config mirrors the SvelteKit variants’ proxy block exactly. In dev, /api, /socket, /users, /live, /assets all proxy to Phoenix on :4000. In production, Vite builds to ../server/priv/static/app with base path /app/ so Phoenix serves it at /app.

Available addons

AddonDefaultNotes
dockeroffDockerfile + docker-compose for containerized deploy

Threlte and model-pipeline addons aren’t offered for this variant — they’re SvelteKit-specific.

Verifying the install

cd MyApp
make db.setup
make dev

Open http://localhost:5173 — the React landing page loads, /api/me proxies through to Phoenix.

Adding more shadcn components

cd client
npx shadcn@latest add dropdown-menu sheet tabs

The components.json and path aliases (@/components, @/lib) are pre-configured.

Connecting to Phoenix from React

src/lib/socket.ts exposes a framework-agnostic API:

import { connectSocket, subscribeSocketStatus, pingSocket } from '@/lib/socket';

// In a component:
useEffect(() => {
  connectSocket();
  return subscribeSocketStatus((status) => setStatus(status));
}, []);

The shared backend’s auth flow (session cookies + socket token at /api/socket-token) works the same way as in the SvelteKit variants — see Auth System.

What to build next