fflib-apex-common brings the Apex Enterprise Patterns into a shared library
Common Apex Library supporting Apex Enterprise Patterns and much more!
At a glance
- What is it?
- fflib-apex-common is a dependency-free Apex library that packages the Service, Domain and Selector layers of the Apex Enterprise Patterns for Salesforce developers, together with a Unit of Work and a Data Mapper approach to DML. It is BSD-3-Clause licensed, deployed as an SFDX project, and shipped without tagged releases.
- Who is it for?
- fflib-apex-common fits a Salesforce development team that wants the Selector, Domain and Service separation enforced by a library it does not have to maintain in every org, and that can accept a shared package dependency in exchange. It does not fit a team that wants zero package dependencies in production, and it is a poor fit for a small org where writing a handful of base classes locally would be faster.
- Can I use it commercially?
- Yes. BSD-3-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly Apex, 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
The library is a set of layers, not a framework you plug into
The thing to understand about fflib-apex-common is that it is a library of base classes and interfaces, not a runtime framework with a bootstrap of its own. The idea it implements comes from a Dreamforce 2012 presentation on Apex Enterprise Patterns, and the patterns it carries forward are ones that already existed in other platforms and languages: Data Mapper, Service Layer, Unit of Work and Model View Controller. The stated purpose of applying them to Force.com is to help manage governed resources such as DML, to encourage better separation of concerns in the logic, and to enforce Force.com coding practices.
That framing matters for how you evaluate it. Adopting the library is not a matter of switching on a feature. It is a matter of restructuring your Apex so that queries, business logic and persistence each live in a layer with a defined job, and then adopting base classes that enforce that structure. The payoff is a codebase where a reviewer can tell where a piece of logic belongs. The cost is a refactor.
The project also adds namespace qualification compared with the earlier version of the patterns, so that classes group together more easily in the IDE and in packages. For an org with many managed packages installed, that is not a cosmetic detail. It is what stops your base classes from colliding with the base classes of the next library you take a dependency on.
Selector, Domain and Service each own a different kind of logic
The documentation list makes the layering concrete, with separate write-ups for the Service Layer, the Domain Layer and the Selector Layer, plus Trailhead modules covering separation of concerns, the service layer, and the domain and selector layers together.
The Selector Layer is the query layer. It is where SOQL lives, which means a single place to look when you want to know which queries your application issues and to keep them out of the business logic. The Domain Layer is where the rules live: the behaviour that applies to your records, independent of how they are queried and independent of who is calling. The Service Layer sits above both and is the entry point that orchestrates them, which is where a user action or an interface call lands.
The reason this matters on Salesforce specifically is the platform constraint. DML is a governed resource, with limits, with transaction boundaries, and with sharing rules that apply to every record you touch. A codebase that scatters queries and updates across classes cannot answer simple questions about how many rows it will insert in a transaction or which classes bypass sharing. Splitting the layers gives you a place to put the answer, and the library gives you base classes to inherit from so the structure is a convention rather than a code review comment.
One caveat the documentation raises is Apex sharing. A separate article covers Apex Sharing and its application to the patterns, which tells you the interaction between the layers and the platform's sharing model is a real topic, not an afterthought. A library cannot make your sharing decisions for you.
Unit of Work and Data Mapper cover the record boundary
Beyond the three layers, the pattern set includes a Unit of Work and a Data Mapper, and those two are what deal with records at the edge of your business logic.
A Unit of Work is the object that knows what has changed and what needs to be persisted, and it typically owns the transaction boundary: it collects the work, performs the DML, and handles the outcome. On a platform where DML is a governed resource, that boundary is worth making explicit, because it is the point at which you can decide what to do with a partial failure and how many rows a single transaction touches.
A Data Mapper is the object that moves data between your domain objects and the database, keeping the field-level knowledge of your SObjects in one place rather than spreading set statements across the codebase.
Taken together with the Model View Controller pattern named in the same list, the library gives you a fairly complete answer to how a Salesforce application should be layered, including the part where a controller handles input from a page, a Lightning component or an API caller. That last part is where the library is most opinionated and where you have to check compatibility with your current interface layer, because a controller base class assumes things about how your entry points are structured.
The README names the layers and the patterns and points to an alternative domain structure document and a changelog, so read those and the source tree before you commit to the refactor.
No dependencies for deployment, and ApexMocks is only a companion
The dependency situation is stated unusually clearly, and it matters for org limits and for release management. The project says there are no dependencies for deployment or for running the library's own Apex tests. ApexMocks, the Mockito-style mocking library for Apex, remains a useful companion if your own application tests use that style, but it is explicitly not required by the fflib-apex-common metadata.
That is a cleaner position than most Apex libraries occupy, where a test framework dependency drags a whole namespace into every scratch org. Here the library is self-contained, and the mocking question is a separate decision you make for your own test suite.
The test story is thin, though. The repository carries a CI workflow whose badge reads as a push-and-run-Apex-tests workflow, and it creates a scratch org as part of that process, which tells you the library is tested on every push in an automated way. There is no coverage figure and no per-release test report, and there is no tagged release at all, so there is no release-by-release note to read.
Practically, this means adopting the library means adopting a source dependency rather than a versioned one. Since the repository has no GitHub releases, the snapshot you deploy is whatever the default branch held at the time you deployed, and pinning a specific commit is the only way to keep two orgs on the same code.
Deployment is an SFDX project and a button, not an install command
There is no package installation command, and there is no npm or Composer style entry point, because the artifact is Apex. What the repository contains is an SFDX project layout: a sfdx-project.json at the root and a sfdx-source/ directory holding the code, alongside config/ and docs/ directories. The README links to a deployment button that pushes the source to a Salesforce org, which is the deployment path the project itself points at.
That is a meaningful difference from a library you install by running one command. Adopting this one means getting the code into your org, and the question of how, whether through the deploy button, through a source format, or by copying classes into the org by hand, is left to the deployment tooling you already use. There is a working sample application in a separate repository, fflib-apex-common-samplecode, which illustrates the patterns end to end and is the fastest way to see what a project looks like once the layers are in place.
For a team with a Salesforce DX pipeline already in place, this is a non-issue. For a team without one, it is the largest single piece of work in the adoption, and larger than the code changes themselves. A related detail worth noting is that the project has a dedicated document for migration tips and one for key changes, which is the place to read before planning the refactor, since the structure has moved since the original 2012 version.
BSD-3-Clause, no releases, and commits landing as of 2026-10-06
The licence is BSD-3-Clause, which is permissive and short. You can use, modify and redistribute the code, including inside proprietary commercial software, provided you keep the copyright notice, the licence text and the disclaimer of warranty. For a library that other teams may fork internally, that is a light obligation compared with the copyleft of a GPL project. This is a licensing fact rather than legal advice.
The maintenance picture needs a caveat. The repository is not archived, the default branch is master, and the last push was on 2026-10-19, so the code is still being changed. At the same time, the project has no GitHub releases, and no tags to speak of, so there is no versioned artefact to install and no release notes per version. The changelog lives in the repository instead, at docs/changelog.md, which is where you would look to see what changed.
For a library that other people deploy into production orgs, the absence of tagged releases has a concrete consequence. You cannot say in a change record that you upgraded from version A to version B, because there are no versions. You can only say that you deployed a particular commit. Any team that needs traceability on what is running in which org has to build that discipline themselves, and it is worth asking the maintainers, or the community on FFLib.dev, how they expect consumers to track versions before a large rollout.
The activity level is healthy, which is the more positive half of the picture. A library that was introduced in 2012 and still receives commits in 2026 has outlived most of its peers.
The realistic alternative is your own base classes in each org
The other way to get the same separation of concerns is to write the base classes yourself: a selector base class, a domain base class, a service base class, a unit of work and a data mapper, in every org, kept in sync by hand or by packaging them yourself. The difference in approach is where the maintenance burden sits, not in the shape of the design.
Your own classes are free to shape exactly as your team wants, they add no package dependency to your org, and you can evolve them without waiting on anyone else. That is a genuine advantage, and for a small team or a single org it is often the faster path, since the library's structure is a fairly opinionated answer to a problem you may not have in the same shape.
The library wins on the other side. You inherit a design that has been applied to Salesforce for over a decade, you get the benefit of other people's fixes to selector and unit of work behaviour, and you avoid maintaining five base classes per org. The cost is that you take a dependency on code you do not control, in a project with no tagged releases, and you have to accept its layering rather than adjust it.
The other alternative is the documentation route rather than the code route. The Trailhead modules and the pattern articles linked from the README describe the same layers in detail, and a team that follows them closely can build its own implementation without taking a dependency. The library is the shortcut version of that path, with the usual trade: less work up front, less control afterwards.
Editorial conclusion
fflib-apex-common fits a Salesforce development team that wants the Selector, Domain and Service separation enforced by a library it does not have to maintain in every org, and that can accept a shared package dependency in exchange. It does not fit a team that wants zero package dependencies in production, and it is a poor fit for a small org where writing a handful of base classes locally would be faster. Before adopting it, read docs/changelog.md and docs/newdomainstructure.md to see how much of the old structure you would be moving, confirm the selector and service layers still match your current Apex style, and deploy the sample application in a sandbox to judge the fit before you touch production code.
Frequently asked questions
What does fflib-apex-common actually give me in a Salesforce org?
It is a library of base classes and interfaces that implement the Apex Enterprise Patterns, including the Selector, Domain and Service layers along with a Unit of Work and Data Mapper approach to DML. Adopting it means restructuring your Apex so each layer owns one kind of logic.
Do I need ApexMocks to use fflib-apex-common?
No. The project states there are no dependencies for deployment or for running its own Apex tests, and that ApexMocks is only a useful companion if your application tests use Mockito-style mocking. It is not required by the library metadata.
How do I install fflib-apex-common in a Salesforce org?
There is no installation command, because the artefact is Apex source rather than a package you fetch. The repository is an SFDX project with sfdx-project.json and sfdx-source/, and the README links to a deploy to Salesforce button, so deployment goes through the Salesforce tooling you already use.
Is fflib-apex-common still being worked on?
The repository is not archived and the last push was on 2026-10-19. There are no GitHub releases, so there is no tagged version to install and you track changes through the changelog in docs/changelog.md instead.
What licence is fflib-apex-common under?
BSD-3-Clause, which permits commercial use, modification and redistribution provided the copyright notice, the licence text and the warranty disclaimer are retained. The licence file is in the repository root.
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/apex-enterprise-patterns-fflib-apex-common)Was this useful?