This document provides a high-level overview of the Documenso codebase to help humans and agents understand how the application is structured.
Documenso is an open-source document signing platform built as a monorepo using npm workspaces and Turborepo. The application enables users to create, send, and sign documents electronically.
┌─────────────────────────────────────────────────────────────────────────────┐
│ Remix App (Hono Server) │
│ apps/remix │
├─────────────┬─────────────┬─────────────┬─────────────┬─────────────────────┤
│ /api/v1/* │ /api/v2/* │ /api/trpc/* │ /api/jobs/* │ React Router UI │
│ (ts-rest) │ (tRPC) │ (tRPC) │ (Jobs API) │ │
├─────────────┴─────────────┴─────────────┴─────────────┴─────────────────────┤
│ │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────────────┐ │
│ │ @api │ │ @trpc │ │ @lib │ │ @email │ │ @signing │ │
│ │ (REST) │ │ (RPC) │ │ (CORE) │ │ │ │ │ │
│ └─────────┘ └─────────┘ └────┬────┘ └─────────┘ └─────────────────┘ │
│ │ │
│ ┌──────────────────┼──────────────────┐ │
│ │ │ │ │
│ ┌────▼────┐ ┌─────▼─────┐ ┌─────▼─────┐ │
│ │ Storage │ │ Jobs │ │ PDF │ │
│ │Provider │ │ Provider │ │ Signing │ │
│ └────┬────┘ └─────┬─────┘ └─────┬─────┘ │
│ │ │ │ │
└──────────────┼──────────────────┼──────────────────┼────────────────────────┘
│ │ │
┌──────┴──────┐ ┌──────┴──────┐ ┌──────┴──────┐
│ Database │ │ Inngest/ │ │ Google KMS/ │
│ S3 │ │ Local │ │ Local │
└─────────────┘ └─────────────┘ └─────────────┘
| Package | Description | Port |
|---|---|---|
@documenso/remix |
Main application - React Router (Remix) with Hono server | 3000 |
@documenso/documentation |
Documentation site (Next.js + Nextra) | 3002 |
@documenso/openpage-api |
Public analytics API | 3003 |
| Package | Description |
|---|---|
@documenso/lib |
Core business logic (server-only, client-only, universal) |
@documenso/trpc |
tRPC API layer with OpenAPI support (API V2) |
@documenso/api |
REST API layer using ts-rest (API V1) |
@documenso/prisma |
Database layer (Prisma ORM + Kysely) |
@documenso/ui |
UI component library (Shadcn + Radix + Tailwind) |
@documenso/email |
Email templates and mailer (React Email) |
@documenso/auth |
Authentication (OAuth via Arctic, WebAuthn/Passkeys) |
@documenso/signing |
PDF signing (Local P12, Google Cloud KMS) |
@documenso/ee |
Enterprise Edition features |
@documenso/assets |
Static assets |
| Package | Description |
|---|---|
@documenso/app-tests |
E2E tests (Playwright) |
@documenso/eslint-config |
Shared ESLint config |
@documenso/prettier-config |
Shared Prettier config |
@documenso/tailwind-config |
Shared Tailwind config |
@documenso/tsconfig |
Shared TypeScript configs |
| Category | Technology |
|---|---|
| Frontend | React 18, React Router v7 (Remix) |
| Server | Hono |
| Database | PostgreSQL 15, Prisma, Kysely |
| API | tRPC, ts-rest, OpenAPI |
| Styling | Tailwind CSS, Radix UI, Shadcn UI |
| Auth | Arctic (OAuth), WebAuthn/Passkeys |
| React Email, Nodemailer | |
| Jobs | Inngest / Local |
| Storage | S3-compatible / Database |
| @libpdf/core, pdfjs-dist | |
| i18n | Lingui |
| Build | Turborepo, Vite |
| Testing | Playwright |
- Location:
packages/api/v1/ - Framework: ts-rest (contract-based REST)
- Mount:
/api/v1/* - Auth: API Token (Bearer header)
- Status: Deprecated but maintained
Routes (RESTful pattern):
GET/POST/DELETE /api/v1/documents/*GET/POST/DELETE /api/v1/templates/*- Recipients and fields nested under documents
- Location:
packages/trpc/server/ - Framework: tRPC with trpc-to-openapi
- Mount:
/api/v2/*,/api/v2-beta/* - Auth: API Token or Session Cookie
- Status: Active
Routes (action-based pattern):
GET/POST /api/v2/document/*- Document operationsGET/POST /api/v2/template/*- Template operationsGET/POST /api/v2/envelope/*- Envelope operations (multi-document)GET/POST /api/v2/folder/*- Folder management
Route Organization:
packages/trpc/server/
├── document-router/
│ ├── get-document.ts
│ ├── get-document.types.ts
│ └── ...
├── template-router/
├── envelope-router/
├── recipient-router/
├── field-router/
└── ...
- Mount:
/api/trpc/* - Usage: Frontend-to-backend communication
- Auth: Session-based
Jobs handle async operations like email sending, document sealing, and webhooks.
┌─────────────────┐ ┌───────────────────────────────────────┐
│ triggerJob() │────▶│ Job Provider │
│ │ │ ┌─────────────┬─────────────────┐ │
│ - name │ │ │ Inngest │ Local │ │
│ - payload │ │ │ (Cloud) │ (Database) │ │
└─────────────────┘ │ └─────────────┴─────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────┐ │
│ │ Job Handler │ │
│ │ (async processing) │ │
│ └─────────────────────┘ │
└───────────────────────────────────────┘
packages/lib/jobs/client/- Provider implementationspackages/lib/jobs/definitions/- Job definitions
Email Jobs:
send.signing.requested.email- Signing invitationsend-confirmation-email- Email verificationsend-recipient-signed-email- Notify on signaturesend-rejection-emails- Rejection notificationssend-document-cancelled-emails- Cancellation notices
Internal Jobs:
internal.seal-document- Finalize signed documentsinternal.bulk-send-template- Bulk document sendinginternal.execute-webhook- External webhook calls
The codebase uses a strategy pattern with ts-pattern for provider selection via environment variables.
Handles file uploads and downloads.
| Provider | Description | Env Value |
|---|---|---|
| Database | Store files as Base64 in DB | database |
| S3 | S3-compatible storage (+ CloudFront) | s3 |
Config: NEXT_PUBLIC_UPLOAD_TRANSPORT
Location: packages/lib/universal/upload/
Cryptographically signs PDF documents.
| Provider | Description | Env Value |
|---|---|---|
| Local | P12 certificate file | local |
| Google Cloud HSM | Google Cloud KMS | gcloud-hsm |
Config: NEXT_PRIVATE_SIGNING_TRANSPORT
Location: packages/signing/
Sends transactional emails.
| Provider | Description | Env Value |
|---|---|---|
| SMTP Auth | Standard SMTP with credentials | smtp-auth |
| SMTP API | SMTP with API key | smtp-api |
| Resend | Resend API | resend |
| MailChannels | MailChannels API | mailchannels |
Config: NEXT_PRIVATE_SMTP_TRANSPORT
Location: packages/email/mailer.ts
Processes async jobs.
| Provider | Description | Env Value |
|---|---|---|
| Local | Database-backed queue | local (default) |
| Inngest | Managed cloud service | inngest |
Config: NEXT_PRIVATE_JOBS_PROVIDER
Location: packages/lib/jobs/client/
Browser
│
▼
Hono Server (apps/remix/server/)
│
├──▶ /api/v1/* ──▶ ts-rest handlers (packages/api/)
│
├──▶ /api/v2/* ──▶ tRPC OpenAPI handlers (packages/trpc/)
│
├──▶ /api/trpc/* ──▶ tRPC handlers (packages/trpc/)
│
├──▶ /api/jobs/* ──▶ Job handlers (packages/lib/jobs/)
│
└──▶ /* ──▶ React Router (apps/remix/app/routes/)
│
▼
React Components (packages/ui/)
1. Upload Document ──▶ Storage Provider (DB/S3)
│
2. Add Recipients ────────────────┤
│
3. Add Fields ────────────────────┤
│
4. Send Document ─────────────────┤
│ │
▼ │
Email Job ──▶ Email Provider |
│ |
5. Recipient Signs ───────────────┤
│ │
▼ │
seal-document Job │
│ │
▼ │
Signing Provider ◀─────────────┘
│
▼
Signed PDF ──▶ Storage Provider
documenso/
├── apps/
│ └── remix/
│ ├── app/
│ │ └── routes/ # React Router routes
│ │ ├── _authenticated+/ # Protected routes
│ │ ├── _unauthenticated+/ # Public routes
│ │ └── _recipient+/ # Signing routes
│ └── server/
│ ├── router.ts # Hono route mounting
│ └── main.js # Entry point
├── packages/
│ ├── api/v1/ # API V1 (ts-rest)
│ ├── trpc/server/ # API V2 + Internal (tRPC)
│ ├── lib/
│ │ ├── server-only/ # Server business logic
│ │ ├── client-only/ # Client utilities
│ │ ├── universal/ # Shared code
│ │ └── jobs/ # Background jobs
│ ├── prisma/ # Database schema & client
│ ├── signing/ # PDF signing
│ ├── email/ # Email templates
│ └── ui/ # Component library
└── docker/ # Docker configs
# Full setup (install, docker, migrate, seed, dev)
npm run d
# Start development server
npm run dev
# Database GUI
npm run prisma:studio
# Type checking (faster than build)
npx tsc --noEmit
# E2E tests
npm run test:e2e| Service | Port |
|---|---|
| PostgreSQL | 54320 |
| Inbucket (Mail) | 9000 |
| MinIO (S3) | 9001, 9002 |
| Variable | Purpose | Options |
|---|---|---|
NEXT_PUBLIC_UPLOAD_TRANSPORT |
Storage provider | database, s3 |
NEXT_PRIVATE_SIGNING_TRANSPORT |
Signing provider | local, gcloud-hsm |
NEXT_PRIVATE_SMTP_TRANSPORT |
Email provider | smtp-auth, smtp-api, resend, mailchannels |
NEXT_PRIVATE_JOBS_PROVIDER |
Jobs provider | local, inngest |
See .env.example for the complete list of configuration options.