---
url: https://apexfluently.beyondthecloud.dev/libraries/trigger-lib.md
description: >-
  Apex trigger framework with record filtering, automatic parent enrichment,
  bypasses, and recursion control. One orchestrator per SObject, one handler per
  concern.
---

# Trigger Lib

Apex trigger framework for Salesforce with record filtering, automatic parent enrichment, bypasses, and recursion control.

::: info Documentation
You can find the full documentation at [trigger.beyondthecloud.dev](https://trigger.beyondthecloud.dev/).
:::

## What Does It Solve?

* **Bulk Loops In Every Handler** - Each handler iterates over `Trigger.new` and guards records on its own.
* **SOQL Scattered Across Handlers** - Parent data is queried in many places and burns query limits.
* **Uncontrolled Recursion** - Update triggers re-fire with no depth limit.
* **Heavy Setup** - Frameworks require custom metadata before the first handler runs.

## Why Trigger Lib?

* **Orchestrator & Handlers** - One orchestrator per SObject, one handler per concern, wired in Apex.
* **Record Filtering** - Handlers run only against records that qualify, so logic never guards itself.
* **Parent Enrichment** - Related data is pulled up front, so handlers make no SOQL queries of their own.
* **Bypasses** - Disable an individual handler or a whole orchestrator when you need to.
* **Recursion Control** - Depth limiting built in, defaulting to 3.
* **No Required Metadata** - Works with zero custom metadata records; metadata only overrides defaults.

## Quick Start

```apex
// Trigger
trigger ContactTrigger on Contact(before insert) {
    TriggerOrchestrator.run(new ContactTriggerOrchestrator());
}

// Orchestrator - one per SObject
public with sharing class ContactTriggerOrchestrator implements TriggerOrchestrator.BeforeInsert {
    public List<BeforeInsert.Handler> beforeInsertHandlers() {
        return new List<BeforeInsert.Handler>{ new ContactDescriptionHandler() };
    }
}

// Handler - runs on a single record that qualifies
public with sharing class ContactDescriptionHandler implements BeforeInsert.Handler {
    public Boolean qualifiesForBeforeInsertWhen(TriggerHandler.Record record) {
        return record.isRecordTypeEqual('Business_Contact') && record.isBlank(Contact.Description);
    }

    public void onBeforeInsert(TriggerHandler.Record record) {
        record.put(Contact.Description, 'Created by ContactDescriptionHandler');
    }
}
```

## Documentation

* [GitHub Repository](https://github.com/beyond-the-cloud-dev/trigger-lib)

## Installation

* [Installation Guide](https://trigger.beyondthecloud.dev/installation.html)
* [Copy and Deploy](https://github.com/beyond-the-cloud-dev/trigger-lib/tree/main/force-app/main/default/classes)
