When no-code ERPNext extensions with Frappe packages fit your roadmap
Choose no-code ERPNext extensions when several sites or teams need the same additions and you want to avoid forking ERPNext. The typical situation is a group of companies or business units that each run their own ERPNext site and all need the same custom DocTypes, a set of client scripts, a shared print format or a few workflow helpers. Built by hand on each site, these drift apart within months. Built once and shipped as a package, they can be installed and updated from a single source. A no-code extension covers the components a System Manager can create in the desk UI: custom DocTypes, Server Scripts and Client Scripts, and Pages. These sit in a custom module and are exported so they can travel with the package.
The package itself needs more than the components. Before you ship anything to another site, confirm three things: the package has a README that states what it adds, which ERPNext and Frappe versions it was tested against, and how it is installed and removed. Decide the license in writing before the first external copy goes out. ERPNext and the Frappe Framework are licensed under GPL-3.0 and MIT respectively, so ask your counsel which license your package will carry and whether it can be redistributed to the sites you have in mind. Server Scripts also carry a platform constraint: since version 15 they are disabled by default and need the server_script_enabled setting, and Frappe Cloud public shared benches do not allow them. Check that every target site can enable them before you design around them.
Plan to graduate to a full custom app when the logic outgrows the UI. Signals include Python that is too large or too complex to keep in a Server Script, the need for hooks that override ERPNext controllers, tests that must run in version control, or reports and background jobs that need proper code review. At that point the work moves into the custom app process described on the sibling page. Ask your team to estimate how many scripts they expect to maintain across sites, and to confirm with their Frappe partner or in their own test environment whether the package behaves the same after each ERPNext minor release.
Which packaging approach fits which situation
When one ERPNext site is the only target, a no-code package is often the lightest option. DocTypes, client scripts, custom fields and print formats can be built in the UI, and the team keeps working in the same bench it already operates. The main risk is that the extension lives only in that database, so nothing is reproducible if the site is rebuilt or the team changes.
- Build location: Changes are made directly in the site's Desk, which is quick to iterate but hard to review.
- Recovery: A rebuilt site will not carry the changes unless they were exported first.
- Server logic: Server scripts must be enabled with
server_script_enabledon version 15 and later, which is a site-level decision. - Upgrades: Test each ERPNext minor and major release against the extension on a copy of the site before applying it.
- Ownership: Name who may change the site, since the UI makes edits easy to make without review.
Confirm with your own team whether the site will ever need a second copy, because that answer decides whether export discipline is worth setting up now.
When one organization runs several sites, such as separate companies, regions or test and production copies, the cost of hand-editing each site grows quickly. A package that is exported and installed on each site keeps behaviour consistent. The trade-off is that every site must run compatible ERPNext and package versions, and each one needs its own upgrade test.
- Consistency: One exported package gives every site the same DocTypes, scripts and print formats.
- Environments: Build in a development site, export, then install on staging and production.
- Drift: Check that no site has local edits that the package will overwrite on migrate.
- Versioning: Keep the package in git so each release can be traced to a site state.
- Multi-company behaviour: Test any logic that depends on company defaults on each site separately.
Ask the implementation team to show how a change moves from the development site to production, and who approves it at each step.
When the package is sold or given to other organizations, it stops being a local convenience and becomes a product. Each recipient runs its own site, versions and data, so the package needs a README, a license decision, install instructions and a clear list of what it changes. Where the logic is significant, a custom app is usually the more maintainable shipping format.
- Documentation: Describe every DocType, script and field the package adds, along with its dependencies.
- License: Choose and state a license for the package. ERPNext itself is licensed under GPL-3.0 and the Frappe Framework under MIT, so confirm with counsel how those terms apply to your code.
- Support boundary: Define which versions you support and what happens on upgrades.
- Server logic: Plan for recipients who may not enable server scripts, which pushes logic toward an app.
- Upgrades: Each recipient's upgrade becomes a support question, so test against the supported ERPNext versions listed by Frappe.
Confirm who will maintain the package after release, because support obligations usually last longer than the initial build.
Frappe Cloud public shared benches do not allow Server Scripts, and the framework disables them by default from version 15 unless the setting is enabled. A site on that kind of bench therefore cannot rely on server-side Python defined in the UI. Logic that needs document events, validation or API endpoints must move into a custom app or be removed from the design.
- Server scripts: Assume they are unavailable on public shared benches and confirm with the hosting provider.
- Client scripts and custom fields: These run in the browser or in the database definition, so they remain available for form-level behaviour.
- Custom apps: Logic that must run on the server needs a deployment route the hosting plan allows, which may mean a dedicated or private bench.
- Hosting plan: Check which bench type the plan provides before designing around any server-side feature.
- Migration path: Plan how logic moves if the site later changes hosting.
Before you commit to a design, ask the hosting provider in writing which server-side features the chosen plan permits.
Configuration options and when each fits
This table compares the five ways to package ERPNext changes for other sites, from UI-only DocTypes to a full custom app. Read each row as a question: what the option covers, whether your change fits it, and what you give up by choosing it. The main takeaway is that the more the change depends on Python or on shipping through git, the sooner you should move it out of the UI and into an app.
| Option | What it covers | When it fits | Trade-offs and what to confirm |
|---|---|---|---|
| UI-only DocTypes and pages | Custom DocTypes, fields and pages built in the desk UI and exported as a custom module | Small, self-contained tools where a user-facing form or list is enough | Lives in the database until exported. Confirm the export includes every dependent record and permission. |
| Client scripts | Browser-side JavaScript on form events, such as field filters and custom buttons | Form behaviour that needs no server-side data changes | Runs in the browser, so it is not a security control. Confirm behaviour across the browsers your users run. |
| Server scripts | Python on document events or as API endpoints in a restricted environment | Simple document logic that must run on the server | Since version 15 disabled by default, enabled with server_script_enabled. Frappe Cloud public shared benches do not allow them. Confirm the restricted environment covers your calls. |
| Export and packaging into a custom module | Exporting customizations and shipping them with a custom module across sites | Reusing the same configuration on several sites under version control | Export can overwrite target-site changes on migrate. Confirm which records are exported and how conflicts are handled. |
| Graduation to a full custom app | Scaffolded app with Python code, hooks, tests and its own release cycle | Logic needs server code, overrides, background jobs or formal testing | Requires a development workflow, code review and upgrade testing with each ERPNext release. Confirm who maintains it after handover. |
How to build and package a no-code extension step by step
This sequence takes a no-code ERPNext extension from a version check on a development site to a tested package that installs cleanly on another site. Each step closes with a check, so the package reaches a second site only after it has passed review.
Confirm the ERPNext version and hosting target
Before building anything, record the ERPNext and Frappe version the target sites run and confirm they are on a listed, supported release. Check the supported versions page to see the end-of-life dates for each major version, and note the hosting model (Frappe Cloud, Docker Compose or bench). Frappe Cloud public shared benches do not allow server scripts, so confirm that before you design anything that depends on them. Done when the version, hosting model and script policy are written down for both the development and target sites.
Build DocTypes and scripts on a development site
Create the custom DocTypes, fields, client scripts and server scripts on a dedicated development site, not on a production site. Keep each change small and named clearly, and record which features depend on server scripts being enabled through the server_script_enabled setting. Your ERP administrator or a developer with Frappe experience should do this work. Done when the extension behaves as specified on a test record and the list of all customizations matches the design notes.
Export and organize the custom module
Create a module for the extension, assign the DocTypes and scripts to it, and export the customizations so they are stored as files rather than only in the database. Review the exported folder and confirm it contains every DocTypes, script and custom field you built, and nothing from unrelated test data. Check the module name and folder layout against the Frappe documentation for your version. Done when a developer who did not build the extension can read the exported files and identify each component.
Write the README and choose a license
Write a README that states what the package does, which ERPNext and Frappe versions it was tested on, which settings it requires (for example, server scripts enabled), how to install it, and how to remove it. Choose a license deliberately and record it in the package metadata. ERPNext itself is GPL-3.0 and the Frappe Framework is MIT, so consult your legal or compliance team about how the chosen license interacts with the code you ship. Done when the README and license file are committed and a reviewer can answer the install questions without asking the author.
Test install on a clean site
Create a fresh site on the same ERPNext version as the target, install the package from the exported files and run through the scenarios in your test notes. Confirm that every DocType, field and script appears and that no dependency on the development site is missing. Record any errors and fix them in the source files, not on the clean site. Done when the fresh install passes all test cases and the test log is saved with the package.
Run migrate and confirm the result
Run the migrate command on the clean site after installing, and on a copy of an existing site that already has the package, to confirm that custom fields and scripts sync without overwriting data. Review the migration output for errors and check the affected forms, reports and records afterward. Note any customization that a later migrate could overwrite and document it in the README. Done when migrate completes without errors on both sites and the checked records are unchanged.
Decide whether to graduate to a full app
Compare the package against the limits of no-code work: complex server logic, custom controllers, background jobs, tests under version control or code shared across many sites. If any of these now apply, plan the move to a custom Frappe app with version control and deployment steps, and keep the no-code package as the reference specification. If none apply, keep the package as is and record the review date. Done when the decision and its reasons are recorded in the project notes.
Security and operational risks of shipping UI-built logic
Logic built in the UI lives in the database and runs with the permissions of whoever can edit it, so it carries risks that a reviewed code repository would normally catch. The cards below cover who can change that logic, what the runtime allows, what a package carries with it, and what happens when ERPNext upgrades underneath it.
Who can edit scripts in production
Script editing is a privileged action, because a server script or client script changes how documents save and what data users see. On a live site, the people who can open the Server Script or Client Script DocTypes are effectively code authors. Before you ship a package, confirm which roles hold rights to those DocTypes on each target site, and whether production edits are allowed at all. Many teams build on a staging site and move the result through a reviewed export.
Server script enablement and sandbox limits
Since version 15, server scripts are disabled by default and must be turned on with the server_script_enabled setting. Enabling it on a self-hosted site is a deliberate decision that should be recorded and owned. The sandbox restricts what Python can import and do, so confirm that the logic you built runs inside it. Logic that needs external libraries, file system access or network calls usually belongs in a custom app instead.
Permission setup shipped with the package
A package that adds DocTypes often ships without the role permissions that control them, so the receiving site either blocks users or opens data too widely. Export the permission rows along with the DocTypes and test them with a user from each role. Check that new DocTypes do not expose data through existing reports, list views or linked fields. Document which roles the package expects so the receiving administrator can map them to local roles.
Secrets and credentials not included in exports
Integration settings often hold API keys, tokens and passwords entered through the UI. Those values are stored in the database, not in the code, so a package exported from one site should not contain them, and the receiving site must supply its own. Check every exported Single or settings record for stored credentials before you publish. Document each secret the package needs, where it is entered, and who is responsible for rotating it.
Upgrade behavior across ERPNext versions
UI-built logic is tied to the ERPNext and Frappe version it was written against. Field names, standard hooks and form events can change in a minor or major release, and a script that worked last quarter may fail silently after an update. Pin the version you tested, keep a test list for each package, and rerun it before every upgrade. Confirm the support status of your target version first, since Frappe's supported versions page sets the end-of-life dates.
Review of code before install on other sites
A package installed on another site runs with that site's data and permissions, so it deserves the same review as any third-party code. Read every script, custom DocType and print format before installation, looking for outbound calls, broad permission grants and logic that touches sensitive fields. Confirm the license in the package README, since ERPNext is GPL-3.0 and that affects how you may share changes. Keep a record of who approved each version installed.
Questions teams ask before building an ERPNext package
What does it cost to build a no-code ERPNext package?
Cost depends on how many DocTypes, scripts, pages and print or report pieces the package contains, how many sites it must run on, and how much testing and documentation you need before release. The work is paid as a fixed-scope engagement or internal staff time. One-time costs include design, build, testing and packaging. Recurring costs include reviewing the package at each ERPNext minor release and any retainer for support. Ask any partner for a quote that lists each deliverable, the sites in scope, the test cases, and whether upgrade checks are included. Hosting costs are separate: the ERPNext pricing page lists self-hosting as free, and Frappe Cloud shared site hosting starts at 5 US dollars per month.
How long does it take to build and test a package?
It depends on scope. A package with a few custom fields, one client script and a print format is a very different job from one with several linked DocTypes, server logic and a custom page. Testing time grows with the number of roles, permissions and sites the package must support. Plan time for requirements, build, a test pass on a staging site that matches production, a documented install and a rollback path. Ask for a timeline tied to a written scope, with the review points and the acceptance criteria listed in advance.
Can our internal team build an ERPNext package without outside help?
Yes, if the team has a developer who knows ERPNext data models, roles and permissions, and someone who can run a staging site. Most of the risk sits in the details: permission rules that leak data across roles, scripts that run during migrations, and customizations that get overwritten on upgrade. Teams that build in-house usually document each object, keep the package in version control and test every ERPNext upgrade on a copy of production before rolling it out. If those habits are not in place, a short external review of the design is often more useful than a full build.
What does the work need from our side?
You need to provide a written description of the business process, the roles and approval steps, sample documents and the fields each user group needs. You also need staging access, a test dataset that does not expose live personal data, and a named owner who can approve design decisions and sign off on tests. Confirm with your environment owner who can install packages on each site, and whether your change process requires a separate review before a package reaches production.
When should a package become a custom Frappe app?
Move to a custom app when the logic needs Python modules, hooks into ERPNext events, custom APIs, scheduled jobs, or code that must be versioned and tested like software. Server Scripts are one signal to watch. According to the Frappe documentation, starting from version 15 they are disabled by default and must be enabled with the server_script_enabled setting, and Frappe Cloud public shared benches do not allow them. If the package must run on those hosts, plan for a custom app from the start. Your engineers should also check whether the Frappe support versions policy, which lists the supported ERPNext and Frappe Framework versions, covers the version you target.
Does a Frappe support contract change the answer?
It can. According to Frappe's supported versions policy, customers must be on a listed version and subscribed to a matching Frappe Cloud support plan to receive warranty coverage from Frappe. A package built on an unsupported version, or on a site without that plan, will not carry Frappe warranty coverage for issues in the package or the platform. Confirm the current policy and your eligibility on the Frappe support versions page before you choose a version, and ask any implementation partner how they handle upgrades and fixes after go-live.
What breaks most often in packages after an ERPNext upgrade?
Customizations that depend on field names, script behavior or report layouts that changed in the new release are the most common issues. Packages that were exported without a clear ownership model can also overwrite changes made in production. Before each ERPNext minor upgrade, run the package on a staging copy of production, review the release notes for the version in use, and check permissions and print formats. Keep a rollback plan and a record of which package version is installed on each site.
When a no-code package should graduate to a full Frappe app
A package should graduate to a full Frappe app when its logic outgrows what the UI can express and what the restricted environment will run. The first signal is Python logic that needs libraries, long-running processing, or access to code paths that a Server Script cannot reach. Server Scripts run inside a restricted environment, and since version 15 they are disabled by default and must be enabled with the server_script_enabled setting. If your package depends on that setting being on, or if a site that hosts it is a Frappe Cloud public shared bench, where Server Scripts are not allowed, the package cannot run as a pure no-code bundle. Check this against every target site before you promise the package to anyone.
The second signal is a need to change ERPNext behavior itself. Overriding standard controllers, adjusting how a stock document validates, or extending an ERPNext workflow through hooks requires code that lives in an app, not in a DocType definition. Hooks are the supported way to extend ERPNext without forking it, and they belong in a repository that someone can review, test and pin to a version. The third signal is governance: if the package needs change history, code review, branch-based testing, or a release process tied to ERPNext minor releases, which ship frequently on both supported majors, keeping it as exported JSON in a shared site becomes hard to control. Plan for those reviews before the package grows, not after it breaks a client site.
The fourth signal is deployment. A full app is installed through bench, so it must be added to the bench, installed on each site, and migrated along with ERPNext. Confirm with your platform team how they build and deploy images, whether you run bench on Linux or use the Docker-based setup described in the frappe_docker repository, and who approves each change. The graduation decision is practical: if you cannot name who reviews the code, who runs the migration on each site, and which ERPNext version it is tested against, the package is not ready to stay no-code.
How DeployOpen scopes and delivers ERPNext extensions
DeployOpen approaches no-code ERPNext extensions as a written, fixed-scope piece of work: we agree what the package will add, build it on a staging site, and hand over the package with its documentation. The same discipline applies whether the package stays inside your organization or is shared with other ERPNext sites.
How we scope
- We list each DocType, script, page and report the package will add, and which sites it must install on.
- We confirm the ERPNext and Frappe version the package targets, and check it against the supported versions list before work starts.
- We record in writing whether server scripts are allowed on the target sites, since they are disabled by default from version 15.
How we build
- We build the extension in a development bench so custom fields, scripts and pages are exported into a module rather than left in the database.
- We test each DocType and script against roles and permissions that match your real users before the package is considered ready.
- We check that the package installs cleanly on a fresh site and that a migrate run leaves existing data and forms intact.
How we hand over
- You receive the package source, a README describing purpose, dependencies and install steps, and the license file you select.
- We document which items are no-code and which would need a full custom app, so your team knows when a change must move to code.
- We walk your administrators through installing, updating and removing the package on a staging site before production use.
How we support
- Ongoing support, upgrades and testing for the package are available as a retainer, scoped separately from the build.
- When ERPNext or Frappe releases a new minor version, we can review the package against it and plan the fixes it needs.
- Before any version upgrade, we recommend confirming with your team which features depend on the package and retesting them.

