Atomic CRM is a full-featured CRM built with React, shadcn-admin-kit, and Supabase. It provides contact management, task tracking, notes, email capture, and deal management with a Kanban board.
make install # Install dependencies (frontend, backend, local Supabase)
make start # Start full stack with real API (Supabase + Vite dev server)
make stop # Stop the stack
make start-demo # Start full-stack with FakeRest data providermake test # Run unit tests (vitest)
make typecheck # Run TypeScript type checking
make lint # Run ESLint and Prettier checksmake build # Build production bundle (runs tsc + vite build)npx supabase migration new <name> # Create new migration
npx supabase migration up # Apply migrations locally
npx supabase db push # Push migrations to remote
npx supabase db reset # Reset local database (destructive)make registry-gen # Generate registry.json (runs automatically on pre-commit)
make registry-build # Build Shadcn registry- Frontend: React 19 + TypeScript + Vite
- Routing: React Router v7
- Data Fetching: React Query (TanStack Query)
- Forms: React Hook Form
- Application Logic: shadcn-admin-kit + ra-core (react-admin headless)
- UI Components: Shadcn UI + Radix UI
- Styling: Tailwind CSS v4
- Backend: Supabase (PostgreSQL + REST API + Auth + Storage + Edge Functions)
- Testing: Vitest
src/
├── components/
│ ├── admin/ # Shadcn Admin Kit components (mutable dependency)
│ ├── atomic-crm/ # Main CRM application code (~15,000 LOC)
│ │ ├── activity/ # Activity logs
│ │ ├── companies/ # Company management
│ │ ├── contacts/ # Contact management (includes CSV import/export)
│ │ ├── dashboard/ # Dashboard widgets
│ │ ├── deals/ # Deal pipeline (Kanban)
│ │ ├── filters/ # List filters
│ │ ├── layout/ # App layout components
│ │ ├── login/ # Authentication pages
│ │ ├── misc/ # Shared utilities
│ │ ├── notes/ # Note management
│ │ ├── providers/ # Data providers (Supabase + FakeRest)
│ │ ├── root/ # Root CRM component
│ │ ├── sales/ # Sales team management
│ │ ├── settings/ # Settings page
│ │ ├── simple-list/ # List components
│ │ ├── tags/ # Tag management
│ │ └── tasks/ # Task management
│ ├── supabase/ # Supabase-specific auth components
│ └── ui/ # Shadcn UI components (mutable dependency)
├── hooks/ # Custom React hooks
├── lib/ # Utility functions
└── App.tsx # Application entry point
supabase/
├── functions/ # Edge functions (user management, inbound email)
└── migrations/ # Database migrations
For more details, check out the doc/src/content/docs/developers/architecture-choices.mdx document.
The codebase includes mutable dependencies that should be modified directly if needed:
src/components/admin/: Shadcn Admin Kit framework codesrc/components/ui/: Shadcn UI components
The src/App.tsx file renders the <CRM> component, which accepts props for domain-specific configuration:
contactGender: Gender optionscompanySectors: Company industry sectorsdealCategories,dealStages,dealPipelineStatuses: Deal configurationnoteStatuses: Note status options with colorstaskTypes: Task type optionslogo,title: BrandinglightTheme,darkTheme: Theme customizationdisableTelemetry: Opt-out of anonymous usage tracking
Complex queries are handled via database views to simplify frontend code and reduce HTTP overhead. For example, contacts_summary provides aggregated contact data including task counts.
User data syncs between Supabase's auth.users table and the CRM's sales table via triggers (see supabase/migrations/20240730075425_init_triggers.sql).
Located in supabase/functions/:
- User management (creating/updating users, account disabling)
- Inbound email webhook processing
Two data providers are available:
- Supabase (default): Production backend using PostgreSQL
- FakeRest: In-browser fake API for development/demos, resets on page reload
When using FakeRest, database views are emulated in the frontend. Test data generators are in src/components/atomic-crm/providers/fakerest/dataGenerator/.
List filters follow the ra-data-postgrest convention with operator concatenation: field_name@operator (e.g., first_name@eq). The FakeRest adapter maps these to FakeRest syntax at runtime.
The project uses TypeScript path aliases configured in tsconfig.json and components.json:
@/components→src/components@/lib→src/lib@/hooks→src/hooks@/components/ui→src/components/ui
When modifying contact or company data structures:
- Create a migration:
npx supabase migration new <name> - Update the sample CSV:
src/components/atomic-crm/contacts/contacts_export.csv - Update the import function:
src/components/atomic-crm/contacts/useContactImport.tsx - If using FakeRest, update data generators in
src/components/atomic-crm/providers/fakerest/dataGenerator/ - Don't forget to update the views
- Don't forget the export functions
- Don't forget the contact merge logic
Import test-data/contacts.csv via the Contacts page → Import button.
- Pre-commit: Automatically runs
make registry-gento updateregistry.json
- Frontend: http://localhost:5173/
- Supabase Dashboard: http://localhost:54323/
- REST API: http://127.0.0.1:54321
- Storage (attachments): http://localhost:54323/project/default/storage/buckets/attachments
- Inbucket (email testing): http://localhost:54324/
- The codebase is intentionally small (~15,000 LOC in
src/components/atomic-crm) for easy customization - Modify files in
src/components/adminandsrc/components/uidirectly - they are meant to be customized - Unit tests can be added in the
src/directory (test files are named*.test.tsor*.test.tsx) - User deletion is not supported to avoid data loss; use account disabling instead
- Filter operators must be supported by the
supabaseAdapterwhen using FakeRest