Skip to main content
Atelier is a pnpm monorepo with four apps under apps/.

apps/web — React frontend

  • React 19 + Vite + Tailwind CSS v4
  • Clerk (@clerk/clerk-react) for authentication; useAuth() provides tokens
  • TanStack Query for all server state; queries live in src/hooks/
  • Jotai for lightweight client state
  • CASL (@casl/react) for UI-level permission checks, built from studio.currentUserRole in AbilityProvider and consumed via useAbility()
  • Typed API client at src/lib/api.ts, always accessed through useApi()
  • Route guards: AuthRouteStudioRouteAppRoute
  • Visual pinboard built on react-konva; drag-and-drop via @dnd-kit

apps/server — Express backend

  • Express + TypeScript, run with tsx in dev and tsc for production builds
  • Prisma ORM against PostgreSQL; client singleton at src/lib/prisma.ts
  • Clerk (@clerk/express) validates JWTs via a global clerkMiddleware()
  • Authorization via requireStudioAbility(action, subject) middleware
  • AI agent for pinboard building (see Agentic pinboard)

apps/chrome-extension and apps/landing

The Chrome extension captures products from retailer sites into the studio product library. The landing app is the marketing site.

Request flow

Clerk issues JWTs on the frontend. ApiProvider wraps createApi(getToken) so every fetch carries a Bearer token. On the server, clerkMiddleware() decodes it and requireStudioAbility does the DB lookup that attaches req.studioMembership and req.ability to the request.