When you need xMatix to behave differently, there is almost always more than one tool that could do it — and they form a ladder, from plain configuration at the bottom to custom code at the top. The rule that keeps a system maintainable is simple: pick the lowest rung that genuinely solves the problem. Lower rungs are declarative — visible in Setup, testable before they go live, and safe across product updates. Higher rungs buy expressive power at the cost of code that someone must read, test and maintain. Climb only when the requirement truly cannot be expressed a rung below, and never ship a weaker approximation just to stay declarative.
Where the rungs live in Setup
The bottom rung is Setup → Design Studio → Entities: open an entity and its Schema (fields, record types, relations, lookup filters, field dependencies), Logic (validations, actions, approval processes, document settings) and Experience (views, layouts, email templates) pages. Every higher rung is a register under Setup → Process Studio: Business Rules, Scripts, UI Components, Workflows, Approvals, and — for system boundaries rather than behavior — Integrations and Sync Profiles. Each register is gated by its own setup capability (for example setup.automation.businessrules.manage, setup.automation.scripts.manage, setup.automation.workflows.manage, setup.automation.customcomponents.manage, setup.metadata.approval.manage); the data model needs setup.metadata.model.manage. Before adding anything, search the relevant register: overlapping rules, scripts and workflows on the same entity are the commonest cause of surprising saves.
The ladder at a glance
| Rung | Tool | Reach for it when |
|---|---|---|
| 1 | Field, validation and record-type configuration | The change is about a field: required, unique, a default, a picklist value, a format, a layout, a variant of the record |
| 2 | Business rules | "When this record is saved (or changes state), enforce, derive or hand off something" |
| 3 | Approval processes | A person must sign off before something proceeds |
| 4 | Workflows | Multi-step processes over time: "then wait, then notify someone, then do a second thing later" |
| 5 | Automation scripts | Server-side logic beyond declarative reach: cross-record calculations, calls to other systems, custom buttons |
| 6 | Custom components | The standard user-interface widgets cannot express the experience |
The rungs in detail
Field, validation and record-type configuration
The bottom rung is not really customization at all — it is the entity model itself. Required and unique fields, defaults, picklists, field formats, lookup filters, field dependencies, record types and page layouts cover a surprising share of requirements. A validation on the entity is a plain, always-on check with a message; it is the right home for a rule with no condition ("Quantity must be positive"). If the ask can be stated as a property of a field or as an unconditional check, it belongs here. See Entity behavior and Design a form layout.
Business rules
A business rule is declarative logic evaluated inside the save pipeline: a condition on the incoming record and an ordered list of actions. Its triggers decide when it is evaluated — on every save, only on insert or update, only when named fields change, on delete, when a status field makes a specific transition (Draft → Submitted), after an approval decision, on an hourly schedule, or after the save commits.
The actions split into two families, and the split matters for choosing a rung:
- Save-time actions shape the record before it is written: Block Save and Show Message (error, warning or info), Set Value, Copy From Field, Format Value, Lookup Value, Set Required, Set Read-Only, Lock Record (with editable exceptions) and Enforce Unique.
- Bridge actions run only after a successful commit and hand off to another subsystem instead of changing the record: Request Approval, Invoke Automation Script (a server-action-bound script), Raise Event, Assignment (route to a queue or resource), Create Activity, Create Record (of any entity), Send Message (templated e-mail or in-app), Enqueue Job and Raise Nudge.
Because of the bridges, a rule reaches further than "this record only": it can start an approval, open a task, create a related record or kick off a script without any code of its own. What a rule cannot do is call an external system directly, compare arbitrary old and new values (a status transition has its own trigger; anything else needs a script), or wait — every action of a rule runs within the save or immediately after it. Rules have a Test Runner in Setup, so you can prove a condition against a real record before activating it. See Business rules.
Approval processes
When the requirement is "a manager must allow this", model it as an approval process — even when it looks like the escape hatch of a blocking rule. An approval process is defined per entity with an entry condition, an order (the first matching active process claims the record), who may submit, and one or more steps that resolve a real approver from a record field, a role or a team. It notifies the approver, can lock the record while the decision is pending, enforces maker-checker if you ask it to, stamps the outcome onto the record and leaves an audit trail of who decided what and when. Records enter it from a Submit for approval action, from a business rule's Request Approval bridge, or from a workflow step. An editable "approved" checkbox is not an approval: it records no approver, no timestamp and no reason. See Approval processes.
Workflows
A workflow orchestrates across time and across records in a visual designer: it starts from a record event (create, update or delete of a named entity, either synchronously before the save — the only phase that can cancel it — or asynchronously after it), then runs steps such as branch, wait, send a message, submit for approval, update or create records, call a script or enqueue a job. Triggers register only from the published version; every edit is a draft until you publish again. If the ask contains "and then, later…", it is a workflow rather than a business rule. See Build a workflow.
Automation scripts
Scripts are C# code compiled when you save them and run by the platform in a sandbox with a single Ctx object as their whole contract: records with old values, data access to any entity, metadata, outbound HTTP, messaging and e-mail, jobs and queues, approvals, secrets and logging. A script is bound to an entity either on a lifecycle slot — load defaults (inserts), pre-validate, validate, before save, after save, before delete, after delete — with the change kinds it listens to and an optional condition, or to a server action behind a button. Bindings can run inline or asynchronously on the worker; inline runs have a 10-second budget, asynchronous runs 60 seconds. Reach for a script for cross-record calculations, external calls, complex old-versus-new comparisons and the logic behind custom buttons. See Your first automation script.
Custom components
Custom components (Process Studio → UI Components) are your own user-interface widgets, versioned like scripts and bound to one entity or to all entities, and optionally offered inside App Pages. They are placed in layouts and pages by the designer and read and write through the same data APIs as the rest of the product, so security and validation still apply. This rung is for presentation; if the logic could live server-side, keep it there. This is the one rung that runs in the browser rather than on the server, so a component can never enforce anything — pair it with a rule or validation when data integrity depends on it.
Choosing quickly
A few signal phrases map directly to rungs: "this field must…" is configuration; "when the record is saved…" is a business rule; "someone must approve…" is an approval process; "then wait / then notify / then later…" is a workflow; "look across records / call another system…" is a script; "show it differently…" is a layout or a component. When two rungs both work, the lower one wins.
Two further questions settle most borderline cases. Does it need to block the save? Only validations, save-time rule actions, before-save workflows and validate/before-save scripts can; anything that runs after the commit cannot. Must it survive an edit by any administrator? Rules, approvals and workflows are readable in Setup by anyone with the capability; a script is readable only by someone who reads code.
Try it somewhere safe
Every rung can be authored in a sandbox copied from production and moved across with a package, so a new rule, workflow or script never meets live records untested. All rungs also run inside one fixed save pipeline — defaults, validation, rules, module logic, then workflows and scripts — and when two customizations seem to fight, that order is almost always the explanation; see What runs when you save a record.
Common questions
Why prefer a business rule over an automation script?
Because a rule is declarative: any administrator can open it in Setup, read exactly what it does, test it against a record, and adjust it without a developer. A script is code — more expressive, but opaque to non-developers and a maintenance obligation from the day it ships. Both run in the save pipeline, so for single-record save logic the rule delivers the same outcome at lower cost. Reserve scripts for what rules genuinely cannot express: cross-record calculations, external calls, complex comparisons of old and new values.
Can a business rule call another system?
Not directly — a rule never makes an outbound call itself, which is what makes it safe to run inside every save. It can hand off: its after-commit bridge actions can invoke a server-action script (which may call out through Ctx.Http), send a templated message, enqueue a background job or raise an event. When a save must reach another system, use one of those bridges or an integration flow when you need connector-grade retry and monitoring. See the integrations overview for how external connections are modeled.
Isn't an "override" checkbox simpler than an approval process?
Simpler to build, worse in every way that matters. A checkbox that lifts a block records nothing: no approver identity, no timestamp, no reason, and anyone with edit rights can tick it. An approval process resolves the right approver, notifies them, locks the record while pending, and writes an audit trail. If you do choose a checkbox as a deliberate lightweight alternative, restrict who can edit it with field-level security — and treat that as the exception, not the default.
When is a workflow the wrong tool?
When everything it does happens inside one save with no waiting and no branching over time — that is a rule. And when it must block the save on a condition — a rule or validation does that without the publish-and-version overhead, and an asynchronous workflow cannot block at all.
