Tutorials/Framework Architecture & Core Concepts

Framework Architecture & Core Concepts

Frappe Framework Architecture — Core Concepts

Frappe Framework Architecture
Frappe Framework Architecture

Site

A Site is a single Frappe tenant (e.g., yoursite.erpnext.com). Each site has its own MariaDB database, file system, and config. Multiple sites run on one server with full data isolation.

Apps

An App is a Python package on a bench — e.g., frappe, erpnext, custom_app. Apps provide DocTypes, APIs, and hooks.

Modules

A Module groups related DocTypes within an app — e.g., Accounts, HR, Manufacturing, CRM.

DocType

A DocType is the fundamental building block — defines a data entity's fields, permissions, and behaviour. Every form in Frappe is a DocType. Stored as JSON in the app.

DocField

A DocField defines one field within a DocType: Data, Int, Date, Link, Table, Select, Attach, etc.

Virtual DocType

A Virtual DocType (isvirtual=1) has no MariaDB table — data fetched from external source by overriding getlist() and get_doc().

Virtual DocField

A Virtual DocField has no DB column — value computed at runtime, ideal for derived/calculated fields.

Metadata-Driven Framework — DocType = Class, Document = Object

The Analogy

What Metadata-Driven Means

  • Schema stored as data in MariaDB — tabDocType and tabDocField hold the entire schema
  • Forms auto-generated from DocType fields — no HTML to write
  • Permissions, Workflows, Print Formats configured via UI — stored as DocType records
  • Add a field → form updates immediately, MariaDB column added automatically
  • For : IT team adds custom fields without code or deployment

DocType Definition — JSON, Python Controller & Lifecycle

JSON Definition

Every DocType is a JSON file in the app codebase — version-controlled in git.

DocType JSON Definition
DocType JSON Definition
  • autoname — naming rule
  • engine: "InnoDB" — MariaDB storage engine
  • fields — array of DocField definitions (fieldname, fieldtype, label, mandatory)
  • permissions — role-based access control baked in
  • states — workflow states (Draft, Submitted, Cancelled)

Python Controller

The Python controller inherits from Document and overrides lifecycle methods to add business logic.

Python Controller
Python Controller

Lifecycle Events

Low-Code + High-Code — Frappe's Sweet Spot

Frappe uniquely combines a low-code platform for business users with a full-code framework for developers — both coexist without conflict, safe across upgrades.

High-code Controller Example
High-code Controller Example

Low-Code

  • DocType builder via UI — drag-drop fields, auto-generated forms
  • Visual Workflow builder, Automation Rules, Server Scripts in browser
  • Custom Fields on any DocType — no code, no deployment
  • Print Format designer, Dashboard and Charts builder

High-Code

  • Full Python controller classes with lifecycle hooks
  • @frappe.whitelist() — any Python function as REST API
  • Client Scripts — JS per DocType for form events
  • Full MariaDB access via frappe.db.* | Background jobs via frappe.enqueue()

Customisation Without Touching Core — hooks.py

hooks.py integrates your custom app with Frappe without modifying a single line of ERPNext source.

hooks.py integration diagram
hooks.py — integrating a custom app without touching ERPNext core

overridedoctypeclass

override_doctype_class = {

"Custom DocType": "custom_app.overrides.custom_doctype.CustomStudentGroup",

"Employee": "custom_app.overrides.employee.CustomEmployee",

}

doc_events

doc_events = {

"Sales Invoice": {"on_submit": "my_app.custom_logic.on_invoice_submit"},

"record": {"validate": "custom_app.validators.validate_student"}

}

Other Key Hooks

  • Zero ERPNext source changes — ships as separate custom_app app
  • Upgrade-safe — bench update never breaks customisations
  • Git-trackable — entire customisation is a Python package

Need help with your workflow setup?

If you're stuck or want help applying these guides to your setup, our team can assist with configuration, customization, and workflow implementation.

WhatsApp