Frappe Framework 101: Complete ERPNext & Python Web Development Guide
Master Frappe Framework & ERPNext! Learn DocTypes, Python ORM, MariaDB/Postgres setup, Desk UI, Hooks, and REST API development with real code examples.

Header Ad Advertisement
If you want to build complex, enterprise-grade Python web applications or customize ERPNext (the world's top open-source ERP), the Frappe Framework is one of the most powerful full-stack web frameworks in the software ecosystem.
Unlike Django or Flask where you manually write HTML forms, database migrations, authentication, and REST endpoints from scratch, Frappe uses a meta-data driven architecture.
You define a DocType (a blueprint for data), and Frappe automatically builds the database schema, administrative Desk UI, role-based permissions, and REST APIs for you!
In this comprehensive guide, we will walk you through Frappe Bench setup, DocTypes, Python ORM, Hooks, and REST API integrations.
1. Frappe Architecture Overview
Frappe combines proven open-source technologies into a unified stack:
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ ๐ฅ๏ธ Desk UI (Vue.js / jQuery / Bootstrap UI Engine) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ ๐ Python WSGI Backend (Werkzeug / Jinja2 / Python 3.10+) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ ๐๏ธ Database Layer (MariaDB 10.6+ / PostgreSQL 14+) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ โก Background Queue (Redis + Celery / Python RQ Worker) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
2. Setting Up Frappe Bench CLI
The Bench CLI is the command-line Swiss Army knife for Frappe development:
# 1. Install Bench CLI using pip
pip3 install frappe-bench
# 2. Initialize a new bench environment with MariaDB & Redis
bench init frappe-bench --frappe-branch version-15
# 3. Create a new local development site
cd frappe-bench
bench new-site mysite.local
# 4. Start local development server (Default Port: 8000)
bench start
3. Creating Your First App & Custom DocType
To create a new app named library_management:
# Create custom app inside apps/ directory
bench new-app library_management
# Install app on your local site
bench --site mysite.local install-app library_management
๐ What Is a DocType?
In Frappe, a DocType represents both a database table AND a UI form.
Suppose we create a Library Member DocType:
{
"doctype": "DocType",
"name": "Library Member",
"module": "Library Management",
"custom": 0,
"fields": [
{ "fieldname": "first_name", "fieldtype": "Data", "label": "First Name", "reqd": 1 },
{ "fieldname": "last_name", "fieldtype": "Data", "label": "Last Name" },
{ "fieldname": "email_address", "fieldtype": "Data", "options": "Email", "reqd": 1 },
{ "fieldname": "phone_number", "fieldtype": "Phone", "label": "Phone" },
{ "fieldname": "membership_status", "fieldtype": "Select", "options": "Active\nExpired\nCancelled", "default": "Active" }
],
"permissions": [
{ "role": "Library Manager", "read": 1, "write": 1, "create": 1, "delete": 1 }
]
}
4. Python Controller & ORM API
Every DocType has a corresponding Python controller file where you write backend validation business logic:
# library_management/library_management/doctype/library_member/library_member.py
import frappe
from frappe.model.document import Document
class LibraryMember(Document):
def validate(self):
"""Runs automatically before inserting or saving a record"""
if self.email_address and "@" not in self.email_address:
frappe.throw("Please enter a valid email address for library member.")
# Capitalize full name automatically
self.first_name = self.first_name.strip().title()
def on_submit(self):
"""Runs when document is submitted"""
frappe.msgprint(f"Library Membership activated for {self.first_name}!")
๐ Frappe Python ORM Cheat Sheet
# Create new document record
member = frappe.get_doc({
"doctype": "Library Member",
"first_name": "Sumit",
"email_address": "sumit@vyuhantrix.com"
})
member.insert()
# Query single record
doc = frappe.get_doc("Library Member", "MEM-0001")
# Database List Query
active_members = frappe.db.get_all(
"Library Member",
filters={"membership_status": "Active"},
fields=["name", "first_name", "email_address"]
)
5. Built-in REST API
Frappe automatically exposes a secure REST API for every single DocType out of the box!
GET /api/resource/Library%20Member?fields=["name","first_name","email_address"] HTTP/1.1
Host: mysite.local
Authorization: token api_key:api_secret
Response JSON:
{
"data": [
{ "name": "MEM-0001", "first_name": "Sumit", "email_address": "sumit@vyuhantrix.com" }
]
}
Mid Content Ad Advertisement
Interactive Developer Tools & Calculators
View All Tools โJSON Formatter
Format, validate and beautify JSON with syntax highlighting and error detection.
Base64 Encoder
Encode and decode Base64 strings and files instantly in your browser.
JWT Decoder
Decode and inspect JSON Web Tokens โ header, payload, claims, and expiry.
Regex Tester
Test and debug regular expressions with live match highlighting and flag toggles.
Editorial Disclaimer
The information in this article is provided for educational and informational purposes only. While we strive for accuracy, content may become outdated as technologies, regulations, and best practices evolve. Learntrix and Vyuhantrix make no warranties regarding the completeness, accuracy, or applicability of the information to your specific situation. Always verify critical information from primary and authoritative sources before implementation.
Last content review: August 2026 ยท Learntrix by Vyuhantrix
Copyright 2026 Vyuhantrix Technologies. All content on Learntrix is the intellectual property of Vyuhantrix. Reproduction, distribution, or republishing of this article โ in whole or in part โ without written permission from Vyuhantrix is strictly prohibited.
Footer Article Ad Advertisement
Related Articles
View all in Programming & Development โ
ERPNext Customization Masterclass: DocTypes, Server Scripts & Jinja Print Formats
Learn how to customize ERPNext without breaking core updates! Master Client Scripts (JS), Server Scripts (Python), Custom Fields, and Jinja PDF templates.

How Does a Solar Eclipse Work: Umbra, Penumbra & Geometry Explained Simply
Why does the Moon cover the Sun so perfectly? Learn the orbital geometry, umbra, penumbra, and total vs partial solar eclipses with simple 8th-grade analogies.
