Skip to main content

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:

  1. Role Permissions → Read/Write/Create/Delete
  2. User Permissions → Record-level access
  3. Field-Level Permissions → Hide/Show fields
  4. 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
Click to rate this post!
[Total: 1 Average: 5]