Email Kit
Full-featured email client with folders, threads, compose dialog, labels, and responsive layout. Includes both UI and backend scaffolding.
Quick reference
CLI commands
# Add UI components (inbox, compose, threads, etc.)
npx @fivfold/ui add email
# Add backend scaffolding (Express/NestJS + TypeORM)
npx @fivfold/api add email --framework=nestjs --orm=typeorm
# Use MongoDB + Mongoose
npx @fivfold/api add email --framework=nestjs --orm=mongoose --database=mongodb
# Use Express + Prisma
npx @fivfold/api add email --framework=express --orm=prisma
# Dry run to preview files
npx @fivfold/ui add email --dry-run
npx @fivfold/api add email --dry-runOverview
The Email Kit provides a complete email client experience: folder sidebar, thread list, message view, compose dialog, labels, and recipient input with autocomplete. Each Kit in FivFold combines a polished frontend (built on shadcn/ui) with optional backend scaffolding for Express or NestJS. Supported combinations:
| Layer | Options |
|---|---|
| Framework | NestJS, Express |
| SQL | TypeORM (PostgreSQL, MySQL, MariaDB, MSSQL), Prisma |
| NoSQL | Mongoose (MongoDB), Prisma (MongoDB connector) |
| Cloud NoSQL | Azure Cosmos DB SDK, AWS DynamoDB SDK |
Demo
This demo is presented with Mock Data
Guide
Step-by-step guides for the frontend UI and backend API integration. In the sidebar, choose Frontend first, then runtime through ORM, so proxy and CORS snippets match your app.
The Email Kit is built exclusively with shadcn/ui primitives. Follow the steps below to install, integrate, and customize the UI.
1Install the Email Kit
Run the FivFold UI CLI to add the Email Kit to your project. Ensure you have run npx @fivfold/ui init first.
npx @fivfold/ui add emailThe Kit is copied to @/components/ui/kits/email/ (or your configured kits alias in fivfold.json).
2Generated file structure
The command creates a folder with multiple component files for easier development and customization:
kits/email/
types.ts # Shared types (FivFoldEmailFolder, FivFoldEmailThread, etc.)
recipient-input.tsx # To/Cc/Bcc input with autocomplete (Command + Popover)
thread-item.tsx # Thread list row with star button
compose-dialog.tsx # Compose, reply, and forward dialog
message-panel.tsx # Message detail with accordion and Reply/Reply All/Forward
sidebar-content.tsx # Folders and labels sidebar
index.tsx # Main EmailKit component and re-exports3Import and use in your app
Import the main component and types from the kit folder:
import { EmailKit } from "@/components/ui/kits/email";
import type { FivFoldEmailThread, FivFoldEmailFolder } from "@/components/ui/kits/email";
export function EmailPage() {
const [threads, setThreads] = useState<FivFoldEmailThread[]>([]);
const [selectedFolderId, setSelectedFolderId] = useState("inbox");
return (
<EmailKit
folders={folders}
selectedFolderId={selectedFolderId}
onFolderSelect={setSelectedFolderId}
threads={threads}
selectedThreadId={selectedThreadId}
onThreadSelect={setSelectedThreadId}
onCompose={() => setComposeOpen(true)}
onSend={handleSend}
onStar={handleStar}
availableLabels={labels}
/>
);
}4Props reference
The Email Kit exposes a single EmailKit component. Props are grouped by the UI section they control.
Folder Sidebar
Navigation for Inbox, Sent, Drafts, Trash, and custom folders. Uses Button, ScrollArea, Badge, Separator. Implemented in sidebar-content.tsx.
| Prop | Type | Purpose |
|---|---|---|
| folders | FivFoldEmailFolder[] | List of folders (Inbox, Sent, Drafts, Trash, custom). Drives sidebar navigation. |
| selectedFolderId | string | Currently selected folder. Controls which threads are shown. |
| onFolderSelect | (id: string) => void | Callback when user selects a folder. Fetch threads for the new folder. |
| availableLabels | FivFoldEmailLabel[] | Labels shown in sidebar for filtering. Optional. |
Thread List
Scrollable list of email threads with sender, subject, snippet, datetime, labels, star toggle. Uses ScrollArea, Input, Badge. Each row is thread-item.tsx.
| Prop | Type | Purpose |
|---|---|---|
| threads | FivFoldEmailThread[] | Threads for the current folder. Map from your API response. |
| selectedThreadId | string | null | Currently selected thread. Controls which message is shown. |
| onThreadSelect | (id: string) => void | Callback when user selects a thread. Fetch message details. |
| searchValue | string | Search input value. Filter threads client-side or pass to API. |
| onSearchChange | (value: string) => void | Callback when search input changes. Debounce and refetch. |
| onStar | (threadId, starred) => void | Callback when user stars/unstars. Call PATCH /api/email/threads/:id. |
| loadingThreads | boolean | Shows loading state in thread list while fetching. |
Message Panel
Accordion-style message view with sender avatar, body, attachments, Reply/Reply All/Forward actions. Uses Accordion, Button, ScrollArea.
| Prop | Type | Purpose |
|---|---|---|
| message | FivFoldEmailMessage | null | The selected message to display. From GET /api/email/threads/:id. |
| loadingMessage | boolean | Shows loading state while fetching message details. |
| onReply | (message) => void | Opens compose with Reply pre-filled. Call onSend when submitted. |
| onReplyAll | (message) => void | Opens compose with Reply All (To/Cc) pre-filled. |
| onForward | (message) => void | Opens compose with Forward pre-filled. |
Compose Dialog
To/Cc/Bcc recipient input with autocomplete (Command + Popover), subject, body. Uses Dialog, Input, Textarea, Badge.
| Prop | Type | Purpose |
|---|---|---|
| onCompose | () => void | Opens the compose dialog. Typically set state to show dialog. |
| onSend | (data) => void | Callback with to, cc, bcc, subject, body. Call POST /api/email/send. |
| composeTitle | string | Dialog title (e.g. "New Message", "Reply", "Forward"). |
5Integration with backend
You own the wiring
The step-by-step guides, environment variables, and dev-server proxy or rewrite examples are suggestions—not a mandated layout. You should read the generated files, your existing routes and auth, and your deployment topology, then choose URLs, origins, and headers that match your app. We encourage verifying every connection yourself before shipping.
Step-by-step: Email UI → API
Examples match the Frontend choice in the stack sidebar (Next.js). Your mount paths may differ; adjust prefixes to match how you register routes and proxies.
Next.js → API
Prefer rewrites in next.config.ts so browser code can use same-origin paths like /api/email/... while the dev server forwards to your backend. Alternatively set NEXT_PUBLIC_API_URL and call that base from client code.
// next.config.ts — example rewrite to API on another port
import type { NextConfig } from 'next';
const nextConfig: NextConfig = {
async rewrites() {
return [
{
source: '/api/:path*',
destination: 'http://localhost:3001/:path*', // your Nest/Express port
},
];
},
};
export default nextConfig;If the app and API both use port 3000, run the API on a different port (e.g. 3001) or use a monorepo BFF pattern.
API → browser (CORS)
Allow your UI's dev origin on the API. For Next.js that is typically http://localhost:3000 (plus 127.0.0.1 if you use it).
Production
https://api.example.com/email) and lock CORS to known web origins — not *.Connecting Email (UI layer) data to your user system
The kit components are presentational: they do not know your user id. Your fetch layer must attach the authenticated user (header, cookie, or token) so the API returns only that user’s mail.
- Pass Authorization or session cookies from the same auth system your API trusts.
- When mapping API JSON to FivFold types, keep thread ownership consistent with backend user scoping.
- If you use org-level mailboxes, include tenant context in your API client base URL or headers as you already do elsewhere.
Inspect generated code
userId, ownerId, etc.) to your User table or IdP subject. Migrate or add FKs where needed—FivFold cannot know your prior schema.7shadcn/ui primitives
Adding the Email Kit installs these shadcn/ui primitives if not already present:
| Component | Used in |
|---|---|
| button | Actions, folder items, compose |
| input | Search, compose fields |
| dropdown-menu | Label picker, actions |
| card | Message panel, compose dialog |
| dialog | Compose, reply, forward |
| scroll-area | Thread list, message body, sidebar |
| label | Form labels in compose |
| textarea | Message body in compose |
| accordion | Message headers/body expand |
| command | Recipient autocomplete |
| popover | Recipient autocomplete dropdown |
| badge | Labels, unread count |
| separator | Visual dividers |
| tooltip | Hover hints |
