Understanding the Directory Structure of Frappe Framework (Version 15)
Introduction & Context
The directory structure of the Frappe Framework defines how every app, module, and DocType is organized inside a Frappe project. In Version 15, the structure remains modular, predictable, and developer-friendly, allowing clean separation between server-side, client-side, and configuration files. Understanding this hierarchy is essential for building, customizing, and maintaining ERPNext or any Frappe-based application.
This guide explains each folder and file in a Frappe bench, Frappe app, and module, with Version-15-accurate examples.
What Is the Directory Structure in Frappe Framework v15?
The directory structure in Frappe v15 is the organized layout of folders and files that define:
- Bench environment
- Sites
- Apps
- Modules
- DocTypes
- Controllers
- Scripts
- Print formats, Reports, Web pages, REST endpoints, and more
Each layer has a specific purpose and must follow Frappe conventions to work correctly.
Bench Directory Structure Overview
A standard Frappe bench (created using bench init) contains:
frappe-bench/
│
├── apps/
├── sites/
├── config/
├── logs/
├── env/
├── Procfile
├── README.md
apps/
Contains all installed applications, including:
- frappe
- erpnext
- custom apps created via bench new-app
sites/
Holds all site environments:
- site_config.json
- public files
- private files
- database connections
- assets
config/
Bench-level configuration:
- redis
- supervisor configurations
- nginx templates
logs/
Runtime logs including workers, scheduler, and request errors.
Frappe App Directory Structure (v15)
When you run bench new-app my_app, the generated folder looks like:
my_app/
│
├── my_app/
│ ├── config/
│ ├── modules.txt
│ ├── startup.py
│ ├── hooks.py
│ ├── __init__.py
│ ├── public/
│ ├── templates/
│ ├── www/
│ └── <module folders>
│
├── MANIFEST.in
├── README.md
├── setup.py
└── patches.txt
Key Components
hooks.py (Most important file)
Controls:
- DocType events
- Page/Report overrides
- API endpoints
- Fixtures
- Permissions
- Scheduled tasks
- Web templates
Example:
doc_events = {
"Sales Invoice": {
"validate": "my_app.api.validate_invoice"
}
}
modules.txt
List of module names inside the app.
Frappe uses this to generate module-level directories.
config/
Contains desktop icons, menu definitions, and workspace configuration.
public/
Static assets: JS, CSS, images.
Automatically served via /assets/my_app.
templates/
Jinja templates for web pages, emails, print formats.
www/
Public website pages like:
www/index.html
www/features.html
Module Directory Structure in Frappe
Each module inside an app (e.g., “CRM”, “Manufacturing”) contains its own folder:
my_app/
└── my_app/
└── crm/
├── doctype/
├── report/
├── page/
├── dashboard_chart/
├── module_name.json
├── __init__.py
Each subfolder relates to a feature type.
doctype/
Holds folder structures for each DocType:
lead/
│
├── lead.json # Metadata
├── lead.py # Controller class
├── lead_list.js # List view logic
├── lead_list.json # List view config
├── lead_dashboard.py # Dashboard config
└── lead.js # Client script
report/
Each Report has:
sales_report/
│
├── sales_report.json
└── sales_report.py
page/
Custom Pages (client-side UI):
page_name/
├── page_name.js
├── page_name.py
└── page_name.html
dashboard_chart/
For analytics dashboard widgets.
DocType Folder Structure (Fully Explained)
A DocType automatically generates:
| File | Purpose |
| <doctype>.json | Stores all fields, metadata, permissions |
| <doctype>.py | Server-side controller class |
| <doctype>.js | Form-level scripting |
| <doctype>_list.js | List view JS |
| <doctype>_list.json | List view configuration |
| <doctype>_dashboard.py | Dashboard metrics |
| test_<doctype>.py | Unit tests |
Example layout:
task/
│
├── task.json
├── task.py
├── task.js
├── task_list.js
├── task_list.json
├── task_dashboard.py
└── test_task.py
Configuration & Setup Files in Frappe Apps
setup.py
Defines installation requirements and package information.
Example:
install_requires = ["frappe"]
MANIFEST.in
Includes static and template files during app packaging.
patches.txt
Lists database patches executed during app migrations.
Understanding Site Directory Structure (v15)
Inside /sites/<site_name>/:
site/
│
├── site_config.json
├── apps.txt
├── public/
├── private/
├── logs/
├── database/
└── assets/
site_config.json
Contains:
- DB credentials
- Redis settings
- Installed apps
Example:
{
"db_name": "site1",
"db_password": "pass123"
}
public/
Publicly accessible files:
- images
- web assets
private/
Internal-only files:
- private attachments
- backups
apps.txt
List of installed apps for this specific site.
Best Practices for Working with Frappe Directory Structure
1. Keep Custom Code Inside Apps
Never modify the core frappe/ or erpnext/ app.
2. Use Proper Module Naming
Consistent naming ensures predictable paths.
3. Keep DocType Folders Clean
Do not add extra files inside DocType folders.
4. Use Bench Commands
Avoid editing generated files manually.
5. Version Control Everything
Commit only your custom app, not the bench environment.
Common Mistakes & Troubleshooting
| Issue | Cause | Fix |
| App not appearing in Desk | Missing module in modules.txt | Add module name & reinstall |
| ImportError for module | Wrong folder structure | Verify __init__.py exists |
| Static files not loading | Files missing in public folder | Run bench build |
| Hooks not triggering | Incorrect dotted path | Verify paths in hooks.py |
Cross-References (Recommended Reading)
These topics naturally follow after directory structure:
- Frappe Architecture (Version 15)
- DocType Creation in Frappe
- Controller Methods (validate, before_save, etc.)
- Form Scripts in Frappe (Client Scripts)
- REST API & Server Scripts
Conclusion
The directory structure of Frappe Framework v15 forms the backbone of all development activity—from DocTypes and server-side controllers to static assets and custom pages. Mastering this structure enables developers to build stable, scalable, and maintainable applications on Frappe and ERPNext.
Frappe Framework Directory Structure (Version 15)
Based strictly on:
Reference: https://docs.frappe.io/framework/user/en/basics/directory-structure
GitHub (v15): https://github.com/frappe/frappe/tree/version-15