Skip to content

FFLib vs Apex Fluently

FFLib is an excellent library created by Andrew Fawcett and widely adopted by the Salesforce community. It is important to note that FFLib was created over 10 years ago to address the challenges Salesforce presented at that time. One of the most critical issues was Field-Level Security (FLS/CRUD). Since Apex runs in system mode by default, performing CRUD checks required explicit calls to Schema. Introducing additional layers of abstraction-such as selectors and the Unit of Work-to handle CRUD checks was a smart and forward-thinking solution.

The tools we use should help overcome the limitations of the underlying technology, and this is exactly what FFLib achieved by providing a structured way to handle CRUD and many other concerns.

However, times change-and Apex has evolved significantly. New features are continuously introduced, and while FFLib has attempted to keep pace with these changes, in our opinion it has struggled to fully adapt. Some relatively recent features, such as Database.queryWithBinds (introduced in Winter ’24), are still not supported.

Additionally, modern software architecture increasingly favors lightweight, flexible approaches that can be easily adapted to project-specific needs. FFLib has traditionally been best suited for large, enterprise-scale projects; for smaller projects, it often feels like overkill. As a result, many of its benefits tend to be realized primarily by large enterprise clients. From our personal experience (which may be limited), we have rarely encountered a truly clean and well-executed FFLib implementation in real-world projects.

There are many more reasons why FFLib may not be the ideal choice for modern software development-but let’s keep it simple.

Our Alternative

We propose a different approach: well-designed, flexible, single-class frameworks that can be used independently, with no dependencies between them. Each framework can be tailored to the specific needs of a project. For example, the SOQL library does not force you to adopt a selector layer-you may choose to use one or not, and you can implement it in various ways based on your own judgment. We provide recommendations, but the final decision is always yours.

Philosophy Behind Apex Fluently

The primary goal of Apex Fluently is not just to solve technical problems-it is to make developers’ lives easier.

What does that mean in practice? A significant portion of our implementation effort was dedicated to interface design. We continuously asked ourselves:

  • Is this easy to use?
  • Is it obvious?
  • Would another developer immediately understand it?

We do not want to deliver another overcomplicated or overengineered set of libraries. Simplicity is the key. Apex Fluently is designed to be truly plug-and-play - without the need to dive into the implementation details or spend time understanding internal mechanics. The libraries should naturally guide you toward the correct usage and clearly inform you when something is wrong.

To achieve this, we made several deliberate technical decisions:

  1. Single-class design
    Most of our frameworks are implemented as a single class. Why? Because you can simply copy and paste them without worrying about unnecessary dependencies or deployment issues. Everything is contained within one class. This also provides a clear and obvious entry point-you never have to search for where to start.

  2. Strong encapsulation via interfaces
    We emphasize strong encapsulation. All methods intended for public use are clearly exposed at the top of the class. There is no need to dig into the implementation to find what you need-everything relevant is immediately visible.

  3. Builder pattern and Fluent API
    While we use multiple design patterns internally, the usage layer is built around the builder pattern. You can chain methods in virtually any order without worrying about internal dependencies-the library will handle it. Need to override default behavior? Simply chain another method. This approach naturally results in a Fluent API and makes the code extremely readable, with an English-like notation.

  4. Comprehensive documentation
    Every library is fully documented with dedicated documentation. You will find extensive examples, complete API references, and even search functionality that directs you straight to what you are looking for.

The most common feedback we hear about Apex Fluently is:

“It’s so easy to use - I love it!”

Keep an open mind, give Apex Fluently a try, and see for yourself.

Comparison

CategoryFFLibApex Fluently
Documentation❌ Limited documentation and examples (fflib.dev)✅ Comprehensive documentation with extensive examples and use cases; each library has its own dedicated documentation site
API Design❌ No clear API structure; requires digging into implementation to find methods✅ Single-class libraries with all public methods defined in interfaces at the top of each class
Installation❌ Copy and Paste or Deploy button only✅ Multiple options: Copy and Paste, Deploy button, Unmanaged Package, Unlocked Package
Features❌ Missing modern Salesforce features (e.g., Database.queryWithBinds(), WITH USER_MODE, Iterable)✅ Includes the latest Salesforce Apex features, aligned with each Salesforce release
Bug Fixes❌ Pending bugs remain unresolved✅ No known issues; reported problems are resolved within 24 hours
Development❌ Not actively developed; updates occur every few months✅ Actively maintained with new features implemented weekly or monthly
Project Fit❌ Best suited for large projects; can be overkill for smaller implementations✅ Scales to any project size without unnecessary complexity
Battle-Tested✅ Widely adopted across many projects✅ Proven in production across numerous projects; SOQL Lib has been cloned over 2,000 times
Flexibility❌ All-or-nothing approach due to internal dependencies✅ Fully modular with no inter-library dependencies; use only what you need (e.g., SOQL Lib works without a selector layer)
Support❌ Community-managed with slow response times✅ Professionally managed by Beyond The Cloud with rapid response times
Complexity❌ Complex architecture built over 10 years; difficult to understand✅ Simple single-class architecture with small, well-documented methods