Unlocking HR Power: A Software Engineer's Take on Frappe/HRMS


Unlocking HR Power: A Software Engineer's Take on Frappe/HRMS

frappe/hrms

2025-07-24

Frappe/HRMS is an open-source Human Resources and Payroll management system built on the Frappe Framework. If you're not familiar, the Frappe Framework is a full-stack web framework written in Python and JavaScript (client-side). It's the same framework that powers ERPNext, a very popular open-source ERP system. This means Frappe/HRMS inherits all the benefits of the Frappe ecosystem.

It's designed to handle a wide range of HR functions, including

Employee Management
Keeping track of employee details, hierarchy, and roles.

Leave Management
Handling leave applications, approvals, and balances.

Attendance Management
Recording and tracking employee attendance.

Payroll
Processing salaries, deductions, and generating pay slips.

Recruitment
Managing job applications and hiring processes.

Performance Management
Setting goals and evaluating performance.

And much more!

As a software engineer, Frappe/HRMS offers a lot more than just a ready-to-use HR system. Here's how it can be incredibly beneficial

Since it's built on the Frappe Framework, Frappe/HRMS is highly extensible. You can

Add Custom Fields
Easily add new data fields to existing documents (like Employee, Leave Application, etc.) without writing complex code.

Create Custom DocTypes
Develop entirely new modules or "DocTypes" (Frappe's term for database tables/objects) to cater to unique business requirements.

Write Custom Scripts
Implement custom logic using Python (server-side) and JavaScript (client-side) to automate workflows, validate data, or integrate with other systems. This is where your engineering skills really shine!

Customize Workflows
Define custom approval flows for various HR processes (e.g., leave approval, expense claims).

This means you're not just deploying an off-the-shelf product; you're getting a robust foundation that you can tailor precisely to your organization's needs, or even for clients if you're a consultant.

If you're looking to deepen your Python and JavaScript skills, or learn a new full-stack framework, Frappe/HRMS (and the underlying Frappe Framework) is an excellent playground. You'll gain practical experience in

Model-View-Controller (MVC) or Model-View-ViewModel (MVVM) architecture
Frappe follows a similar pattern, making it easy to understand how data, UI, and business logic are separated.

Database Interactions
Frappe abstracts much of the SQL, allowing you to focus on business logic using its ORM-like features.

Client-side Scripting
Enhancing user experience and adding dynamic behavior with JavaScript.

API Development/Consumption
Frappe provides powerful REST APIs that you can use to integrate with other systems or build mobile apps.

Being open-source, Frappe/HRMS (and Frappe) has an active community. You can

Contribute Code
Fix bugs, add new features, or improve existing ones. This is a fantastic way to build your portfolio and contribute to a widely used project.

Learn from Others
Explore the codebase, understand best practices, and learn from how other developers have solved problems.

Get Support
If you get stuck, the community forums and documentation are great resources.

Because it's open-source and provides APIs, you can easily integrate Frappe/HRMS with other systems in your tech stack. Think about

Accounting Software
Syncing payroll data with your accounting system.

Time Tracking Tools
Importing attendance data from external time trackers.

Applicant Tracking Systems (ATS)
Streamlining recruitment by connecting with external ATS.

Single Sign-On (SSO)
Integrating with your existing authentication systems (e.g., LDAP, OAuth).

This is particularly valuable if your organization already uses other specialized software.

Getting Frappe/HRMS up and running usually involves installing the Frappe Bench, which is a command-line utility for managing Frappe sites.

Here's a simplified overview of the installation process (assuming a Linux-like environment)

Python 3.x
Frappe requires Python.

Node.js and npm/yarn
For front-end asset compilation.

Redis
For caching and background jobs.

MariaDB/MySQL
As the database.

Git
For cloning repositories.

Install Frappe Bench

pip3 install frappe-bench

Create a New Bench
This will create a directory where your Frappe sites will live.

bench init frappe-hrms-bench
cd frappe-hrms-bench

Create a New Site
A "site" in Frappe is an independent instance of an application.

bench new-site hrms.local

Install Frappe and HRMS Apps

bench get-app frappe_hr
bench --site hrms.local install-app frappe_hr

Note: frappe_hr is the app name for Frappe HRMS.

Start the Bench

bench start

This will start the development server. You can usually access your site at http://hrms.local:8000 (or whatever port it specifies).

For detailed and up-to-date instructions, always refer to the official Frappe documentation

Let's look at some simple code examples to illustrate how you can customize Frappe/HRMS.

Let's say you want to track an employee's "Preferred Lunch Cuisine."

This is the easiest way for simple additions.

Go to Awesomebar (search bar) and type "Customize Form."

Select DocType
Employee.

Scroll down to the "Fields" table and click "Add Row."

Set

Label
Preferred Lunch Cuisine

Field Type
Select

Options
Italian\nMexican\nIndian\nJapanese\nOther (each option on a new line)

You can also set other properties like "Default Value," "Mandatory," etc.

Click "Update."

That's it! Now every Employee document will have this new field.

For more programmatic control, you'd create a custom app.

Create a New App

bench new-app my_custom_hrms_features

Install the App on your Site

bench --site hrms.local install-app my_custom_hrms_features

Add the Custom Field Definition
Inside your my_custom_hrms_features app, navigate to my_custom_hrms_features/my_custom_hrms_features/doctype/employee_customization/employee_customization.json (you might need to create this structure, or a patch file).

Alternatively, a more common and robust way is to use a Custom Field JSON file directly in your app's custom_fields directory.

my_custom_hrms_features/my_custom_hrms_features/custom_fields/employee/preferred_lunch_cuisine.json

{
    "fieldname": "preferred_lunch_cuisine",
    "label": "Preferred Lunch Cuisine",
    "fieldtype": "Select",
    "options": "Italian\nMexican\nIndian\nJapanese\nOther",
    "insert_after": "reports_to",
    "doctype": "Employee"
}

Then run bench migrate to apply this change.

Let's say you want to automatically set the "Employee Name" based on "First Name" and "Last Name" when creating a new employee.

Create a file my_custom_hrms_features/my_custom_hrms_features/doctype/employee/employee_dashboard.js (or similar path within your custom app, and ensure it's hooked in hooks.py for the Employee DocType).

// my_custom_hrms_features/my_custom_hrms_features/doctype/employee/employee.js

frappe.ui.form.on('Employee', {
    // This function runs when the form is loaded
    refresh: function(frm) {
        // You can add logic here if needed on refresh
    },

    // This function runs when the 'first_name' field changes
    first_name: function(frm) {
        if (frm.doc.first_name && frm.doc.last_name) {
            frm.set_value('employee_name', frm.doc.first_name + ' ' + frm.doc.last_name);
        } else if (frm.doc.first_name) {
            frm.set_value('employee_name', frm.doc.first_name);
        }
    },

    // This function runs when the 'last_name' field changes
    last_name: function(frm) {
        if (frm.doc.first_name && frm.doc.last_name) {
            frm.set_value('employee_name', frm.doc.first_name + ' ' + frm.doc.last_name);
        } else if (frm.doc.last_name) {
            frm.set_value('employee_name', frm.doc.last_name);
        }
    }
});

Note: Frappe's employee_name is usually auto-generated based on Naming Series, but this demonstrates client-side interaction.

Let's say you want to automatically create a "Welcome Task" for a new employee once their status is set to "Onboarded."

You'd add this logic to a Server Script (via the UI) or within a custom Python file in your app, usually in a hooks.py file or a specific Python module associated with the DocType.

Go to Awesomebar and type "Server Script."

Click "Add Server Script."

Set

DocType
Employee

Script Type
DocType Event

Reference Doctype Event
on_update (or after_insert)

Enabled
Checked

In the Script field (Python code)

# Script for Employee DocType on_update event

if doc.status == "Onboarded" and doc.has_value_changed("status"):
    # Check if a welcome task already exists for this employee
    existing_task = frappe.db.get_value("Task", {"employee": doc.name, "subject": "Welcome to the Team!"})

    if not existing_task:
        task = frappe.get_doc({
            "doctype": "Task",
            "subject": "Welcome to the Team!",
            "description": f"Prepare welcome kit and onboarding documents for {doc.employee_name}.",
            "status": "Open",
            "priority": "High",
            "assigned_to": [frappe.db.get_value("User", {"email": doc.user_id}) or "Administrator"], # Assign to the employee's user or admin
            "employee": doc.name # Link the task to the employee
        })
        task.insert()
        frappe.msgprint(f"Welcome Task created for {doc.employee_name}!")

You'd typically define this in a Python file like my_custom_hrms_features/my_custom_hrms_features/employee_events.py and then hook it in your hooks.py.

my_custom_hrms_features/my_custom_hrms_features/employee_events.py

import frappe

def create_welcome_task(doc, method):
    # This function is called when an Employee document is updated or inserted
    if doc.status == "Onboarded" and doc.has_value_changed("status"):
        existing_task = frappe.db.get_value("Task", {"employee": doc.name, "subject": "Welcome to the Team!"})

        if not existing_task:
            task = frappe.get_doc({
                "doctype": "Task",
                "subject": "Welcome to the Team!",
                "description": f"Prepare welcome kit and onboarding documents for {doc.employee_name}.",
                "status": "Open",
                "priority": "High",
                "assigned_to": [frappe.db.get_value("User", {"email": doc.user_id}) or "Administrator"],
                "employee": doc.name
            })
            task.insert()
            frappe.msgprint(f"Welcome Task created for {doc.employee_name}!")

Then, in your my_custom_hrms_features/my_custom_hrms_features/hooks.py

doctype_events = {
    "Employee": {
        "on_update": "my_custom_hrms_features.employee_events.create_welcome_task"
    }
}

After making code changes, remember to run bench migrate and potentially bench restart to ensure the changes are picked up.

Frappe/HRMS is a powerful and flexible open-source solution for HR and payroll. For a software engineer like myself, it's not just a tool; it's a platform for learning, customization, and contribution. Whether you're building bespoke solutions for clients or streamlining internal HR processes, understanding and leveraging the Frappe Framework will undoubtedly enhance your capabilities.


frappe/hrms




Diving into Maigret: A Software Engineer's Guide to User Dossiers

maigret is an open-source OSINT (Open-Source Intelligence) tool written in Python. Its core function is to collect information about a person based on a given username across thousands of websites


Building Applications with Puter: A Developer's Guide

Puter provides a consistent development environment that's accessible from any device with a web browser. This means you don't need to worry about setting up your local machine every time you switch computers


tags, suitable for articles or documentation:

Here is an explanation of how it can be useful, along with deployment and sample code considerations, from a software engineer's perspective


From Tokens to Tasks: A Technical Overview of Composio for Python and TypeScript Developers

Think of Composio as the "Professional Swiss Army Knife" for LLMs. While models are great at thinking, they usually live in a vacuum


Motia: The All-in-One Solution for APIs, Jobs, and AI

Let's dive into MotiaDev/motia, a very interesting backend framework. It's designed to bring a lot of common backend concerns under one roof


Nextcloud Server: An Engineer's Guide to Open Source PHP/JS Collaboration

Here is a friendly and clear breakdown of how Nextcloud can be useful to you, along with examples for getting started.Nextcloud is more than just a file-sync-and-share tool; it's a self-hosted


Building Robust AI Applications with the Model Context Protocol (MCP)

Think of this curriculum as a friendly guide to a very important concept in AI the Model Context Protocol (MCP). Instead of being a single tool or library


OpenArm Deep Dive: Setup, Control, and Sample Code for Robotics Development

The enactic/openarm project is a fully open-source humanoid arm designed for physical AI research and deployment, especially in environments where the arm needs to make contact with objects or its surroundings


Boosting Your Dev Skills with GitHubDaily: A Curated Open-Source List

GitHubDaily is a goldmine for any developer. Here's why it's so valuableDiscovering New Tools It's tough to keep up with the fast-paced world of tech


Python for Web Dev: An Engineer's Guide to reflex-dev/reflex

Let's dive into reflex-dev/reflex, a fantastic tool for us software engineers. It's an open-source framework that lets you build web applications using only Python