Skip to content

Trigger Lib

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

API version

License

GitHub Repo starsGitHub Release

Documentation

You can find the full documentation at 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

Installation