A business phone system inside your product, in an afternoon.
Open-source React components for embedded texting, calling, voicemail, number porting, and 10DLC compliance — built on the Handset API. Installed with the shadcn CLI: the source lands in your repo, styled with your tokens, yours to change.
1. Point the CLI at the registry
2. Install the components
Live demo — this is the messaging block, running on mock data. Send something.
Components
35+ components across the whole phone system — realtime built in, your API key never in the browser. Install only what you use.
Blocks
@handset/phone-system
Texting, calls, and voicemail behind three tabs — one import.
@handset/messaging
Two-pane texting surface — inbox plus thread, responsive to mobile.
@handset/softphone
A phone inside your product — dial, answer, mute, hang up.
@handset/contact-timeline
One customer's messages, calls, and voicemails in one scroll.
Messaging
@handset/inbox
Conversation list with previews, relative times, STOP badges, infinite scroll.
@handset/thread
Message history with delivery states, opt-out handling, wired composer.
@handset/composer
Draft box with live SMS segment counting and unicode detection.
@handset/broadcast-composer
One message to many, one call each — opt-outs handled per recipient.
@handset/scheduled-composer
Send now or schedule for later — real server-side send_at.
@handset/message-templates
Saved messages with {{variable}} merge, previewed before you send.
@handset/quiet-hours
A sending-window guard — no texting people at 2am.
@handset/opt-in-form
Consent UI whose exact shape passed a real carrier review.
Voice
@handset/click-to-call-button
Rings the agent, bridges the customer, narrates the call live.
@handset/call-log
Call history with outcomes and expandable transcripts.
@handset/call-transcript
Speaker-labeled transcripts — one-shot or following a live call.
@handset/agent-assist
Live call panel — transcript as it happens, AI summary after hangup.
@handset/voicemail-player
Playback with expiry-safe URLs, durations, and transcripts.
@handset/voicemail-inbox
Voicemail list with unread state and the player inline.
Numbers & compliance
@handset/number-picker
Area-code search and one-click claim for self-serve onboarding.
@handset/brand-registration-form
The 10DLC brand form — EIN, entity, contact, validated.
@handset/campaign-registration-form
Use case, samples, and opt-in — the carrier minimums enforced.
@handset/e911-address-form
The emergency address a carrier dispatches on, validated.
@handset/compliance-status
Brand and campaign approval tracked to green — or the reason why.
@handset/texting-readiness
The 10DLC pipeline as a checklist instead of a mystery.
@handset/port-status
'Where's my number?' as a stepper, rejections made fixable.
@handset/port-in-wizard
Check, collect account details, and submit a port — guided.
Call routing
Realtime & plumbing
@handset/event-log
The realtime stream as a live, filterable inspector.
@handset/usage-dashboard
Per-kind usage with bars and spend from your own rates.
@handset/deliverability-panel
Delivery rate and failure reasons from a recent sample.
@handset/usage-meter
Period usage with comparative bars — show or re-bill customers.
@handset/next-routes
Server proxy route — your API key never reaches the browser.
@handset/react
The headless layer on npm — hooks for messaging, voice, numbers, compliance, and routing — if you'd rather bring your own UI.
How it works
- Components render in your app and call
/api/handset/*— routes in your backend, added by@handset/next-routes. - Your server holds the Handset API key and scopes every request to the signed-in user's tenant. No keys, no tokens in the browser.
- The Handset API does the rest: numbers, delivery, threading, 10DLC compliance, STOP/HELP handling.
MIT licensed. Built by Handset, the business phone API for vertical SaaS.