Tendkit

Search documentation

Find a docs page

Get Started

Installation

Add Tendkit to a Next.js app with the shadcn CLI and create the tables.

Add the items

  1. Add the Tendkit registry

    Optional: it lets you write @tendkit/support instead of full URLs. Add it to components.json:

    components.json
    {
      "registries": {
        "@tendkit": "https://tendkit.softwaresavants.dev/r/{name}.json"
      }
    }
  2. Add the engine, a store, the screens and a channel

    Terminal
    npx shadcn@latest add @tendkit/support @tendkit/support-postgres @tendkit/support-ui @tendkit/channel-resend

    Without the registry entry, use the URLs: https://tendkit.softwaresavants.dev/r/support.json, and so on. Use support-d1 instead of support-postgres for SQLite or Cloudflare D1.

  3. Create the tables

    Export the support schema from your Drizzle schema, then generate a migration.

    db/schema.ts
    export * from "@/lib/support/postgres/schema";
    Terminal
    npx drizzle-kit generate
    npx drizzle-kit migrate

    The tables are support_tickets, support_messages, support_contacts, support_contact_identities, support_attachments, support_events, support_reads and support_channel_state. The copied 0000_init.sql shows the exact SQL.

  4. 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):

Terminal
npx shadcn@latest add @tendkit/support @tendkit/support-d1 @tendkit/channel-resend --cwd packages/api
npx shadcn@latest add @tendkit/support-ui --cwd apps/web

What lands where

  • lib/support/: service.ts, store.ts, channel.ts, types.ts, text.ts, address.ts, plus postgres/ or d1/ and channels/.
  • components/support/: support-inbox.tsx, support-ticket.tsx, support-composer.tsx, support-requests.tsx, link-customer-dialog.tsx, provider.tsx, client.ts and messages/en.json.

Dependencies

The CLI installs these for you. The screens use TanStack Query, 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.