For Developers
How to clone, run, and extend HotCRM — for engineers building customisations.
For Developers
This page is for engineers. End users and admins can skip it.
Prerequisites
- Node.js 20+
- pnpm 9+ (workspace package manager)
- A clone of the
objectstack-ai/hotcrmrepository
Setting up locally
git clone https://github.com/objectstack-ai/hotcrm.git
cd hotcrm
pnpm install
pnpm devOpen http://localhost:3000 — the app boots with seed data the first time you sign up.
What's in the repo
hotcrm/
├── packages/ # Business capability packages
│ ├── crm/ # Sales objects, flows, sharing, approvals
│ ├── finance/ # Contracts, revenue
│ ├── products/ # Product catalog
│ ├── service/ # Cases, knowledge base
│ ├── marketing/ # Campaigns
│ └── ai/ # Copilot agents, skills, knowledge bases
└── apps/
├── crm/ # The CRM application
└── docs/ # This documentation siteEach package follows the file suffix protocol:
| Suffix | Defines |
|---|---|
*.object.ts | Data model |
*.hook.ts | Server-side lifecycle logic |
*.action.ts | API endpoints / AI-callable tools |
*.flow.ts | Multi-step automation |
*.skill.ts | AI skill |
*.agent.ts | Composite AI agent |
*.page.ts | UI page layout |
*.view.ts | List view |
*.dashboard.ts | Dashboard |
*.sharing.ts | Sharing rule |
*.approval.ts | Approval process |
*.statemachine.ts | State transitions |
Core platform: ObjectStack
HotCRM runs on @objectstack/runtime — a metadata-first runtime that handles persistence, sharing, validation, automation, and AI. We don't modify the runtime; we define metadata that the runtime executes.
Key concepts:
- Objects are TypeScript files (no YAML, no JSON, no UI clicking).
- ObjectQL is the data-access API —
broker.find('crm_opportunity', {...})instead of SQL. - Hooks fire on lifecycle events (
before_create,after_update, etc.). - Flows orchestrate multi-step business logic visually defined in TS.
- Every metadata file is validated at compile time against
@objectstack/specschemas.
Common tasks
Add a field to an existing object
// packages/your-extension/src/opportunity.object.ts
import { defineObject, Field, ObjectSchema } from '@objectstack/spec/data';
export default ObjectSchema.parse(defineObject({
name: 'crm_opportunity',
extends: 'crm.opportunity',
fields: {
custom_priority: Field.select({
options: [
{ value: 'a', label: 'A' },
{ value: 'b', label: 'B' },
],
}),
},
}));➜ Full guide: Extending Objects
Add an AI skill
// packages/your-extension/src/your_skill.skill.ts
import { defineSkill } from '@objectstack/spec/ai';
export default defineSkill({
name: 'your_skill',
// ...
});➜ Full guide: Building AI Skills
Customise a page
// packages/your-extension/src/opportunity.page.ts
import { definePage, PageSchema } from '@objectstack/spec/ui';
export default PageSchema.parse(definePage({
object: 'crm_opportunity',
// ...
}));➜ Full guide: UI Extensions
Validating your changes
pnpm typecheck # validates all metadata against @objectstack/spec
pnpm test # unit tests
pnpm lint # code style
pnpm build # full buildCI runs the same checks on every PR.
Where to keep customisations
Add a new package under packages/ rather than editing core packages. This keeps you upgradable when HotCRM ships updates.
packages/
acme-crm-extension/ # your customisationsYour package can extends: any core object, register new skills against the existing Copilot, and add pages/views/dashboards alongside the built-in ones.
Where to go next
- Extending Objects — the data layer.
- Building AI Skills — the AI layer.
- UI Extensions — the front-end.
- Administration — how admins configure the system you build.