CRM App Backend Template
React — Schema, API & AI Guide
A production-ready React CRM backend schema and Starter Kit on Back4app: Contact, Company, Deal, Activity, pipeline stages, ER diagram, data dictionary, JSON schema, API playground, and a one-click AI Agent prompt to deploy in minutes.
Key Takeaways
On this page you get a production-ready CRM schema, a one-click AI prompt, and step-by-step React code — so you can ship a CRM app without building the backend.
- Deploy in minutes — Paste the AI Agent prompt and get a running app with contacts, companies, deals, and pipeline.
- Secure by default — ACLs and role-based access so users see only their assigned deals and data.
- React-native SDK — Typed objects, async/await, offline pinning, and Live Queries for pipeline updates.
- REST + GraphQL — Both APIs auto-generated; filter deals by stage, list activities by relatedTo.
- Five classes — _User (built-in), Company, Contact, Deal (pipeline), Activity (tasks/events).
What Is the React CRM App Backend Template?
The React CRM App Backend Template pairs Back4app's CRM schema (Contact, Company, Deal, Activity) with the Parse JavaScript SDK and React. Use hooks to fetch contacts and deals, filter by pipeline stage, and subscribe to Live Queries for real-time updates. Ideal for dashboards and internal tools: connect your components to a managed backend without writing API routes or managing auth yourself.
Best for:
Overview
React CRM UIs typically show a pipeline (deals by stage), contact and company lists, and activity timelines. Back4app provides the backend; the Parse JavaScript SDK and React hooks handle fetching, state, and real-time updates via Live Queries.
The schema defines _User, Company, Contact, Deal, and Activity. In React you use new Parse.Query('Deal').equalTo('stage', stage) and store results in state or context. The Back4app React/JS SDK supports session auth, so only assigned or owned data is returned.
Core CRM Features
A React CRM backend with built-in contact and company management, deal pipeline stages, and activity tracking. Use hooks and the Parse SDK for real-time pipeline updates.
Contact management
Store and manage contacts with name, email, phone, company, and notes. Ideal for React apps.
Company management
Track companies with name, website, industry, and address. Links to contacts and deals.
Deal pipeline
Sales pipeline with stages, amount, expected close date, and assignment. Built for React backends.
Activity tracking
Log calls, emails, meetings, and notes linked to contacts and deals. Works with React SDK.
User & permissions
Built-in user model and pointers for ownership and assignment. ACLs out of the box for React.
Why Build Your React CRM Backend with Back4app?
Back4app removes the need for a custom backend so you can focus on pipeline views and contact/deal management.
- •Hooks-friendly SDK: Use the Back4app JavaScript SDK with useEffect and useState; fetch contacts and deals on mount and update state after mutations.
- •Auth out of the box: Parse.User.login() and signUp() give you session tokens; restrict data by assignedTo or createdBy.
- •Real-time with Live Queries: Subscribe to Deal and Activity changes so pipeline and dashboard stay in sync without polling.
Ideal for React developers building CRM or sales dashboards—same backend, any frontend.
Core Benefits
A production-ready CRM backend so you can ship faster and focus on your app.
Ship Faster, No Backend Code
REST & GraphQL APIs and a ready-to-use schema — connect your app and go.
Secure by Default
ACLs and class-level permissions; restrict by assignedTo and createdBy.
Real-Time Pipeline
Live Queries over WebSockets for instant deal and activity updates.
Built-In Auth
User sign-up, login, and session handling out of the box.
Works Offline
Local pinning keeps contacts and deals available offline and syncs when you reconnect.
Deploy in Minutes
Use the AI Agent to create and deploy your CRM app from this template.
Ready to try it?
Let the Back4app AI Agent create your CRM app backend, connect the React frontend, and deploy — all from a single prompt.
Free to start — 50 AI Agent prompts/month, no credit card required
Technical Stack
Everything powering this CRM app template at a glance.
ER Diagram
Entity-Relationship diagram for the React CRM app data model.
CRM schema: _User, Company, Contact, Deal, Activity with pointers for company, contact, deal, assignedTo, relatedTo, createdBy.
View diagram source
erDiagram
_User {
String objectId PK
String username
String email
String password
Date createdAt
Date updatedAt
}
Company {
String objectId PK
String name
String website
String industry
String address
String notes
Pointer createdBy FK
Date createdAt
Date updatedAt
}
Contact {
String objectId PK
String name
String email
String phone
Pointer company FK
String notes
Pointer createdBy FK
Date createdAt
Date updatedAt
}
Deal {
String objectId PK
String title
Number amount
String stage
Pointer contact FK
Pointer company FK
Date expectedCloseDate
String notes
Pointer assignedTo FK
Date createdAt
Date updatedAt
}
Activity {
String objectId PK
String type
String subject
String description
Date dueDate
Date completedAt
Pointer relatedTo FK
Pointer createdBy FK
Date createdAt
Date updatedAt
}
Company ||--o{ Contact : "has"
Company ||--o{ Deal : "has"
Contact ||--o{ Deal : "has"
_User ||--o{ Deal : "assignedTo"
_User ||--o{ Activity : "createdBy"
Contact ||--o{ Activity : "relatedTo"
Deal ||--o{ Activity : "relatedTo"
_User ||--o{ Company : "createdBy"
_User ||--o{ Contact : "createdBy"
Integration Flow
Auth-to-CRUD sequence: how your React app talks to Back4app — login, then query contacts and deals, update pipeline.
View diagram source
sequenceDiagram
participant User
participant App as React App
participant Back4app as Back4app Cloud
User->>App: Login
App->>Back4app: Parse.User.logIn(username, password)
Back4app-->>App: Session token
App-->>User: Logged in
User->>App: Load contacts and deals
App->>Back4app: new Parse.Query('Deal').find() or Parse.Query('Contact').find()
Back4app-->>App: List of Deal / Contact
App-->>User: Show pipeline
User->>App: Create deal or contact
App->>Back4app: deal.save() or contact.save()
Back4app-->>App: Deal (objectId)
App-->>User: Updated listData Dictionary
Complete field reference for every class in the schema.
| Field | Type | Description | Required |
|---|---|---|---|
| objectId | String | Auto-generated unique identifier | auto |
| name | String | Full name of the contact | |
| String | Email address | — | |
| phone | String | Phone number | — |
| company | Pointer<Company> | Company this contact belongs to | — |
| notes | String | Free-form notes | — |
| createdBy | Pointer<_User> | User who created this contact | — |
| createdAt | Date | Auto-generated creation timestamp | auto |
| updatedAt | Date | Auto-generated last-update timestamp | auto |
9 fields in Contact
Security & Permissions
How ownership, ACLs, and class-level permissions protect data in this CRM schema.
Row-Level ACLs
Use ACLs and pointers (assignedTo, createdBy) so users only see and edit their assigned deals and related data.
Class-Level Permissions
CLPs restrict which roles or users can create, read, update, or delete objects at the class level.
Pointer-Based Ownership
Deal.assignedTo and Activity.createdBy link to _User; Cloud Code can enforce visibility and edits by role.
Schema (JSON)
Raw JSON schema definition — copy and use in your Back4app app or import via the API.
{
"classes": [
{
"className": "Contact",
"fields": {
"objectId": {
"type": "String",
"required": false
},
"name": {
"type": "String",
"required": true
},
"email": {
"type": "String",
"required": false
},
"phone": {
"type": "String",
"required": false
},
"company": {
"type": "Pointer",
"targetClass": "Company",
"required": false
},
"notes": {
"type": "String",
"required": false
},
"createdBy": {
"type": "Pointer",
"targetClass": "_User",
"required": false
},
"createdAt": {
"type": "Date",
"required": false
},
"updatedAt": {
"type": "Date",
"required": false
}
}
},
{
"className": "Company",
"fields": {
"objectId": {
"type": "String",
"required": false
},
"name": {
"type": "String",
"required": true
},
"website": {
"type": "String",
"required": false
},
"industry": {
"type": "String",
"required": false
},
"address": {
"type": "String",
"required": false
},
"notes": {
"type": "String",
"required": false
},
"createdBy": {
"type": "Pointer",
"targetClass": "_User",
"required": false
},
"createdAt": {
"type": "Date",
"required": false
},
"updatedAt": {
"type": "Date",
"required": false
}
}
},
{
"className": "Deal",
"fields": {
"objectId": {
"type": "String",
"required": false
},
"title": {
"type": "String",
"required": true
},
"amount": {
"type": "Number",
"required": false
},
"stage": {
"type": "String",
"required": false
},
"contact": {
"type": "Pointer",
"targetClass": "Contact",
"required": false
},
"company": {
"type": "Pointer",
"targetClass": "Company",
"required": false
},
"expectedCloseDate": {
"type": "Date",
"required": false
},
"notes": {
"type": "String",
"required": false
},
"assignedTo": {
"type": "Pointer",
"targetClass": "_User",
"required": false
},
"createdAt": {
"type": "Date",
"required": false
},
"updatedAt": {
"type": "Date",
"required": false
}
}
},
{
"className": "Activity",
"fields": {
"objectId": {
"type": "String",
"required": false
},
"type": {
"type": "String",
"required": false
},
"subject": {
"type": "String",
"required": false
},
"description": {
"type": "String",
"required": false
},
"dueDate": {
"type": "Date",
"required": false
},
"completedAt": {
"type": "Date",
"required": false
},
"relatedTo": {
"type": "Pointer",
"required": false
},
"createdBy": {
"type": "Pointer",
"targetClass": "_User",
"required": false
},
"createdAt": {
"type": "Date",
"required": false
},
"updatedAt": {
"type": "Date",
"required": false
}
}
},
{
"className": "_User",
"fields": {
"objectId": {
"type": "String",
"required": false
},
"username": {
"type": "String",
"required": true
},
"email": {
"type": "String",
"required": true
},
"password": {
"type": "String",
"required": true
},
"createdAt": {
"type": "Date",
"required": false
},
"updatedAt": {
"type": "Date",
"required": false
}
}
}
]
}Build with AI Agent
Use the Back4app AI Agent to build a real CRM app from this template: it will create the frontend, the backend (this schema, auth, and APIs), and deploy it — no manual setup. The prompt below describes this CRM stack so the Agent can generate a production-ready app in one go.
Create a CRM app on Back4app with this exact schema and behavior. Schema: 1. _User (use Back4app built-in): username (String, required), email (String, required), password (String, required); objectId, createdAt, updatedAt (system). 2. Company: name (String, required), website (String), industry (String), address (String), notes (String), createdBy (Pointer to _User); objectId, createdAt, updatedAt (system). 3. Contact: name (String, required), email (String), phone (String), company (Pointer to Company), notes (String), createdBy (Pointer to _User); objectId, createdAt, updatedAt (system). 4. Deal: title (String, required), amount (Number), stage (String; e.g. lead, qualified, proposal, negotiation, won, lost), contact (Pointer to Contact), company (Pointer to Company), expectedCloseDate (Date), notes (String), assignedTo (Pointer to _User); objectId, createdAt, updatedAt (system). 5. Activity: type (String; e.g. call, email, meeting, note), subject (String), description (String), dueDate (Date), completedAt (Date), relatedTo (Pointer to Contact or Deal), createdBy (Pointer to _User); objectId, createdAt, updatedAt (system). Security: - Set ACLs so only authenticated users can access data; use role-based or owner-based rules where appropriate (e.g. assignedTo, createdBy). - Use Class-Level Permissions so only authenticated users can create/read/update/delete these classes. Auth: - Sign-up (username, email, password) and login; support logout/session. Behavior: - Full CRUD for Company, Contact, Deal, and Activity. - List deals with filter by stage and order by expectedCloseDate or updatedAt (pipeline view). - List activities by relatedTo (Contact or Deal). - Optional: real-time Live Queries for Deal and Activity for dashboard/pipeline updates. - Optional: offline pinning for mobile (Contacts, Deals, Activities). Deliver: - Create the Back4app app with the schema above, ACLs, and any Cloud Code needed. - Generate the frontend and connect it to this backend; deploy so the app is runnable end-to-end.
Press the button below to open the Agent with this template's prompt pre-filled.
API Playground
Try the REST and GraphQL endpoints for the CRM schema. Responses from the example data above — no Back4app account needed.
Uses the same CRM schema (Contact, Company, Deal, Activity) as this template.
Step-by-Step React Integration
Connect to your Back4app backend from a React app using the Back4app React SDK.
Step 1: Install Back4app React SDK
Add the Back4app SDK for your stack (e.g. npm, pubspec, or package manager).
Bashnpm install parseStep 2: Initialize Back4app in your app
Initialize the Back4app SDK at app startup with your App ID and server URL.
JavaScriptimport Parse from 'parse'; Parse.initialize( 'YOUR_APP_ID', 'YOUR_JAVASCRIPT_KEY', { serverURL: 'https://parseapi.back4app.com' } ); Parse.serverURL = 'https://parseapi.back4app.com';Step 3: Query contacts and deals
Use the SDK to fetch Contact and Deal objects; filter deals by stage for the pipeline.
JavaScriptasync function getDeals(stage = 'qualified') { const query = new Parse.Query('Deal'); query.equalTo('stage', stage); query.ascending('expectedCloseDate'); const results = await query.find(); return results; } async function getContacts() { const query = new Parse.Query('Contact'); return await query.find(); }Step 4: Create a contact or deal
Create a new Contact or Deal with the required fields and pointers (company, contact, assignedTo), then save.
JavaScriptasync function createDeal(title, stage = 'lead', amount) { const Deal = Parse.Object.extend('Deal'); const deal = new Deal(); deal.set('title', title); deal.set('stage', stage); if (amount != null) deal.set('amount', amount); await deal.save(); return deal; } async function createContact(name, email, phone) { const Contact = Parse.Object.extend('Contact'); const contact = new Contact(); contact.set('name', name); if (email) contact.set('email', email); if (phone) contact.set('phone', phone); await contact.save(); return contact; }Step 5: Update deal stage and activities
Update Deal.stage when moving in the pipeline; create and list Activity by relatedTo.
JavaScript// Update deal stage (e.g. move in pipeline) async function updateDealStage(objectId, stage) { const query = new Parse.Query('Deal'); const deal = await query.get(objectId); deal.set('stage', stage); await deal.save(); } // Delete a deal async function deleteDeal(objectId) { const query = new Parse.Query('Deal'); const deal = await query.get(objectId); await deal.destroy(); }
State Management Integration
Integrate the Back4app SDK with your app's state layer (e.g. context, store, or services) for pipeline and contact state.
Full Data Model
Copy a complete CRM model for type-safe serialization (e.g. class, interface, or type definition).
// TypeScript interfaces for Deal and Contact (matches Back4app schema)
interface Deal {
objectId?: string;
title: string;
amount?: number;
stage?: string;
expectedCloseDate?: string;
contact?: { __type: string; className: string; objectId: string };
company?: { __type: string; className: string; objectId: string };
assignedTo?: { __type: string; className: string; objectId: string };
createdAt?: string;
updatedAt?: string;
}
interface Contact {
objectId?: string;
name: string;
email?: string;
phone?: string;
company?: { __type: string; className: string; objectId: string };
createdAt?: string;
updatedAt?: string;
}
function toDeal(obj: Parse.Object): Deal {
return {
objectId: obj.id,
title: obj.get('title'),
amount: obj.get('amount'),
stage: obj.get('stage'),
expectedCloseDate: obj.get('expectedCloseDate')?.toISOString?.() ?? undefined,
contact: obj.get('contact'),
company: obj.get('company'),
assignedTo: obj.get('assignedTo'),
createdAt: obj.get('createdAt')?.toISOString?.() ?? undefined,
updatedAt: obj.get('updatedAt')?.toISOString?.() ?? undefined,
};
}Offline-First & Local Datastore
Use pin() and unpin() so contacts and deals are available offline and sync when back online.
Supported SDKs include a local datastore. Pin Contact, Deal, and Activity objects to keep them on device; query pinned data when offline. When the app is back online, sync with the server.
Below: pin results after fetch, and unpin when you no longer need local copies.
// 1. Enable local datastore (e.g. before Parse.initialize)
Parse.enableLocalDatastore();
// 2. After fetching deals, pin them for offline access
async function fetchAndPinDeals() {
const query = new Parse.Query('Deal');
query.equalTo('stage', 'qualified');
query.ascending('expectedCloseDate');
const results = await query.find();
await Parse.Object.pinAll(results);
return results;
}
// 3. When offline (or for instant load), query from local datastore
async function getDealsFromLocal() {
const query = new Parse.Query('Deal');
query.fromLocalDatastore();
return await query.find();
}
// 4. Unpin when no longer needed
async function unpinAllDeals() {
await Parse.Object.unpinAll('Deal');
}Frequently Asked Questions
Common questions about the CRM app backend template.
Ready to Build Your CRM App?
Start your React project in minutes. No credit card required.