CRM System

Build your own HubSpot/Pipedrive

◐ Depends

CRM is where "build vs buy" gets nuanced. A basic contact and deal tracker is straightforward to vibe code. A full HubSpot replacement with marketing automation, email sequences, and integrations is a multi-year engineering effort. Know your actual requirements before starting.

Why This Works

Simple needs, simple build

Contact list + deal pipeline + activity log is a weekend project with modern tools.

Custom workflows

Your sales process is unique. Built-in automation can match exactly how you work.

Integration depth

Direct database access means your other tools can read/write CRM data trivially.

No per-seat pricing

Salesforce at $150/user/month adds up fast. Self-hosted has no user limits.

Data ownership

Your customer data stays yours. Export, analyze, migrate without vendor lock-in.

Performance

No API rate limits. Bulk operations happen at database speed.

Tech Stack

LayerToolsWhy
FrontendNext.js + Tanstack TableServer components for fast loads. Tanstack handles complex data tables with sorting, filtering.
DatabasePostgreSQL + PrismaRelational data with complex queries. Full-text search built in.
Searchpg_trgm or MeilisearchFuzzy search on contacts, companies, deals. Postgres works until 1M+ records.
Email IntegrationNylas or direct IMAPNylas abstracts email complexity. IMAP works but requires more code.
Background JobsInngest or Trigger.devHandle email sync, reminders, automation sequences reliably.
File StorageS3 + signed URLsAttachments, documents, imports. Signed URLs for secure access.

Architecture

┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ Web UI │────▶│ Next.js │────▶│ PostgreSQL │ │ (React) │ │ API │ │ (Data) │ └─────────────┘ └──────┬──────┘ └─────────────┘ │ ┌────────────────┼────────────────┐ ▼ ▼ ▼ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ Email │ │ Background │ │ File │ │ (Nylas) │ │ (Inngest) │ │ (S3) │ └─────────────┘ └─────────────┘ └─────────────┘

The Prompt

Copy this into Cursor, Claude, or ChatGPT to generate a working implementation:

Build a CRM system with these core modules: ## Database Schema model Contact { id String @id @default(cuid()) email String? phone String? firstName String lastName String title String? companyId String? company Company? @relation(fields: [companyId], references: [id]) ownerId String owner User @relation(fields: [ownerId], references: [id]) deals Deal[] activities Activity[] tags Tag[] customFields Json? source String? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@index([email]) @@index([companyId]) @@index([ownerId]) } model Company { id String @id @default(cuid()) name String domain String? @unique industry String? size String? website String? contacts Contact[] deals Deal[] customFields Json? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@index([domain]) } model Deal { id String @id @default(cuid()) name String value Decimal? currency String @default("USD") stageId String stage Stage @relation(fields: [stageId], references: [id]) pipelineId String pipeline Pipeline @relation(fields: [pipelineId], references: [id]) contactId String? contact Contact? @relation(fields: [contactId], references: [id]) companyId String? company Company? @relation(fields: [companyId], references: [id]) ownerId String owner User @relation(fields: [ownerId], references: [id]) expectedClose DateTime? probability Int? activities Activity[] createdAt DateTime @default(now()) updatedAt DateTime @updatedAt closedAt DateTime? @@index([stageId]) @@index([ownerId]) } model Pipeline { id String @id @default(cuid()) name String stages Stage[] deals Deal[] } model Stage { id String @id @default(cuid()) name String order Int pipelineId String pipeline Pipeline @relation(fields: [pipelineId], references: [id]) deals Deal[] @@index([pipelineId, order]) } model Activity { id String @id @default(cuid()) type String // 'call', 'email', 'meeting', 'note', 'task' subject String body String? contactId String? contact Contact? @relation(fields: [contactId], references: [id]) dealId String? deal Deal? @relation(fields: [dealId], references: [id]) userId String user User @relation(fields: [userId], references: [id]) dueAt DateTime? completedAt DateTime? createdAt DateTime @default(now()) @@index([contactId]) @@index([dealId]) @@index([userId, dueAt]) } ## Core Features ### Contact Management - List view with infinite scroll, sorting, filtering - Quick search with fuzzy matching (pg_trgm) - Bulk actions (tag, assign, delete) - Import from CSV with field mapping - Merge duplicates by email/phone ### Pipeline View - Kanban board with drag-and-drop stages - Deal cards showing value, contact, days in stage - Stage-level metrics (count, total value) - Quick deal creation from any stage - Rotting indicator for stale deals ### Activity Timeline - Unified feed per contact/deal - Log calls, emails, meetings, notes - Task creation with reminders - Email integration (show sent/received) - Scheduled activities with calendar view ### Dashboard - Pipeline value by stage (bar chart) - Deals closing this month - Activity leaderboard - Win rate trends - Revenue forecast

Timeline

Week 1: Data Foundation

  • Set up database schema with Prisma
  • Build contact CRUD with search
  • Create company management
  • Implement pipeline and stages
  • Basic list views with filtering

Week 2: Pipeline & Activities

  • Build Kanban pipeline view
  • Implement drag-and-drop stage changes
  • Create activity logging system
  • Add task management with due dates
  • Build contact/deal detail pages

Week 3: Polish & Automation

  • CSV import with mapping UI
  • Email integration setup
  • Dashboard with key metrics
  • Basic automation (stage change triggers)
  • Mobile-responsive refinements

Open Source References

Twenty ↗

Modern open-source CRM. Excellent reference architecture.

Erxes ↗

Full marketing/sales platform. Study their data model.

SuiteCRM ↗

Salesforce alternative. Enterprise features, older codebase.

Krayin ↗

Laravel-based CRM. Good if you prefer PHP.

Cost Comparison

HubSpot

$4,000/month
Professional tier with 10 users. Plus onboarding.

Self-Hosted

$100/month
Database + hosting + email integration.
$3,900/month
potential annual savings

Watch Out For