Skip to main content
Frappe FrameworkERPNextImplementationBest Practices

Frappe ERPNext: extend it, do not edit it

The first time an ERPNext implementation hits a gap, editing core looks fast. It is also the fastest way to create long-term technical debt.

CoaleTech Engineering9 min read

The first time an ERPNext implementation hits a gap, the quick fix is tempting. Open the core file. Add the field. Change the validation. It works today. It is a liability tomorrow.

We have seen this many times. A Kenyan retailer needs a KRA eTIMS field on the sales invoice. A manufacturer needs a custom quality check on the stock entry. A SACCO needs extra KYC fields on the customer. The fastest path is to edit ERPNext directly. Six months later, the upgrade fails, the custom code conflicts with a new release, and the client is stuck on an old version.

Why core edits fail

ERPNext is open source. The code is yours to read and modify. But open source does not mean you should edit the product. Every change to core creates three problems.

  1. 01Upgrade risk. When ERPNext releases a security patch or a new version, your edited files conflict. Merging them is manual and error-prone.
  2. 02Support risk. A consultant who did not write the edit cannot maintain it. Knowledge walks out the door with the developer.
  3. 03Multi-site risk. If you run several companies on one bench, a core edit applies everywhere or requires branching, which multiplies the maintenance burden.

The alternative is to extend. Frappe Framework is designed for this.

Four extension patterns we use

1. Fixtures for custom fields and property setters

If you need a new field on an existing DocType, you add it through fixtures, not by editing the core JSON. Fixtures are version-controlled JSON files that migrate into the site on install. They add the field, set the property setter, and configure the layout. When ERPNext upgrades, the field stays because it is yours, not a modification of core.

2. doc_events hooks for business logic

If you need something to happen when a sales invoice is submitted, you register a function in hooks.py against the Sales Invoice submit event. Your code runs at the right moment without changing the invoice controller. We use this for eTIMS signing, fleet trip posting, and audit trail capture.

3. Custom apps for new domains

When the requirement is large enough to be a product, we build a custom Frappe app. It has its own DocTypes, reports, workspaces, and front ends. It installs on the same bench as ERPNext and talks to it through the API and hooks. Coale Finance, Mkaguzi, and Payroll Africa all follow this pattern. They are first-class applications, not core hacks.

4. Whitelisted APIs and scheduled jobs

Custom logic is exposed through whitelisted REST endpoints and scheduler events. This keeps the architecture clean: ERPNext handles transactions, the custom app handles the specialization, and the integration layer is explicit and testable.

When to configure, when to customize, when to build

Configure when ERPNext already has the feature and you only need to set it up. Custom fields, workflows, roles, and print formats usually fall here. Customize when the standard model needs predictable extensions that belong to your organization. Build when the requirement is a distinct business domain with its own lifecycle, users, and reporting needs.

The wrong choice is almost always at the extremes. Doing everything with custom fields turns ERPNext into a mess. Building a custom app for a single report is overkill. Editing core is almost never the right answer.

The long-term payoff

A well-extended ERPNext site upgrades cleanly. New developers can read the custom app and the fixtures and understand what was changed and why. Auditors can trace business rules to explicit hooks instead of hunting through modified core files. The client keeps the benefits of open source without owning the cost of a fork.

This is the discipline behind every CoaleTech implementation. We do not edit core. We extend it.

Planning an ERPNext implementation or stuck on an old version because of core edits? Talk to a CoaleTech solutions architect about a clean extension path.

Working on something like this?

We ship ERPNext and custom Frappe apps across Kenya, Uganda, Tanzania, Rwanda, Ethiopia, and Somalia. Let's talk through your build.