A lightweight CRM with contacts, companies, and deals β built for SaaS dashboards and AI agents. Part of the OpenClaw ecosystem. Zero cloud dependencies β runs locally with SQLite.
Built with Preact + Hono + SQLite. Ships with a dual-mode UI: one for humans (clean, responsive tables) and one for AI agents (explicit buttons, large targets).
Clawnify CRM App is a production-ready contact relationship manager designed for the OpenClaw community. Think of it as an open-source HubSpot alternative β a CRM you can self-host, customize, and embed in any SaaS product.
Unlike HubSpot or Salesforce, this runs entirely on your own infrastructure with no API keys, no vendor lock-in, and no per-seat pricing. It provides a complete sales pipeline and lead management system. Manage contacts, companies, and deals with rich column types, inline editing, and full CRUD β all out of the box.
- Three entities β contacts, companies, and deals with foreign key relationships
- Rich column types β avatars, colored pills, entity icons with favicons, currency formatting, email/phone links
- Sidebar navigation β switch between entities with count badges
- Sorting & filtering β per-column sorting with debounced search
- Pagination β server-side with page controls
- Deal pipeline β track deals through stages (prospect β qualified β proposal β negotiation β won/lost)
- Footer calculations β deal count and total value sum
- Company favicons β auto-fetched from domain via Favicone
- Dual-mode UI β human-optimized + AI-agent-optimized (
?agent=true) - SQLite persistence β auto-creates schema and seeds realistic sample data on first run
git clone https://github.com/clawnify/open-crm.git
cd open-crm
pnpm install
pnpm run devOpen http://localhost:5175 in your browser. Data persists in data.db.
Append ?agent=true to the URL:
http://localhost:5175/?agent=true
This activates an agent-friendly UI with:
- Explicit "Edit" / "Delete" buttons on every row (no hover-to-reveal)
- Larger click targets for reliable browser automation
- Always-visible action buttons
- Semantic labels on all interactive elements
The human UI stays unchanged β hover-to-reveal actions, compact spacing, and a clean interface.
| Layer | Technology |
|---|---|
| Frontend | Preact, TypeScript, Vite |
| Backend | Hono, Node.js |
| Database | SQLite (better-sqlite3) |
| Icons | Lucide |
| Favicons | Favicone |
- Node.js 20+
- pnpm (or npm/yarn)
src/
server/
schema.sql β SQLite schema (companies, contacts, deals)
db.ts β SQLite wrapper + seed logic (5 companies, 10 contacts, 8 deals)
index.ts β Hono REST API (full CRUD for all three entities + stats)
client/
app.tsx β Root component + agent mode detection
context.tsx β Preact context for CRM state
hooks/use-crm.ts β Multi-entity state management
components/
sidebar.tsx β Entity navigation with count badges
toolbar.tsx β Entity title + search + add button
data-table.tsx β Table orchestrator
contacts-table.tsx β Contact rows (avatar, company, status pill)
companies-table.tsx β Company rows (favicon, industry pill, contact count)
deals-table.tsx β Deal rows (contact, value, stage pill, footer totals)
add-form.tsx β Slide-down forms for adding records
pill.tsx β Colored status/stage pill
avatar.tsx β Initial-based colored avatar
entity-icon.tsx β Company favicon with letter fallback
pagination.tsx β Page controls
Three entities with foreign key relationships:
ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ
β companies β β contacts β β deals β
ββββββββββββββββ€ ββββββββββββββββ€ ββββββββββββββββ€
β id βββββ β id βββββ β id β
β name β β β first_name β β β name β
β domain β β β last_name β β β contact_id βββΌββββ
β industry β β β email β β β value β
β phone β βββββΌβ company_id β β β stage β
β email β β phone β β β close_date β
β notes β β title β β β notes β
β created_at β β status β β β created_at β
β updated_at β β created_at β β β updated_at β
ββββββββββββββββ β updated_at β β ββββββββββββββββ
ββββββββββββββββ β
β
ON DELETE SET NULL βββββ
companies (id, name, domain, industry, phone, email, notes)
contacts (id, first_name, last_name, email, phone, company_id β companies, title, status)
deals (id, name, contact_id β contacts, value, stage, close_date, notes)Contacts belong to companies. Deals belong to contacts (and inherit the company). Deleting a company sets company_id to NULL on its contacts. Deleting a contact sets contact_id to NULL on its deals.
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/stats |
Aggregate counts and total deal value |
| GET | /api/contacts |
List contacts (paginated, sortable, searchable) |
| POST | /api/contacts |
Create a contact |
| PUT | /api/contacts/:id |
Update a contact |
| DELETE | /api/contacts/:id |
Delete a contact |
| GET | /api/companies |
List companies (paginated, sortable, searchable) |
| POST | /api/companies |
Create a company |
| PUT | /api/companies/:id |
Update a company |
| DELETE | /api/companies/:id |
Delete a company |
| GET | /api/deals |
List deals (paginated, sortable, searchable) |
| POST | /api/deals |
Create a deal |
| PUT | /api/deals/:id |
Update a deal |
| DELETE | /api/deals/:id |
Delete a deal |
This project is part of the OpenClaw ecosystem. Contributions are welcome β open an issue or submit a PR.
MIT