Open-source project
frappe/education avatar
frappe/education

Frappe Education, a school ERP that sits on top of ERPNext

Open source education / school management system

673 stars463 forksPythonNOASSERTION

At a glance

What is it?
Frappe Education is an open-source education and school management system that adds student records, admissions, fees, course scheduling and a student portal to an ERPNext installation. The hard part of adopting it is not the feature list but the dependency chain and the custom licence.
Who is it for?
Frappe Education is worth evaluating for a school that already runs ERPNext or Frappe, or that wants to try the module quickly through Docker Compose before committing to a host. It is the wrong choice for a single school that needs a simple fee ledger with no ERP underneath it, since the module cannot run without ERPNext and a compatible Frappe Framework branch.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository last received commits 8 days 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 October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A school ERP built as an ERPNext module, not a standalone product

Frappe Education does not run on its own. The project describes itself as a module based on ERPNext, which is the Frappe ecosystem's open-source ERP covering accounting, inventory, manufacturing and more. That single architectural decision explains most of what you will and will not find in the repository: there is no separate database schema, no separate authentication system and no separate deployment story, only Frappe doctypes, Frappe UI pages and ERPNext's underlying accounts and inventory machinery.

For the target user, a school or training institution, the problem being solved is fragmentation. The project's motivation section argues that available tools were scattered, too expensive or too complex, and that the goal is one tool that is affordable and customizable to the institution's needs. The feature list follows that logic: student and teacher profiles with attendance, admission management, fee structure and payment scheduling, course scheduling with course calendars, and a student portal where a student can read a timetable, check attendance, pay fees and see current and previous grades.

The fees and attendance parts are where the ERPNext inheritance shows most. A fee schedule in a school is a billing concept, and ERPNext already owns billing, so the module is extending an accounting model rather than inventing a parallel one. If your institution has an accountant and an ERP consultant already, that continuity is an argument for. If you are a small academy with a spreadsheet and no operations staff, the dependency chain below is a cost you have to price in.

The stack underneath: Python, Vue and a pinned Frappe version

The repository layout shows a standard Frappe app with three distinct areas: an education/ directory holding the Python application code, a frontend/ directory for the browser side, and a docker/ directory holding the container setup that the quickstart downloads. The Python package metadata in pyproject.toml names the distribution education, requires Python 3.10 or newer, and builds through flit_core. The frontend is a separate yarn project driven by the package.json scripts, where a postinstall hook runs a yarn install inside frontend, and dev and build scripts do the same for the development server and the production bundle.

The dependency that matters most is pinned in the same file, under the bench dependencies section.

toml
[tool.bench.frappe-dependencies]
frappe = ">=17.0.0-dev,<18.0.0"

Reading that alongside the compatibility matrix gives the real picture. The matrix maps the Education branch version-15.1 and version-15.2 to Frappe Framework version-15, version-16 to version-16, and the develop branch to the framework's develop branch. So the module tracks the framework's major release line, and installing the wrong combination is not a subtle bug but a version mismatch you resolve before starting. The 17.0.0-dev range in the packaging metadata is the bleeding-edge end of that ladder, which tells you the develop branch expects an unreleased framework version. Pick a tagged Education branch and a matching framework version for anything but experiments.

There is also a linter configuration worth knowing about, since it tells you what the maintainers treat as house style: ruff with a line length of 110, targeting Python 3.10, with a specific set of rules disabled. New contributions that ignore those settings will not merge cleanly, and the pre-commit configuration at the repository root means formatting is checked before review.

Docker Compose is the shortest path to a running site

The project documentation offers three routes, and the Docker route is the fastest way to see the module working before you think about domains and mail. You need Docker, docker-compose and git on your machine, then two downloads and one command. The first block creates a working directory and fetches the compose file and the setup script straight from the develop branch of the repository.

bash
    mkdir frappe-education
    cd frappe-education
    # Download the docker-compose file
    wget -O docker-compose.yml https://raw.githubusercontent.com/frappe/education/develop/docker/docker-compose.yml
    # Download the setup script
    wget -O init.sh https://raw.githubusercontent.com/frappe/education/develop/docker/init.sh

Those two URLs pin you to the develop branch, which is the unstable edge of the compatibility matrix. If you want a stable evaluation, download the same two files from the branch matching your framework version instead. Starting the stack is a single command.

bash
    docker compose up -d

Once the containers are up, the site is reachable at http://education.localhost:8000/ and the documentation lists the default credentials as Administrator with the password admin. Those defaults are fine for a local sandbox and nothing else, so treat any deployment that keeps them as misconfigured. The compose file downloads an init script alongside itself, which means the first startup performs database setup work; the first request can be slow while that finishes.

Local development goes through bench, and the order matters

For development the documented route is bench, and it is sequential: install bench and create a frappe-bench directory using the Frappe Framework installation steps, install ERPNext with bench get-app erpnext, then add this module with bench get-app education. ERPNext has to exist first because the education app expects its doctypes and accounting structure, and installing education alone in a fresh bench produces a site that cannot model fees.

After that, you create a site named education.test, map it to localhost with bench --site education.test add-to-hosts, and install the app on the site with the following command.

bash
   $ bench --site sitename install-app education

The documentation writes that command with sitename as a placeholder, so substitute your actual site name rather than copying it literally. The result is visible at two URLs. The desk interface sits at http://education.test:8000/education and the student-facing portal sits at http://education.test:8000/student-portal, and the documentation walks through both as the way to confirm the app is running.

That last check matters because the portal is a distinct surface from the back office. The portal is where students read timetables, review attendance, pay fees and look at grades, which means it is a separate audience with its own permission model and its own empty state to fill before it is useful. A school evaluating this module should load one course, one class and one student, then look at the portal through a student account, because a portal with no data in it tells you very little about whether the fee and attendance flows actually fit your process.

Production deploy goes through a script that names your site

The production path described in the documentation is Frappe Cloud, the managed hosting platform built on the open-source press project, which handles installation, setup, upgrades, monitoring, maintenance and support for Frappe deployments and can manage several deployments at once. If you would rather not operate it, that is a legitimate answer to the deployment question.

The self-hosting route is a two-step script. First you fetch the installer.

bash
wget https://frappe.io/easy-install.py

Then you run the deploy command with the parameters replaced by your own values.

bash
python3 ./easy-install.py deploy \
    --project=education_prod_setup \
    --email=your_email.example.com \
    --image=ghcr.io/frappe/education \
    --version=stable \
    --app=education \
    --sitename subdomain.domain.tld

Two parameters are placeholders the documentation calls out explicitly: your_email.example.com for the administrator address and subdomain.domain.tld for the domain the site will be served on. The image reference ghcr.io/frappe/education pulls a prebuilt container rather than building from the repository, and the --version=stable argument means you are deliberately opting out of the develop branch that the Docker quickstart used. The documentation states that the script produces a production-ready instance with the necessary configurations in about five minutes, which is a claim about the script's own runtime and not a measurement of anything else.

That contrast between the two routes is worth internalizing. The quickstart deliberately runs the unstable branch for convenience, and the production command deliberately pins stable. Copying the quickstart steps into production is how you end up serving the develop branch of a student records system.

The licence is the part GitHub cannot classify for you

The licence is a custom type that GitHub cannot classify, with the actual terms in the LICENSE file, and license.txt is present at the top level of the tree. Nothing in the documentation describes what those terms grant or restrict. That is unusual for a Frappe app, since most modules in the ecosystem ship under a recognizable open-source licence, and it means a procurement or legal review has to read license.txt directly before the code goes anywhere near an institution's data.

There is a second licence dimension that is easier to reason about. Frappe Framework itself, ERPNext and Frappe UI are separate open-source projects with their own terms, and the module depends on all three. Any redistribution or hosted offering has to respect each of those as well as the terms in license.txt. That is not a reason to avoid the project, but it is a reason to read all of them, because a module can be permissively licensed while the framework it plugs into carries conditions of its own.

For the record, the stated motivation for the project is affordability and customizability for educational institutions, and the source code, issue tracker and the public Telegram group referenced in the README are openly available. Openness of the code and clarity of the licence are two different things, and only the first is settled here.

Where the module stops and plain ERPNext starts

The realistic alternative is not a competing school system, it is ERPNext on its own. Because Frappe Education is a module on top of ERPNext rather than a replacement for it, an institution that already runs ERPNext for accounting and inventory can decide per feature whether the module earns its place. Fees, admissions and course calendars are education-specific and would mean custom development in plain ERPNext; student and teacher profiles with attendance overlap with ERPNext concepts enough that a smaller institution might model them directly with fewer moving parts.

The difference in approach is architectural rather than cosmetic. ERPNext gives you a general ledger, stock and manufacturing with the school concepts left to you. The module gives you education-shaped doctypes, a student portal and course calendars on top of that same ledger, and it inherits ERPNext's data model rather than replacing it. The trade-off runs in both directions: you gain workflows that took the maintainers real effort to build, and you take on a dependency chain of framework, ERP, frontend build and container image for a system whose installation is documented in four different ways.

A second boundary is simply scale and staffing. Nothing in the documentation addresses very small institutions, multi-campus organizations or regions with specific reporting requirements, so if your regulator expects particular fee disclosures or attendance records, verify those against the actual doctypes on a trial site rather than trusting the feature list. The fee and grade structures of ERPNext are configurable, but configurable is not the same as pre-validated for your country.

Release cadence, branches and what upgrading costs you

The project ships from a develop branch as the default, with tagged releases alongside it: v16.1.0 and v15.6.0 both dated 2026-06-29 in the recorded release list, and v16.0.1 from 2026-04-07. The last push to the repository was on 2026-10-15, so the code in the default branch is moving, and the releases themselves are spread across two major branches at once. That pairing is normal for Frappe apps, where a version-15 line keeps receiving fixes while version-16 is the current line.

The practical consequence is that the branch you choose determines your upgrade path. version-16 tracks Frappe Framework version-16, version-15 tracks version-15, and develop tracks the framework's own develop branch. Switching between major branches is a migration exercise, not a version bump, because the framework underneath changes underneath you.

For a hosted deployment the upgrade cost is largely handled by whoever runs the platform: Frappe Cloud takes care of installation, setup, upgrades, monitoring, maintenance and support as the documentation describes it. For self-hosted installs, the same work falls on your own team, and the container image referenced by ghcr.io/frappe/education with a --version=stable argument gives you a repeatable unit to pull rather than a build you maintain yourself. The scale of that work is not quantified anywhere in the documentation, so treat it as an open question for anyone running this outside a managed platform.

Editorial conclusion

Frappe Education is worth evaluating for a school that already runs ERPNext or Frappe, or that wants to try the module quickly through Docker Compose before committing to a host. It is the wrong choice for a single school that needs a simple fee ledger with no ERP underneath it, since the module cannot run without ERPNext and a compatible Frappe Framework branch. Verify three things first: that your intended Frappe Framework version matches the compatibility matrix row for the branch you install, that the license.txt terms in this repository are acceptable to your institution, and that the Docker Compose route on the develop branch gives you the site behaviour you expect before you point it at real student records.

Frequently asked questions

Do I need ERPNext to run Frappe Education?

Yes. The project describes itself as a module based on ERPNext, and the documented local setup installs ERPNext with bench get-app erpnext before adding the education app, so the accounting and inventory structures it builds on must be present.

How do I install Frappe Education with Docker?

Download docker-compose.yml and init.sh from the docker directory of the repository into a new folder, then run docker compose up -d. The site becomes available at http://education.localhost:8000/ with the default Administrator credentials listed in the documentation.

Which Frappe Framework version does the develop branch need?

The compatibility matrix maps the develop branch of the education app to the develop branch of Frappe Framework, and the packaging metadata pins frappe to a range of >=17.0.0-dev,<18.0.0. For a stable install, pick a tagged branch such as version-16 and the framework version-16 it maps to.

Can students pay fees themselves in Frappe Education?

Yes. The student portal described in the project documentation lets students check their timetable and attendance, pay fees online, and view current and previous grades, and the module also covers organizing the fee structure and scheduling payments.

What licence does Frappe Education use?

The licence is a custom type that GitHub cannot classify, and the terms are in the LICENSE file with a copy at license.txt in the repository root. The documentation does not summarize what those terms grant or restrict, so read that file directly before deploying.

Official sources

  1. frappe/education on GitHub
  2. Issues
  3. README
  4. Releases
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.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/frappe-education.svg)](https://hysenlabs.com/projects/frappe-education)

Was this useful?