defineApplication call. It declares:
- Identity — universal identifier, display name, description.
- Permissions — which role its logic functions and front components run under.
- Variables (optional) — key–value pairs exposed to your code as environment variables.
- Pre-install / post-install / uninstall hooks (optional) — see Logic Functions.
src/application-config.ts
universalIdentifierfields are deterministic IDs you own. Generate them once and keep them stable across syncs.applicationVariablesbecome environment variables for your functions and front components. In logic functions (server-side), they are available asprocess.env.VARIABLE_NAME. In front components, usegetApplicationVariable('VARIABLE_NAME')fromtwenty-sdk/front-component. Variables marked withisSecret: trueare only injected into logic functions. Front components receive only non-secret variables.- The default role is detected automatically from the role file marked with
defineApplicationRole()— you do not need to reference it fromdefineApplication(). - Pre-install, post-install, and uninstall functions are detected automatically during the manifest build — you do not need to reference them in
defineApplication(). - Passing
defaultRoleUniversalIdentifierexplicitly is still supported for backward compatibility, but is deprecated in favor ofdefineApplicationRole(). serverVariablesare instance-scoped configuration and secrets (e.g. API keys). UnlikeapplicationVariables, they declare no value in the manifest — the workspace operator fills them in from the app’s settings, and they are injected into logic functions only once set.- To render a custom configuration UI inside the app’s Settings tab (in place of the default variable configuration section), declare a front component with
defineSettingsFrontComponent()in its own file. Only one is allowed per app. System-managed sections (auto-upgrade, App URL, connections) always remain visible.
Variable types
BothapplicationVariables and serverVariables accept an optional type (and, for SELECT / MULTI_SELECT, an options list). Supported types: TEXT (default), BOOLEAN, NUMBER, NUMERIC, DATE, DATE_TIME, SELECT, MULTI_SELECT, ARRAY, RAW_JSON, RICH_TEXT.
src/application-config.ts
type only affects presentation and validation — it selects the matching input in the workspace settings UI (a toggle, number field, dropdown, date picker, JSON editor, …) and lets the build validate your config (for example, SELECT / MULTI_SELECT must declare non-empty options). It does not change how the value reaches your code.
Values are always injected as strings — this is inherent to environment variables (process.env.* is string-only). When your logic function runs, the executor serializes each value by its declared type while building process.env, so the string format is consistent no matter how the value was set (manifest default, settings UI, or a previous version):
Parse the string back into the type you expect:
getApplicationVariable('VARIABLE_NAME') — the returned value is a string; parse it as needed.
Default function role
The role declared withdefineApplicationRole() controls what the app’s logic functions and front components can access:
- The runtime token injected as
TWENTY_APP_ACCESS_TOKENis derived from this role. - The typed API client is restricted to the permissions granted to that role.
- Follow least-privilege: declare only the permissions your functions need.
src/roles/default-role.ts. See Roles & Permissions for the full reference.
Marketplace metadata
If you plan to publish your app, these optional fields control how it appears in the marketplace:logoUrl and screenshots are deprecated aliases of logo and galleryImages. External absolute URLs (http:// or https://) are not supported for these fields: they are dropped with a warning at build time. Bundle the images in your app’s public/ folder instead.