← Back to blog
Architecture January 5, 2026 · 10 min

Frappe v16: the application framework hiding behind ERPNext

Most teams discover Frappe through ERPNext. The framework underneath is a full application platform that we use for custom business systems.

Frappe v16: The Application Framework Hiding Behind ERPNext

Most teams find Frappe because they're looking for ERPNext -- the open-source ERP that covers accounting, inventory, HR, CRM, manufacturing, and project management. ERPNext is a complete business system. But the framework it's built on, Frappe, is an application platform in its own right, and we've shipped more custom Frappe apps than ERPNext deployments.

The problem Frappe solves

Every business application needs the same scaffolding: data models, role-based permissions, REST APIs, background jobs, PDF generation, workflow engines, audit trails, and a web UI. Building these from scratch in Django or Rails takes 6-10 weeks before you write a single line of business logic.

Frappe gives you all of this out of the box. You define a DocType (Frappe's data model abstraction), and you get a CRUD API, a form UI, permissions, versioning, and an audit log -- automatically. We built a clinic management system in 3 weeks on Frappe that would have taken 3 months on Django. Not because Django is worse, but because Frappe's batteries are already wired in.

What Frappe v16 gives you

Frappe v16 shipped with significant improvements over v15. Here's what matters in production:

  • DocType system -- Define your data model in JSON or through the UI. Every DocType automatically gets REST and RPC APIs, role-based access control, and full-text search. No boilerplate.
  • Permissions baked into the ORM -- frappe.get_list("Patient", filters={"department": "Oncology"}) respects the logged-in user's role permissions automatically. You never write permission checks manually.
  • Background jobs via Redis + RQ -- frappe.enqueue() drops a function call into a Redis-backed queue. Workers pick it up. Retries, timeouts, and failure handling are built in.
  • Workflow engine -- State machines for document lifecycles. A purchase order goes from Draft to Approved to Ordered to Received, with role-gated transitions and automatic email notifications at each step.
  • Print formats and PDF generation -- Jinja2 templates rendered to PDF via wkhtmltopdf. Invoices, prescriptions, reports -- all templated, all versioned.
  • Real-time via WebSockets -- Document changes push to connected clients. When a nurse updates a patient record, the doctor's screen updates without a refresh.
  • bench CLI -- The deployment tool. bench init creates a new environment. bench get-app pulls in Frappe apps. bench new-site provisions a site with MariaDB, Redis, and Nginx config. One tool manages the full lifecycle.

Frappe vs ERPNext: the distinction

ERPNext is a Frappe app -- the largest and most well-known one. It's a full ERP system that covers accounting, inventory, HR, payroll, CRM, manufacturing, asset management, and project management. If you need an ERP, ERPNext is one of the best open-source options available.

But not every project needs an ERP. When a client needs a patient scheduling system, a custom asset tracker, or an internal approval workflow, we build a custom Frappe app -- not an ERPNext customization. The framework is the value, not the ERP.

# A custom Frappe app: 4 lines to create a full CRUD API
# Define the DocType in JSON, then add business logic:

@frappe.whitelist()
def assign_bed(patient: str, ward: str, bed: str):
    """Assign a bed and update ward availability."""
    bed_doc = frappe.get_doc("Hospital Bed", bed)
    bed_doc.patient = patient
    bed_doc.status = "Occupied"
    bed_doc.save()
    frappe.publish_realtime("bed_assigned", {"ward": ward, "bed": bed})

That function is a full API endpoint -- authenticated, permission-checked, and audit-logged by default. The publish_realtime call pushes the update to every connected client watching the ward dashboard.

In production

We've deployed Frappe-based systems for healthcare (clinic management, patient scheduling), logistics (fleet tracking, delivery workflows), and internal tooling (approval chains, document management). Patterns we've learned:

  • One site per client, multiple apps per site. Frappe's multi-app architecture lets us compose systems from reusable modules. Our healthcare base app provides patient and provider DocTypes; client-specific apps extend them.
  • Custom scripts over core patches. Frappe's hook system (doc_events, override_whitelisted_methods) lets you modify behavior without touching framework code. We've maintained zero-fork deployments for 18+ months.
  • MariaDB, not PostgreSQL. Frappe's ORM is optimized for MariaDB. We've tested PostgreSQL support and it works, but MariaDB is the battle-tested path for production.
  • bench manages everything. Deployments, migrations, backups, domain setup, Let's Encrypt certificates. One CLI for the entire lifecycle. A junior engineer can deploy a production Frappe site in an afternoon with our SOPs.

The tradeoffs

Frappe is opinionated, and those opinions have costs:

  • The built-in web UI is functional, not modern. For internal tools and back-office systems, it's fine. For customer-facing products, we build separate frontends in SvelteKit or React that consume Frappe's API.
  • Learning curve. The DocType system, hook architecture, and bench CLI are Frappe-specific knowledge. Budget 2-3 weeks for a developer to become productive.
  • Scaling ceiling. Frappe handles 80-120 concurrent users per site comfortably. Beyond that, you need Gunicorn worker tuning, Redis cluster config, and potentially read replicas. We've scaled to ~300 concurrent users, but it required deliberate architecture work.
  • MariaDB coupling. The framework assumes MariaDB in subtle ways. If your org is standardized on PostgreSQL, there will be friction.

Our recommendation

If you're building a business application that needs role-based permissions, audit trails, workflow engines, and background jobs -- and you don't want to build that scaffolding yourself -- Frappe v16 is the fastest path to production we've found. Use ERPNext when you need a full ERP. Use a custom Frappe app when you need the framework without the ERP baggage.

The entire stack is open source, runs on your infrastructure, and can be maintained by your team with bench and standard Linux administration. We set it up, write the SOPs, and hand over the keys.

CommitX Technology (OPC) Pvt Ltd
© 2025 — Built with open-source tools, obviously.