App Code
The in-browser editor for extension source — what it is for, and the habits that keep editing production code safe.
The In-Browser Editor
App Code is an editor inside the platform for working on extension source.
Where to find it
Architect Panel → Layout & Pages:
- App Code — the in-browser editor
Architect Panel → Automation:
- Extensions — the extension registry, its versions and runs
Architect Panel → Security:
- Permissions — who may reach the editor
What it gains you
- No local setup. Anybody authorised can make a change from anywhere.
- The code sits beside what it acts on — the datastores and configuration are right there.
- No deployment step for a change to a draft.
And what it costs
Editing production code in a browser is exactly as consequential as it sounds. There is no local branch, no pull request by default, and nobody reviewing over your shoulder.
The convenience is real and it removes the friction that normally makes people careful. That friction was doing something.
Restrict who has it
Access to the editor is the ability to change how the application behaves — equivalent to deploying code, and it should be granted on that basis rather than because somebody is an administrator.
Check who has it periodically. It is exactly the permission that gets granted for convenience and never reviewed.
Work in drafts
The single most important habit. The draft-and-promote model exists so editing is not deploying — use it every time, including for changes that feel too small to matter.
Have a review habit
Nothing enforces review here, so it has to be a practice. Even a colleague reading a diff before promotion catches a meaningful proportion of mistakes, and it is the only check between an edit and production.
Keep source somewhere else too
Version history exists in the platform, and it is not a substitute for your own repository. Keeping a copy under version control gives you branching, review, history alongside the rest of your work, and something to restore from if an instance is rebuilt.
Do not use it as a scratchpad
Experimenting against production data is how something is left half-changed. Where you need to try something, do it in a non-production instance.
Mind what you paste in
Credentials, tokens and connection strings do not belong in extension source. They belong in the platform's own credential storage, where they are encrypted and rotatable.
Worked example
An organisation grants editor access to two people, both of whom would be allowed to deploy. Changes are made in drafts, reviewed by the other before promotion, and mirrored into the organisation's repository. Nothing has been promoted without a second pair of eyes in eighteen months.
Recommendations
- Restrict access as you would deployment rights.
- Always work in a draft.
- Establish a review habit — nothing enforces one.
- Keep a copy in version control.
Working on Extension Code
Extension code runs inside the platform, on real data, frequently while somebody waits. That shapes how it should be written.
Where to find it
Architect Panel → Layout & Pages:
- App Code — the in-browser editor
Architect Panel → Automation:
- Extensions — the extension registry, its versions and runs
Architect Panel → Activity:
- Error Log — where failures surface
Assume everything fails
External calls time out, values are missing, data is malformed, records are in states nobody anticipated. Code that assumes the happy path will meet all of these in its first month.
Handle failure explicitly rather than letting it propagate — and remember the fail mode setting decides whether your failure stops the operation or is skipped.
Be quick
Extensions run under a timeout, and frequently while a person waits. Anything slow — a large query, an external call, a loop over many records — belongs in a background task rather than in a hook attached to saving a record.
If you find yourself raising the timeout, that is usually a signal the work is in the wrong place.
Enforce permissions yourself
Custom code reaching data directly is not constrained by field security or row-level access unless you constrain it. If your extension returns or acts on something the triggering user should not see, that is a disclosure nothing else will catch.
Never embed credentials
They belong in the platform's credential storage. A secret in extension source is in your version history, in the platform's version history, visible to everybody with editor access, and awkward to rotate.
Only call allowlisted hosts
Outbound calls are restricted to hosts on the extension's allowlist. Design for that — and if you need a new host, add it deliberately rather than widening the list to something permissive.
Log enough to diagnose
When something goes wrong at three in the morning, what the log holds is what you have. Record what the extension was acting on, what it decided and what it received from anything external.
Do not log the data itself where it is personal — record identifiers and outcomes, not payloads.
Be idempotent where you can
Runs can be retried, and an extension that creates something each time it runs will create duplicates. Where the work is repeatable, make running it twice produce the same result as running it once.
Keep it small
An extension doing one thing is testable, reviewable and safe to change. One that has accumulated five responsibilities over three years is none of those, and nobody will want to touch it.
Worked example
An extension calling a supplier's API wraps the call with explicit timeout handling, logs the order reference and the outcome rather than the payload, takes its credential from platform storage, and is idempotent on the supplier's reference so a retry cannot double-book. It fails open, because a supplier outage should not stop order entry.
Recommendations
- Handle failure explicitly — everything fails eventually.
- Move slow work to a background task.
- Check permissions in your own code.
- Log identifiers and outcomes, not personal data.