erpnext-impl-customapp
npx machina-cli add skill OpenAEC-Foundation/ERPNext_Anthropic_Claude_Development_Skill_Package/erpnext-impl-customapp --openclawERPNext Custom App - Implementation
This skill helps you determine HOW to build and structure Frappe/ERPNext custom apps. For exact syntax, see erpnext-syntax-customapp.
Version: v14/v15/v16 compatible (differences noted)
Main Decision: What Are You Building?
┌─────────────────────────────────────────────────────────────────────────┐
│ WHAT DO YOU WANT TO CREATE? │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ ► Completely new Frappe/ERPNext app? │
│ └─► See: NEW APP WORKFLOW │
│ │
│ ► Extend existing ERPNext functionality? │
│ └─► See: EXTENSION DECISION │
│ │
│ ► Migrate data between fields/DocTypes? │
│ └─► See: PATCH vs FIXTURE DECISION │
│ │
│ ► Export configuration for deployment? │
│ └─► See: FIXTURE WORKFLOW │
│ │
│ ► Update existing app to newer Frappe version? │
│ └─► See: VERSION UPGRADE WORKFLOW │
│ │
└─────────────────────────────────────────────────────────────────────────┘
Decision 1: Do You Need a Custom App?
┌─────────────────────────────────────────────────────────────────────────┐
│ DO YOU ACTUALLY NEED A CUSTOM APP? │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ What changes do you need? │
│ │
│ ► Add fields to existing DocType? │
│ └─► NO APP NEEDED: Use Custom Field + Property Setter │
│ (Can be exported as fixtures from ANY app) │
│ │
│ ► Simple automation/validation? │
│ └─► NO APP NEEDED: Server Script or Client Script │
│ (Stored in database, no deployment needed) │
│ │
│ ► Complex business logic, new DocTypes, or Python code? │
│ └─► YES, CREATE APP: You need controllers, models, and deployment │
│ │
│ ► Integration with external system? │
│ └─► USUALLY YES: APIs need whitelisted methods, scheduled sync │
│ │
│ ► Custom reports with complex queries? │
│ └─► DEPENDS: Script Report (no app) vs Query Report (app optional) │
│ │
└─────────────────────────────────────────────────────────────────────────┘
Rule: Start with the SIMPLEST solution. Server Scripts + Custom Fields solve 70% of customization needs without a custom app.
Decision 2: Extension Strategy
┌─────────────────────────────────────────────────────────────────────────┐
│ HOW TO EXTEND ERPNext? │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ ► Add fields to existing DocType (e.g., Sales Invoice)? │
│ └─► Custom Field (via UI or fixtures) │
│ └─► Property Setter for behavior changes │
│ │
│ ► Modify DocType behavior/logic? │
│ ├─► v16: Use `extend_doctype_class` hook (PREFERRED) │
│ └─► v14/v15: Use `doc_events` hooks in hooks.py │
│ │
│ ► Override Jinja template? │
│ └─► Copy template to your app's templates/ folder │
│ └─► Register via `jinja.override_template` in hooks.py │
│ │
│ ► Add new DocType related to existing? │
│ └─► Create in your app's module │
│ └─► Link via Link field or Dynamic Link │
│ │
│ ► Add new workspace/menu items? │
│ └─► Create Workspace DocType in your app │
│ └─► Or use `standard_portal_menu_items` hook │
│ │
└─────────────────────────────────────────────────────────────────────────┘
See:
references/decision-tree.mdfor detailed extension patterns.
Decision 3: Patch vs Fixture
┌─────────────────────────────────────────────────────────────────────────┐
│ SHOULD THIS BE A PATCH OR A FIXTURE? │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ Is it CONFIGURATION that should be the same everywhere? │
│ (Custom Fields, Roles, Workflows, Property Setters) │
│ └─► USE FIXTURE │
│ │
│ Is it a ONE-TIME data transformation? │
│ (Migrate old field values, cleanup bad data, populate defaults) │
│ └─► USE PATCH │
│ │
│ Does it need to run BEFORE schema changes? │
│ (Backup data from field that will be deleted) │
│ └─► USE PATCH with [pre_model_sync] │
│ │
│ Does it need to run AFTER schema changes? │
│ (Populate newly added field with calculated values) │
│ └─► USE PATCH with [post_model_sync] │
│ │
│ Is it master data / lookup tables? │
│ (Categories, Status options, Configuration records) │
│ └─► USE FIXTURE for initial, PATCH for updates │
│ │
└─────────────────────────────────────────────────────────────────────────┘
See:
references/decision-tree.mdfor patch timing flowchart.
Decision 4: Module Organization
┌─────────────────────────────────────────────────────────────────────────┐
│ HOW MANY MODULES DO YOU NEED? │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ Small app (1-5 DocTypes, single purpose)? │
│ └─► ONE MODULE with app name │
│ Example: my_app/my_app/ (module "My App") │
│ │
│ Medium app (6-15 DocTypes, multiple areas)? │
│ └─► 2-4 MODULES by functional area │
│ Example: core/, settings/, integrations/ │
│ │
│ Large app (15+ DocTypes, complex domain)? │
│ └─► MODULES by business domain │
│ Example: inventory/, sales/, purchasing/, settings/ │
│ │
│ Multi-tenant or vertical solution? │
│ └─► Consider MULTIPLE APPS instead │
│ Base app + vertical-specific apps │
│ │
└─────────────────────────────────────────────────────────────────────────┘
Rule: Each DocType belongs to EXACTLY one module. Choose module = where would a user look for this DocType?
Quick Implementation Workflows
New App Workflow
1. Create app structure → bench new-app my_app
2. Configure pyproject → Edit pyproject.toml (v15+) or setup.py (v14)
3. Define modules → Edit modules.txt
4. Create DocTypes → bench --site mysite new-doctype MyDocType
5. Write controllers → my_app/doctype/my_doctype/my_doctype.py
6. Configure hooks → hooks.py for integration
7. Export fixtures → bench --site mysite export-fixtures
8. Test installation → bench --site testsite install-app my_app
See:
references/workflows.mdfor detailed steps.
Patch Workflow
1. Plan the migration → What data moves where?
2. Choose timing → [pre_model_sync] or [post_model_sync]
3. Write patch file → myapp/patches/v1_0/description.py
4. Add to patches.txt → Under correct section
5. Test locally → bench --site testsite migrate
6. Handle errors → Add rollback logic if needed
7. Test on copy of prod → ALWAYS before production
See:
references/workflows.mdfor patch patterns.
Fixture Workflow
1. Configure hooks.py → Define fixtures list with filters
2. Make changes via UI → Custom Fields, Property Setters, etc.
3. Export fixtures → bench --site mysite export-fixtures --app my_app
4. Verify JSON files → Check my_app/fixtures/*.json
5. Commit to version control
6. Test import → bench --site newsite migrate
See:
references/workflows.mdfor fixture strategies.
Version-Specific Considerations
| Aspect | v14 | v15 | v16 |
|---|---|---|---|
| Build config | setup.py | pyproject.toml | pyproject.toml |
| DocType extension | doc_events | doc_events | extend_doctype_class preferred |
| Python minimum | 3.10 | 3.10 | 3.11 |
| INI patches | ✅ | ✅ | ✅ |
| Fixtures format | JSON | JSON | JSON |
v16 Breaking Changes
extend_doctype_classhook: Cleaner DocType extension pattern- Data masking: Field-level privacy configuration available
- UUID naming: New naming rule option for DocTypes
- Chrome PDF: wkhtmltopdf deprecated for PDF generation
Critical Implementation Rules
✅ ALWAYS
- Start with
bench new-app- Never create structure manually - Define
__version__in__init__.py- Build will fail without it - Test patches on database copy - Never run untested patches on production
- Use batch processing - Any patch touching 1000+ records needs batching
- Filter fixtures - Never export all records of a DocType
- Version your patches - Use v1_0, v2_0 directories for organization
❌ NEVER
- Put frappe/erpnext in pyproject dependencies - They're not on PyPI
- Include transactional data in fixtures - Only configuration!
- Hardcode site-specific values - Use hooks or settings DocTypes
- Skip
frappe.db.commit()in large patches - Memory will explode - Delete fields without backup patch - Data loss is irreversible
- Modify core ERPNext files - Always use hooks or override patterns
Reference Files
| File | Contents |
|---|---|
references/decision-tree.md | Complete decision flowcharts |
references/workflows.md | Step-by-step implementation guides |
references/examples.md | Complete working examples |
references/anti-patterns.md | Common mistakes to avoid |
See Also
erpnext-syntax-customapp- Exact syntax referenceerpnext-syntax-hooks- Hooks configurationerpnext-impl-hooks- Hook implementation patternserpnext-database- Database operations for patches
Source
git clone https://github.com/OpenAEC-Foundation/ERPNext_Anthropic_Claude_Development_Skill_Package/blob/main/skills/source/impl/erpnext-impl-customapp/SKILL.mdView on GitHub Overview
This skill guides you through building and structuring Frappe/ERPNext custom apps. It covers app structure, module creation, doctype design, fixtures, patches, and deployment, with notes for v14/v15/v16 compatibility.
How This Skill Works
It uses decision-based workflows to determine whether you should build a completely new app, extend an existing ERPNext installation, or implement patches or fixtures. It maps decisions such as NEW APP WORKFLOW, EXTENSION DECISION, PATCH vs FIXTURE DECISION, FIXTURE WORKFLOW, and VERSION UPGRADE WORKFLOW to concrete actions like scaffolding, module and doctype creation, and deployment.
When to Use It
- Starting a completely new Frappe/ERPNext app using the NEW APP WORKFLOW
- Extending existing ERPNext functionality without a new app (EXTENSION DECISION)
- Migrating data or configuring fields via patches vs fixtures (PATCH vs FIXTURE DECISION)
- Exporting deployment-ready configuration using the FIXTURE WORKFLOW
- Upgrading an app to a newer Frappe version (VERSION UPGRADE WORKFLOW)
Quick Start
- Step 1: Decide path using NEW APP WORKFLOW, EXTENSION DECISION, or PATCH vs FIXTURE DECISION
- Step 2: Scaffold or modify your app with bench new-app or appropriate structure changes
- Step 3: Implement doctypes, fixtures, patches, test across v14/v15/v16, and deploy
Best Practices
- Plan app structure before coding including modules, doctypes, and fixtures
- Decide and document PATCH vs FIXTURE DECISION early in the project
- Use the FIXTURE WORKFLOW to export stable configurations for deployment
- Ensure compatibility notes for v14, v15, and v16 and track differences
- Test changes with bench and staging environments before production deployment
Example Use Cases
- NEW APP WORKFLOW example: building a brand new ERPNext module from scratch
- EXTENSION DECISION example: adding features to an existing ERPNext app without a new app
- PATCH vs FIXTURE DECISION example: choosing incremental patches vs exported fixtures
- FIXTURE WORKFLOW example: exporting and deploying configurations to production
- VERSION UPGRADE WORKFLOW example: upgrading an app to v16 and handling diffs