Skip to content
AI & Agents
Skill

/frappe-syntax-hooks

Use when configuring Frappe hooks.py for app events, scheduler tasks, document events, fixtures, boot session, jenv customization, or website routing. Covers v14/v15/v16 including extend_doctype_class. Keywords: hooks.py, doc_events, scheduler_events, fixtures, app_include_js,

From plugin
frappe-claude-skill-package
17961 skills
Install
$ npx -y skills add Impertio-Studio/Frappe_Claude_Skill_Package --skill frappe-syntax-hooks --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/frappe-syntax-hooks

Context preview

The summary Claude sees to decide when to auto-load this skill.

Use when configuring Frappe hooks.py for app events, scheduler tasks, document events, fixtures, boot session, jenv customization, or website routing. Covers v14/v15/v16 including extend_doctype_class. Keywords: hooks.py, doc_events, scheduler_events, fixtures, app_include_js,

SKILL.md

frappe-syntax-hooks.SKILL.md
name: frappe-syntax-hooks
description: >
  Use when configuring Frappe hooks.py for app events, scheduler tasks,
  document events, fixtures, boot session, jenv customization, or website
  routing. Covers v14/v15/v16 including extend_doctype_class. Keywords:
  hooks.py, doc_events, scheduler_events, fixtures, app_include_js,
  override_whitelisted_methods, extend_doctype_class,
  hooks.py example, how to register hook, available hooks list, extend_doctype_class example.
license: MIT
compatibility: "Claude Code, Claude.ai Projects, Claude API. Frappe v14-v16."
metadata:
  author: OpenAEC-Foundation
  version: "2.0"

Frappe Configuration Hooks (hooks.py)

Configuration hooks in hooks.py enable custom apps to extend Frappe/ERPNext behavior. This skill covers ALL non-document-event hooks. For `doc_events` (validate, on_submit, on_update, etc.), see **frappe-syntax-hooks-events**.

Quick Reference: Hook Categories

| Category | Key Hooks | Reference | |----------|-----------|-----------| | App metadata | `app_name`, `app_title`, `required_apps` | Below | | Frontend assets | `app_include_js/css`, `web_include_js/css` | Below | | Install/migrate | `before_install`, `after_install`, `after_migrate` | Below | | Scheduler | `hourly`, `daily`, `cron`, `*_long` | [scheduler-events.md](references/scheduler-events.md) | | Session/auth | `on_login`, `on_logout`, `auth_hooks` | [bootinfo.md](references/bootinfo.md) | | Request middleware | `before_request`, `after_request` | [request-lifecycle.md](references/request-lifecycle.md) | | Permissions | `permission_query_conditions`, `has_permission` | [permissions.md](references/permissions.md) | | DocType overrides | `override_doctype_class`, `doctype_js` | [overrides.md](references/overrides.md) | | Website/portal | `website_route_rules`, `portal_menu_items` | [request-lifecycle.md](references/request-lifecycle.md) | | File handling | `before_write_file`, `write_file` | Below | | Email | `override_email_send`, `default_mail_footer` | Below | | PDF | `pdf_header_html`, `pdf_footer_html` | Below | | Jinja | `jinja.methods`, `jinja.filters` | Below | | Boot/client data | `extend_bootinfo`, `notification_config` | [bootinfo.md](references/bootinfo.md) | | Data/fixtures | `fixtures`, `global_search_doctypes` | Below | | Method overrides | `override_whitelisted_methods`, `standard_queries` | [overrides.md](references/overrides.md) |

---

Decision Tree: Which Hook Do I Need?

What do you want to achieve?
|
+-- ADD JS/CSS to desk or portal?
|   +-- Desk --> app_include_js / app_include_css
|   +-- Portal --> web_include_js / web_include_css
|   +-- Specific form --> doctype_js
|   +-- List view --> doctype_list_js
|
+-- RUN periodic background tasks?
|   +-- < 5 min execution --> hourly / daily / weekly / monthly
|   +-- 5-25 min execution --> hourly_long / daily_long / etc.
|   +-- Exact time needed --> cron
|   See: frappe-syntax-hooks > scheduler-events.md
|
+-- SEND data to client at page load?
|   +-- extend_bootinfo
|
+-- MODIFY controller of existing DocType?
|   +-- v16+ --> extend_doctype_class (RECOMMENDED)
|   +-- v14/v15 --> override_doctype_class (last app wins)
|
+-- MODIFY API endpoint?
|   +-- override_whitelisted_methods
|
+-- CUSTOMIZE permissions?
|   +-- List filtering --> permission_query_conditions
|   +-- Document-level --> has_permission
|
+-- REACT to document save/submit/delete?
|   +-- See frappe-syntax-hooks-events skill
|
+-- EXPORT/IMPORT configuration?
|   +-- fixtures
|
+-- SETUP on install or migrate?
|   +-- after_install / after_migrate
|
+-- ADD custom Jinja functions?
|   +-- jinja.methods / jinja.filters
|
+-- CUSTOMIZE website routing?
|   +-- website_route_rules
|   See: request-lifecycle.md for full routing pipeline
|
+-- INTERCEPT every request/response?
|   +-- before_request / after_request
|   See: request-lifecycle.md for lifecycle flow
|
+-- CUSTOM page rendering?
|   +-- page_renderer hook
|   See: request-lifecycle.md for renderer architecture

---

1. App Metadata Hooks

ALWAYS include these in every hooks.py:

app_name = "myapp"
app_title = "My App"
app_publisher = "My Company"
app_description = "Custom ERPNext extensions"
app_email = "info@mycompany.com"
app_license = "MIT"
required_apps = ["erpnext"]  # Declare dependencies

---

2. Frontend Asset Injection

# Desk (backend UI) assets — loaded on EVERY desk page
app_include_js = "/assets/myapp/js/myapp.min.js"       # string or list
app_include_css = "/assets/myapp/css/myapp.min.css"

# Website/portal assets — loaded on EVERY web page
web_include_js = "/assets/myapp/js/web.min.js"
web_include_css = "/assets/myapp/css/web.min.css"

# Web form specific assets
webform_include_js = {"My Web Form": "public/js/my_webform.js"}
webform_include_css = {"My Web Form": "public/css/my_webform.css"}

# Form script extensions (extend OTHER apps' forms)
doctype_js = {"Sales Invoice": "public/js/sales_invoice.js"}

# List view script extensions
doctype_list_js = {"Sales Invoice": "public/js/sales_invoice_list.js"}

# Custom sounds
sounds = [{"name": "alert", "src": "/assets/myapp/sounds/alert.mp3", "volume": 0.5}]

NEVER put heavy libraries in `app_include_js` — they load on every page.

---

3. Installation & Migration Lifecycle

before_install = "myapp.setup.before_install"
after_install = "myapp.setup.after_install"
after_sync = "myapp.setup.after_sync"            # After fixture sync
before_migrate = "myapp.setup.before_migrate"
after_migrate = "myapp.setup.after_migrate"
before_uninstall = "myapp.setup.before_uninstall"
after_uninstall = "myapp.setup.after_uninstall"
before_tests = "myapp.setup.seed_test_data"

All accept a single dotted-path string. The function receives no arguments.

---

4. Scheduler Events

See [scheduler-events.md](references/scheduler-events.md) for full reference.

scheduler_events = {
    "all": ["myapp.tasks.every_minute"],            # ~60s interval
    "hour
Read more
Ships withfrappe-claude-skill-package

60 deterministic Claude AI skills for Frappe Framework & ERPNext v14-v16 development and operations

Get the whole plugin
Stats
178
Stars
53
Forks
Maintained
Maintenance
Python
Language
2mo ago
Last commit
8mo ago
Created
14d ago
Added

Repo: Impertio-Studio/Frappe_Claude_Skill_Package