Add Tendkit to a Next.js app with the shadcn CLI and create the tables.
Add the items
Add the Tendkit registry
Optional: it lets you write
@tendkit/supportinstead of full URLs. Add it tocomponents.json:components.json{ "registries": { "@tendkit": "https://tendkit.softwaresavants.dev/r/{name}.json" } }Add the engine, a store, the screens and a channel
Terminalnpx shadcn@latest add @tendkit/support @tendkit/support-postgres @tendkit/support-ui @tendkit/channel-resendWithout the registry entry, use the URLs:
https://tendkit.softwaresavants.dev/r/support.json, and so on. Usesupport-d1instead ofsupport-postgresfor SQLite or Cloudflare D1.Create the tables
Export the support schema from your Drizzle schema, then generate a migration.
db/schema.tsexport * from "@/lib/support/postgres/schema";Terminalnpx drizzle-kit generate npx drizzle-kit migrateThe tables are
support_tickets,support_messages,support_contacts,support_contact_identities,support_attachments,support_events,support_readsandsupport_channel_state. The copied0000_init.sqlshows the exact SQL.Wire it up
Create the service, write your directory, add the webhook route, and mount the screens.
Monorepos
Install server items where your API lives and the screens where your web app lives, then fix the few imports that cross packages (the screens only import types from the engine):
npx shadcn@latest add @tendkit/support @tendkit/support-d1 @tendkit/channel-resend --cwd packages/api
npx shadcn@latest add @tendkit/support-ui --cwd apps/webWhat lands where
lib/support/:service.ts,store.ts,channel.ts,types.ts,text.ts,address.ts, pluspostgres/ord1/andchannels/.components/support/:support-inbox.tsx,support-ticket.tsx,support-composer.tsx,support-requests.tsx,link-customer-dialog.tsx,provider.tsx,client.tsandmessages/en.json.
Dependencies
dompurify (to sanitize HTML email), lucide-react and your shadcn/ui button, badge, input, textarea, select, dialog, dropdown menu and skeleton. The stores use drizzle-orm; the Gmail and SMTP adapters use postal-mime. The engine itself has no dependencies.Next steps
Continue with the service. To see the end result first, open the live demo.