ERPNext's setup has three edges: a Frappe 17 dev pin, a Python 3.14 floor, and a demo built to be discarded
Free and Open Source Enterprise Resource Planning (ERP)
At a glance
- What is it?
- ERPNext is a GPL-3.0 ERP written in Python that covers accounting, order management, manufacturing, assets, and projects on top of the Frappe Framework. The business coverage is broad; the install story is where the friction sits, with a framework dependency that starts at a development build, a Python 3.14 minimum, a one-command demo that is explicitly throwaway, and a bench script that leaves three plaintext passwords in your home directory.
- Who is it for?
- Choose ERPNext if your team can run Python 3.14 or newer and can accept a framework dependency whose lower bound is a dev build, and size the evaluation knowing the one-command Docker path cannot host custom apps.
- Can I use it commercially?
- Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The bench dependency range starts at 17.0.0-dev, not a finished release
The project metadata declares the framework as `frappe = ">=17.0.0-dev,<18.0.0"`. The lower bound is a development build, so a site provisioned against a stable, finished Frappe release does not satisfy the range. That one line decides how much of the stack you control. The documented manual route goes through bench, and bench resolves the framework against this range, so a mismatch shows up as a failed install rather than a runtime warning. What this configuration cannot offer is a known-good pair of versions, because the lower end of the range is by definition unreleased. The consequence for a reader planning a deployment is that you are committing to a framework version that keeps moving. Pin the exact commit you test against, and repeat the test whenever the framework side advances, since a framework update can change behavior underneath a pinned ERPNext with no ERPNext release to signal it.
Python 3.14 in the metadata, py310 in the linter
Two version numbers in pyproject.toml disagree. The project block sets `requires-python = ">=3.14"`, so any interpreter older than 3.14 cannot install the app, which narrows the set of machines and container base images you can deploy on. The Ruff section sets `target-version = "py310"` with a line-length of 110. What that buys you is a linter that stays quiet about rules and syntax introduced after 3.10, even though the package refuses to run below 3.14. The consequence is narrow but real: a clean lint run says nothing about the interpreter the package actually demands, and the gap is the kind that surfaces when a new Python release lands and the lint target is still several versions behind. If you pin images, pin 3.14 or newer, and do not read a passing Ruff run as coverage of that version.
Plaid, Google Maps, and python-youtube are mandatory installs, not extras
The core dependency list is flat, with no optional groups. It includes `plaid-python~=7.2.1` and `mt-940>=4.26.0` for bank statement work, `googlemaps~=4.10.0`, `python-youtube~=0.9.9`, `holidays~=0.87`, `rapidfuzz~=3.14.3`, `barcodenumber~=0.5.0`, `Unidecode~=1.4.0`, `pypng`, and `pdfplumber>=0.11.0`. The comments explain two of them: pypng is listed as not used directly and pulled in by PyQRCode for PNG generation, and pdfplumber is described as pure-Python wheels with no system binaries required. Because these sit in the main dependency array rather than an extras table, every install pulls them in whether or not you touch banking or maps. What the file cannot tell you is which feature calls python-youtube. If you are auditing dependencies for a locked-down environment, the answer is not in the manifest, and the practical cost is a wider supply chain and a larger image than a module-by-module install would give you.
The one-command demo logs you in as admin on port 8080 and tells you to bin it
The shortest path clones Frappe Docker rather than ERPNext itself, then starts a single compose file:
git clone https://github.com/frappe/frappe_docker
cd frappe_dockerdocker compose -f pwd.yml up -dSite creation takes a couple of minutes, and the instructions say to watch the `create-site` container logs before opening port `8080`, where the credentials are `Administrator` and `admin`. The prerequisites are only Docker, Docker Compose v2, and git. What this setup cannot do is stated plainly in the quick start: it is a disposable demo, intended for quick evaluation, you are told to expect to throw the environment away, and you will not be able to install custom apps to it. The consequence is that whatever you meant to prove stays unproven, whether that is a custom app, a production configuration, or a real upgrade. Treat port 8080 as a preview of the interface, then read the Docker documentation for a deployment you intend to keep. ARM hosts have their own setup page.
The manual installer leaves three plaintext passwords in your home directory
The manual route hands the heavy lifting to the bench install script, which installs all dependencies including MariaDB. It generates new passwords for three principals: the ERPNext `Administrator` user, the MariaDB root user, and the Frappe user. The script displays those passwords and also saves them to `~/frappe_passwords.txt`, so the database root password lands on disk in readable form, alongside an application password and a framework password. That is the mechanism, and the consequence follows directly: any process, backup, or misconfigured share that can read your home directory now holds the database root credential. Change the values after setup and remove the file rather than leaving it as a record. Set that beside the demo defaults of `admin` and `admin` on port `8080` and the lesson is about defaults: neither credential set is meant to survive a real deployment.
The JavaScript side is a nested banking subproject with an empty devDependencies
package.json keeps the JavaScript surface small. It declares a single runtime dependency, `onscan.js` at `^1.5.2`, and its `devDependencies` object is empty, so no JavaScript tooling versions are pinned there. Every script delegates into a nested project: `postinstall`, `dev`, and `build` each change into the `banking` directory first, and the test script runs Node's built-in test runner over a glob of `.test.mjs` files. The asset mapping in pyproject.toml points the build directory at `./banking`, sends output to `../erpnext/public/banking`, and names `../erpnext/www/banking.html` as the index page. A `yarn.lock` file sits at the root, so the folder and its hooks exist. What you cannot get from this repository is a self-contained JavaScript toolchain, and installing the app triggers a nested `yarn install` inside `banking` before anything else runs.
Two release lines, a develop default branch, and a wall of review bots
The repository is not archived and was last pushed on 2026-09-29, so it is actively maintained. Versions v16.37.0 and v15.121.6 were both published on 2026-09-30, and v16.36.1 on 2026-09-28, which means a 15 line and a 16 line ship side by side. The default branch is `develop`, so the branch you clone is the integration branch rather than a release tag. Around it sit the review gates: `CODEOWNERS`, a pre-commit config, Flake8 and ESLint configs, a `semgrep/` directory with its own `semgrepignore`, a `codecov.yml`, a `commitlint.config.js`, and bot configs for `.coderabbit.yml`, `.greptile`, `.mergify.yml`, and `sider.yml`. Translations run through `crowdin.yml` with `babel_extractors.csv` in the root. For a reader weighing this project, the practical point is that changes arrive continuously rather than in occasional curated drops, so pick a release line and stay on it.
Editorial conclusion
Choose ERPNext if your team can run Python 3.14 or newer and can accept a framework dependency whose lower bound is a dev build, and size the evaluation knowing the one-command Docker path cannot host custom apps. Before committing, read the Frappe Docker FAQ for the deployment you actually want, decide how you will handle the credentials the bench install script writes into your home directory, and pick either the 15 or the 16 release line to track rather than drifting with the develop branch.
Frequently asked questions
What is ERPNext used for?
It is an open source ERP under GPL-3.0 that covers accounting, order management, manufacturing, asset management, and projects inside one system, with a REST API and database abstraction layer from the Frappe Framework underneath.
Is ERPNext really free?
The code is GPL-3.0, and self-hosting needs only Docker, Docker Compose v2, and git. The documentation does not state what Frappe Cloud charges, and a manual install also pulls in MariaDB, so infrastructure and setup effort are yours to cover.
how to install erpnext
There are two documented routes. For a disposable demo, clone Frappe Docker and run `docker compose -f pwd.yml up -d`. For a local site, use the bench install script, then `bench get-app https://github.com/frappe/erpnext` followed by `bench --site erpnext.localhost install-app erpnext`.
how to start erpnext
After setting up bench, run `bench start`, then in a second terminal create a site with `bench new-site erpnext.localhost`, and open `http://erpnext.localhost:8000/app` in the browser.
how to access erpnext database
The documentation gives no direct database login for users. The manual bench install creates a MariaDB root user and saves that password to `~/frappe_passwords.txt`, and the layer above it is the Frappe Framework's database abstraction with a REST API.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/frappe-erpnext)