Developers
Building Frappe apps means writing Python + JavaScript + JSON. The platform handles the framework concerns (auth, DB, UI rendering, API); your app provides the domain logic.
App structure
my_app/
├── my_app/
│ ├── hooks.py # Wire up doc_events, fixtures, web routes
│ ├── install.py # after_install, after_migrate
│ ├── modules.txt
│ ├── my_module/
│ │ ├── doctype/ # Your DocTypes (one folder each)
│ │ ├── custom/ # Hook handlers for OTHER apps' DocTypes
│ │ ├── report/
│ │ └── workspace/
│ └── public/ # JS, CSS, images
├── pyproject.toml
└── setup.py
Key extension points (hooks.py)
| Hook | Use |
|---|---|
doc_events |
React to lifecycle events on any DocType (validate, on_submit, on_cancel) |
doctype_js |
Inject client-side scripts into specific DocType forms |
scheduler_events |
Run code on cron schedules (hourly, daily, custom cron) |
permission_query_conditions |
Filter list views by custom permission logic |
override_doctype_class |
Replace the controller for a DocType with your own |
fixtures |
Ship reference data (Roles, Workspaces, Custom Fields) with the app |
DocType lifecycle
class MyDoc(Document):
def before_insert(self): ... # Before first save
def validate(self): ... # Before any save
def on_update(self): ... # After save
def before_submit(self): ... # Before submit
def on_submit(self): ... # After submit
def on_cancel(self): ... # After cancel
def on_trash(self): ... # Before delete
Where to dig deeper
- Frappe developer docs: frappeframework.com/docs
- Frappe source: github.com/frappe/frappe
- Frappe School (paid courses): frappe.school
Last updated 3 days ago
Was this helpful?