Odel
handset ui

handset ui

Local
@handset-hq1TypeScriptMITUpdated 1w ago

A business phone system for AI agents: send texts, place calls, read transcripts, buy numbers.

Handset UI

Texting inside your product, in an afternoon.

Open-source React components for embedded messaging, built on the Handset API. Distributed the shadcn way: the CLI copies the source into your repo, styled with your Tailwind tokens, yours to change.

# 1. Point the shadcn CLI at the Handset registry
npx shadcn@latest registry add @handset=https://ui.handset.dev/r/{name}.json

# 2. Install a complete texting surface + the server proxy route
npx shadcn@latest add @handset/messaging @handset/next-routes

Set HANDSET_API_KEY in your env, wire resolveTenantId() in the generated route to your session, and render it:

import { HandsetProvider } from "@handset/react";
import { Messaging } from "@/components/handset/messaging";

export default function MessagesPage() {
  return (
    <HandsetProvider>
      <div className="h-[600px]">
        <Messaging />
      </div>
    </HandsetProvider>
  );
}

What's in the registry

ItemWhat it is
@handset/messagingTwo-pane texting surface — inbox + thread, responsive to mobile
@handset/inboxConversation list: previews, relative times, STOP badges, infinite scroll
@handset/threadMessage history: delivery states, opt-out handling, wired composer
@handset/composerDraft box with live SMS segment counting and unicode detection
@handset/next-routesNext.js proxy route — your API key never reaches the browser

Architecture

Two layers, like shadcn-on-Radix:

  • @handset/react (npm, versioned) — headless hooks: useConversations, useThread, useComposer, plus segment math and a tiny client. Logic we maintain; bring your own UI if you prefer.
  • The registry (apps/www/registry) — the visual components, copied into your project as source.

Components never hold API keys. They call proxy routes in your backend (added by @handset/next-routes); your server holds the Handset key and your existing session auth decides which tenant each signed-in user sees. The Handset API handles the rest — numbers, delivery, threading, 10DLC compliance, STOP/HELP.

Development

pnpm install
pnpm --filter @handset/react build   # hooks package
pnpm dev                             # docs site + live demo at localhost:3000
pnpm registry:build                  # compile registry.json → public/r/*.json

The docs site serves a mock Handset API (apps/www/app/api/handset) so the demo works with zero setup.

Requirements

  • React 18+ (components target React 19 / Tailwind v4 / shadcn CLI ≥ 3)
  • A Handset account for real traffic — the demo runs on mock data without one

Roadmap

See ROADMAP.md — shipped components, what's next (call summaries, MMS attachments, more framework proxies), and non-goals. Issues with real use cases move items up the list.

License

MIT © Handset HQ, Inc.