A staff portal small businesses can actually self-host.
StaffPortal is an MIT-licensed reference implementation of an internal staff platform: auth, leave, attendance, payslips, and a document store. It is the open-source distillation of the patterns I keep rebuilding for clients. Fork, rebrand, deploy on Vercel + Supabase, done in an afternoon — without paying per-seat for HR SaaS.
Problem
Small businesses — twenty to a hundred staff — are stuck in the worst part of the HR-software market. They are too small for proper HRIS platforms (which charge enterprise pricing) and too big to keep running everything on a shared spreadsheet. The middle ground is a graveyard of generic SaaS tools that almost-fit and cost £8 per seat per month, forever.
I have built variants of the same internal platform multiple times for clients. Every time, the core 80% is identical: auth, role-based access, leave requests with manager approval, attendance logging, payslip storage, a place to keep policies. The other 20% is genuinely client-specific.
Open-sourcing the core 80% felt obvious. A small business owner who is technical-adjacent — the kind of person who can run `git clone` and follow a README — should be able to deploy a real internal platform without writing a cheque or signing a contract.
- →Per-seat HR SaaS adds up fast for a 50-person business
- →Generic SaaS tools rarely fit how small teams actually work
- →The core feature set is the same across every implementation
- →Existing “HR open source” projects are either dead or bloated
Approach
The design brief was: deployable in an afternoon by someone who can read a README. That meant ruthless choices. One stack — Next.js, Supabase, Tailwind, shadcn/ui. One deployment target — Vercel. One database — the Supabase project you already have. No Docker, no microservices, no Kubernetes, no message queue, no infra you have to provision.
Every feature had to clear a useful bar: does at least 80% of small businesses need this? If not, it stays out of core and can live in a fork. The first cut had auth, profiles, leave, attendance, payslips, and a document store. That was it. No performance reviews, no recruiting, no expenses — those are coming, but only when the core is solid.
I leaned hard on conventions over configuration. Database schema is shipped as Supabase migrations you run with one CLI command. Permissions are pre-baked as RLS policies you do not have to write. Branding is one config file. Email templates are React Email components you can edit if you want, ignore if you do not.
- →Single-stack: Next.js + Supabase + Vercel, nothing else
- →Schema shipped as migrations, applied with one command
- →RLS policies pre-baked: owner, manager, employee roles out of the box
- →Branding via single config file (logo, colours, company name)
- →Email templates as editable React Email components
- →MIT licensed, no telemetry, no usage tracking
If you cannot deploy this in an afternoon, I have failed. That was the brief I held myself to.
Solution
StaffPortal ships as a Next.js application with five working modules out of the box. Auth + profiles handles invite-based onboarding, role assignment, and a basic profile page. Leave covers request, approval, and balance tracking with sensible defaults (statutory UK leave plus configurable bank holidays). Attendance lets staff clock in and out, with an optional kiosk mode. Payslips is a manager-uploaded document store with employee-only visibility. The document store is a general-purpose folder of company policies and forms.
Setup is documented as a literal sequence of seven commands: clone, install, link Supabase, run migrations, set environment variables, deploy to Vercel, invite yourself. The README walks through each one with screenshots. If you have done a Next.js + Supabase project before, you will be live in thirty minutes.
The codebase is intentionally small and readable. Every server action is a separate file. Every database query is plain SQL inside a typed wrapper. Every component is named after what it does. There is no clever abstraction layer between you and the data, because the goal is for a future maintainer to walk in and understand the whole thing in an afternoon.
The roadmap, kept on the public repo, is the next set of modules: expenses (with the AI receipt OCR pattern from my client work, optionally enabled), basic timesheets, and a directory. Each one is a contained PR; nothing in the existing modules has to change.
- →Five working modules out of the box: auth, leave, attendance, payslips, documents
- →Seven-command deploy, fully documented in the README
- →Single-stack, no Docker, no separate infra
- →Small, readable codebase: no clever abstractions, no magic
- →Public roadmap, contributor-friendly issue tracker
- →MIT license, zero telemetry, zero lock-in
What actually changed.
Open source on GitHub. Used by myself and a handful of small businesses who have forked it. The reference implementation now feeds back into my client work — every paid project starts from a known-good baseline.
The most useful outcome — to me — is that StaffPortal has become the foundation of every internal platform I now build for clients. I start with a fork, configure it, and then add the client-specific 20% on top. That has cut the typical project time roughly in half and made every project more reliable, because the core has already been hardened.
For the small businesses who have self-hosted, the value is straightforward: they own their data, they pay only for hosting (which is generous on Vercel + Supabase free tiers up to a meaningful scale), and they can change anything they want. A few have already submitted PRs back upstream — bug fixes, copy improvements, a German translation.
It is also a deliberate statement about how I think about open source. The interesting parts of my client work are the patterns, not the specific implementations. Open-sourcing the patterns gives them a longer life than any single project, and gives smaller businesses access to the kind of internal tools that used to be the preserve of bigger budgets.
Tools, picked deliberately.
What I would tell someone building this from scratch.
Defaults are the product.
For a self-hostable template, the defaults are everything. UK statutory leave, sensible roles, reasonable email copy — these are why somebody can deploy in an afternoon. The defaults are more important than the configurability.
Boring stacks are kind to future maintainers.
I deliberately chose the most boring possible stack: Next.js, Supabase, Tailwind, shadcn. None of it requires reading a 200-page book to contribute. Boring is a feature for open-source software.
Small surface area beats big feature set.
The temptation with an HR template is to ship every possible module. I shipped five. Five is enough to be useful, small enough to maintain, and leaves room for forks to add domain-specific modules without fighting the core.
Open source is a multiplier on client work.
Every client project I now build sits on top of StaffPortal. The hours I have put into the open-source codebase pay back many times over in faster, more reliable client deliveries.
Documentation is part of the deploy.
A self-hostable project lives or dies by its README. I spent as long on the README as I did on some of the modules. If the deploy story breaks, the project dies, regardless of how good the code is.
Need something like this built?
I take one client at a time. If your problem is real and your timeline is honest, let’s talk.