to select ↑↓ to navigate
Frappe Basics

Frappe Basics

  1. Frappe Framework is a full-stack, metadata-driven web framework written in Python and JavaScript.
  2. It was originally built to power ERPNext but is now a standalone, open-source product under the MIT license.
  3. “Frappe” means “to whip” in French, reflecting the framework’s goal of whipping up apps quickly.
  4. The framework follows a Model-View-Controller (MVC) pattern where DocTypes act as models.
  5. Every DocType automatically gets a REST API, role-based permissions, and an auto-generated UI.
  6. Metadata is stored in JSON files inside each app, enabling version control and easy migration.
  7. Bench is the official CLI tool used to create, manage, and deploy Frappe sites and apps.
  8. Sites are multi-tenant; one bench can serve many isolated sites with separate databases.
  9. Frappe uses MariaDB or PostgreSQL as the primary database and Redis for caching and job queuing.
  10. Background jobs are handled by the RQ (Redis Queue) worker system, keeping the UI responsive.
  11. Real-time features are powered by Socket.IO, giving instant updates without page reloads.
  12. The frontend layer is built on a lightweight JavaScript library called “Frappe JS” with minimal dependencies.
  13. Server-side code is written in Python 3, and client-side code is written in ES6+ JavaScript.
  14. Frappe enforces a strict naming convention: snake_case for Python, camelCase for JavaScript, kebab-case for files.
  15. DocTypes can be single (singleton) or child (table) types, giving flexibility for complex data models.
  16. The framework ships with a powerful report builder that can create tabular, pivot, or chart views without code.
  17. Role-based permissions are granular: module, doctype, field, and even record level via user permissions.
  18. Frappe supports server scripts—Python code stored in the database—allowing admins to customize logic without deployments.
  19. Customization is upgrade-safe: hooks and fixtures let you inject logic without modifying core files.
  20. Fixtures export customizations (custom fields, server scripts, etc.) into your app so they travel with git.
  21. Always keep custom code inside your own app, never inside the frappe or erpnext folders to avoid upgrade conflicts.
  22. Use hooks.py to register event handlers, scheduled jobs, API endpoints, and custom fields cleanly.
  23. Write unit tests using the built-in test runner (bench run-tests) and aim for >80 % coverage on critical flows.
  24. Use the ORM instead of raw SQL; it handles parameterization, caching, and permission checks automatically.
  25. Always access the database via frappe.db.sql or the Document API to leverage automatic caching.
  26. Use frappe.call to invoke whitelisted functions from the client side; it enforces CSRF and permission checks.
  27. Whitelist every remote callable method with @frappe.whitelist() and validate permissions inside it.
  28. Never trust user input; validate data on the server even if the client already validates it.
  29. Use frm.add_fetch to pull field values from linked documents instead of writing custom queries.
  30. Prefer Document hooks (before_insert, before_submit, etc.) over bulk database triggers for clarity.
  31. Keep background jobs idempotent; workers may retry failed jobs, so ensure duplicate runs are safe.
  32. Use enqueue with a timeout and queue name to isolate long-running tasks from quick ones.
  33. Cache expensive computations with frappe.cache() (Redis) and set TTLs to avoid stale data.
  34. Use Frappe’s built-in logging (frappe.logger) instead of print statements; it rotates logs automatically.
  35. Follow the existing API pagination pattern—start and page_length—to keep responses small and fast.
  36. Use the built-in import/export tool for master data; it supports CSV/Excel and validates against fieldtypes.
  37. Always create patches (patches.txt) for schema or data migrations instead of running raw SQL manually.
  38. Use bench backup before major upgrades; backups are compressed and include both files and the database.
  39. Keep JavaScript side code modular; place page-specific scripts in public/js and require them via asset bundles.
  40. Use Vue.js or React inside Page or Desk extensions, but mount them cleanly to avoid DOM conflicts.
  41. Avoid jQuery spaghetti; Frappe’s modern UI components (controls, dialogs, datatables) are self-contained.
  42. Write clear commit messages with the app prefix: “feat: add barcode widget to Item” for readability.
  43. Use pre-commit hooks (black, flake8, prettier) to enforce consistent Python and JavaScript style.
  44. Document your DocTypes with descriptive labels and help text; it auto-generates tooltips for users.
  45. Use the built-in translation system: wrap user strings with __() to make your app multilingual.
  46. Keep hard-coded values in site_config.json or Single DocTypes so admins can change them without code.
  47. Monitor worker health with bench doctor and set up alerts for queue backlogs to prevent job pile-ups.
  48. Use Frappe Cloud or Docker images for production; they bake in security hardening and automatic backups.
  49. Contribute reusable features back to the community via GitHub; follow the pull-request template and add tests.
  50. Mastering these best practices ensures your Frappe apps stay fast, secure, upgrade-safe, and enjoyable to maintain.
Last updated 2 weeks ago
Was this helpful?
Thanks!