Understanding the Basics of Frappe Framework (Version 15)
Introduction — What Is the Frappe Framework?
The Frappe Framework is a full-stack, metadata-driven, Python-based web application framework used to build powerful business applications, including ERPNext. In Version 15, Frappe continues to offer an intuitive development environment with a strong focus on low-code extensibility, rapid customization, and maintainability.
Frappe follows the Model-View-Controller (MVC) pattern, integrates seamlessly with MariaDB, and provides built-in tooling such as Desk UI, REST APIs, role permissions, background jobs, real-time updates, and a complete website engine.
Understanding the basics of Frappe is the first step toward building scalable ERP, SaaS, and enterprise applications.
What Are the Core Concepts of Frappe?
Frappe is built on a few essential pillars:
- DocTypes → Data models + Controllers
- Desk UI → Form view, List view, Report view
- Metadata → Defines how a DocType behaves
- Controllers → Python backend logic
- Client Scripts → JS logic for UI
- REST API → Standard API for all DocTypes
- Website Engine → Web pages, portals, and Jinja templates
- Role & Permission System → User access control
- Bench CLI → Server management and toolchain
These concepts together create a flexible environment for building applications rapidly.
Understanding DocTypes — The Heart of Frappe
A DocType is the core building block of the framework.
Every piece of data, every master, and every transaction in ERPNext is represented as a DocType.
DocTypes Define:
- Database tables
- Form layout
- Field types
- Field properties
- Permissions
- Workflows
- Controllers (Python + JS)
- Child tables
- Dashboard integrations
Example Directory Structure:
my_app/
└── my_app/
└── doctype/
└── customer/
├── customer.json # Metadata
├── customer.py # Backend controller
├── customer.js # Client script
└── customer.html # Optional (Web view)
Metadata — How Frappe Defines Structure
Frappe uses a metadata-driven architecture.
This means the whole application structure is stored in JSON files and synced to the database.
Example JSON (customer.json):
{
"doctype": "DocType",
"name": "Customer",
"module": "CRM",
"fields": [
{
"fieldname": "customer_name",
"fieldtype": "Data",
"label": "Customer Name",
"reqd": 1
}
]
}
Metadata ensures consistency between code, database, and UI.
Desk — The User Interface Layer
Desk is Frappe’s backend interface used by users, admins, and developers.
It supports:
- Form view
- List view
- Tree view
- Calendar view
- Kanban view
- Pivot reports
- Custom dashboards
Everything in Desk is generated based on the DocType metadata.
Controllers — Backend Logic in Python (v15)
Each DocType can include a Python controller for business logic.
Common Methods in Controllers:
| Method | Description |
| validate | Runs before saving |
| before_save | Before save logic |
| after_insert | After record creation |
| on_update | After record updated |
| before_submit | Before document submission |
| on_submit | When document is submitted |
| on_cancel | When document is cancelled |
Example Python Controller (v15 syntax):
import frappe
from frappe.model.document import Document
class Customer(Document):
def validate(self):
if len(self.customer_name) < 3:
frappe.throw("Customer Name must be at least 3 characters.")
Client Scripts — Frontend Logic Using JavaScript
Client Scripts modify form behavior in Desk.
Example:
frappe.ui.form.on("Customer", {
refresh(frm) {
frm.set_intro("Fill customer details carefully.");
}
});
Frappe MVC Architecture — How Everything Works Together
Model
DocType + Database + Metadata
Represented by .json + .py files
View
Desk UI, Website pages, Jinja templates
Client Scripts (JS)
Controller
Python methods for business logic
JavaScript events for UI logic
This architecture makes Frappe modular, clean, and easy to extend.
Website & Portal — Frontend Framework Included
Frappe includes a complete website engine with:
-
- Web pages (.html)
- Jinja templating
- Portal pages
- Web forms
- Dynamic routing
- Public & private pages
- Theming with Website Settings
Example Jinja Template:
<h1>{{ doc.customer_name }}</h1>
<p>Email: {{ doc.email_id }}</p>
REST API — Built Automatically for Every DocType
Frappe generates REST endpoints for all DocTypes without extra coding.
GET List
/api/resource/Customer
GET Single Record
/api/resource/Customer/CUST-0001
POST (Create)
{
"customer_name": "ABC Corp"
}
Authentication Options:
- API Key
- Token
- OAuth
- Session-based
Permissions System — Role-Based Access Control (RBAC)
Frappe uses a layered permission model:
- Role Permissions → Read/Write/Create/Delete
- User Permissions → Record-level access
- Field-Level Permissions → Hide/Show fields
- Document Sharing → Share specific records
Example:
A Sales User can only access Customers assigned to them.
Reports & Query Builder
Frappe includes:
- Script Reports
- Query Reports
- Dashboard Charts
- Pivot Tables
- Custom Reports (No code)
Example Script Report Query:
frappe.db.sql("""
SELECT name, customer_name, creation
FROM tabCustomer
""")
Background Jobs — Asynchronous Processing
Uses Frappe’s Queue Worker powered by Python + Redis.
Example:
frappe.enqueue("my_app.tasks.send_bulk_emails")
Real-Time Events — WebSocket Powered
Frappe uses Socket.IO for:
- Notifications
- Chat
- Real-time updates
- Dashboard data refresh
Example:
frappe.realtime.on("msg_print", (data) => {
console.log(data);
});
Best Practices for Working with Frappe v15
- Use DocTypes instead of custom SQL tables
- Avoid overriding core methods — use Hooks
- Use frappe.call() for client-server communication
- Use REST API for integrations
- Keep business logic in Python controllers
- Use Custom Scripts instead of editing core JS
- Use Naming Series for document naming
- Use User Permissions for record-level security
Troubleshooting Basics
| Issue | Cause | Solution |
| Form not loading | Missing field in JSON | Run bench migrate |
| JS not executing | Wrong DocType name | Check console for errors |
| API permission error | Missing role | Check Role Permission Manager |
| Template not rendering | Wrong route | Clear cache: bench clear-cache |
Cross-References (Related Tutorials)
- Create a Site in Frappe v15
- Create a DocType in Frappe v15
- Controller Methods in Frappe v15
- Form Scripts in Frappe v15
- Portal Pages in Frappe v15