Two breaking changes require migration before upgrading. CoreApiClient now requires { runAs } at construction; omitting it fails typecheck. LogicFunctionExecutionContext now carries workspace and trigger fields. SidePanelExpandTarget now takes an expand callback; update front components that wire the side-panel expand action.
localStorage and sessionStorage now work in sandboxed workers, scoped per-app and per-user. Add frontComponentSharedDependencies to package.json to share library bundles across components, dropping per-component size from ~190KB to ~1.6KB. Standard media recording APIs are now available.
App manifests gain timelineActivityTypes for custom event types, writability on objects and fields, and isDeprecated on variables. Logic functions can throw RetryableLogicFunctionError to trigger queue retry with configurable backoff.
⚠️ Breaking changes
- System record page layout (#23651) by @prastoin
SidePanelExpandTargetnow requires an opaqueexpand: () = voidcallback instead of a route descriptor; update any front component that registers a side-panel expand action. (#23965) by @FelixMalfait- Metadata label edits are now two distinct operations: rename changes the canonical value for all locales, translate sets a per-locale override; the previous single-path rename-only behavior is gone. (#24374) by @FelixMalfait
LogicFunctionExecutionContextnow includesworkspaceId,workspaceSubdomain, triggering entity info, and retry counts;CoreApiClientrequires{ runAs: 'workspace' | 'application' }at construction — update every handler and client instantiation. (#24493) by @FelixMalfait
🌟 Highlights
CoreApiClientnow requires{ runAs: 'workspace' | 'application' }at construction andLogicFunctionExecutionContextgains workspace and trigger context — update every handler and client instantiation before upgrading. (#24493)SidePanelExpandTargetnow takes an opaqueexpand: () = voidcallback instead of a route descriptor — front components implementing the side-panel expand action must update. (#23965)- Front components can now call
localStorageandsessionStorage; both are backed by the host page and scoped per-app and per-user, eliminating crashes from storage-dependent libraries in sandboxed workers. (#23761) - Declare
frontComponentSharedDependenciesin package.json to build one shared bundle across all front components, dropping per-component size from ~190KB to ~1.6KB. (#23773) - Add
timelineActivityTypesto your app manifest to declare custom timeline event types with their own renderers, emitters, i18n, and settings integration. (#24620) - Throw
RetryableLogicFunctionError(exported fromtwenty-sdk/logic-function) to classify a logic function failure as transient and trigger queue retry with fixed or exponential backoff. (#24317)
✨ New features
- Front components can now call
window.localStorageandwindow.sessionStorage; both are backed by the host page and scoped per-app and per-user, so storage-dependent dependencies no longer crash in sandboxed workers. (#23761) by @bosiraphael - Add
frontComponentSharedDependencies: ['react', 'react-dom/client']to package.json;twenty-sdk buildcompiles one shared bundle and each front component loads from it instead of bundling its own copy. (#23773) by @bosiraphael - Mark a
serverVariablesentry withisDeprecated: trueto display a Deprecated pill in settings and preserve the stored value while you migrate callers to a replacement variable. (#23868) by @bosiraphael - Front components can now call
navigator.mediaDevices.getUserMediaand construct aMediaRecorderdirectly for audio and video capture using standard web platform APIs. (#24203) by @FelixMalfait - Add optional
writability?: MetadataWritabilityto object and field manifest definitions to restrict editing toAPPLICATIONorSYSTEMlevel; omitting it preserves the defaultOPENbehavior. (#24255) by @abdulrahmancodes - Throw
RetryableLogicFunctionError(exported fromtwenty-sdk/logic-function) to signal a transient failure; configurefixedBackofforexponentialBackoffon the job to control queue retry behavior. (#24317) by @ehconitin - Add
httpMethods: ['GET', 'POST']toserverRouteTriggerSettingsto accept GET requests (e.g. webhook verification challenges); undeclared methods return 405 instead of falling through to the SPA. (#24401) by @emmanuelhb56 - Add
timelineActivityTypesto your app manifest to declare custom timeline event types with renderers, emitters, i18n, and settings controls; messages, notes, tasks, and custom objects share the same model. (#24620) by @FelixMalfait - Add
headerCommandMenuItemUniversalIdentifiersto a widget's front-component configuration to render declared command-menu items as icon buttons in the widget header. (#24688) by @FelixMalfait - Use the new
enqueueJobsmutation to enqueue up to 200 payloads for one logic function in a single call;enqueueJobis deprecated and will be removed in a future release. (#24691) by @martmull
💅 Improvements & UX
- App catalogs and the front-component worker now both use message IDs at runtime; the readable-key format is removed from the worker's catalog lookup path. (#24325) by @FelixMalfait
- Use
{placeholder}syntax for variable substitution in manifest labels;${expression}template-style syntax is no longer supported and was never extracted for translation. (#24326) by @FelixMalfait - Manifest strings appearing in multiple metadata roles now produce separate catalog entries keyed by role, enabling distinct translations in gendered or case-marked languages. (#24360) by @FelixMalfait
timelineActivity.nameis deprecated in favor of atimelineActivityTypeid; in 2.33 new code reads the type first and falls back to name, so existing apps continue to work without immediate changes. (#24568) by @FelixMalfait- The SDK manifest build now validates timeline activity type names for uniqueness, resolves custom renderer references against declared front components, and checks emitter targets and relation fields before sync. (#24661) by @FelixMalfait
- The
CoreApiClientstub now declaresconstructor(options: ClientOptions & { runAs }), sonew CoreApiClient({ runAs: 'application' })passesyarn typecheckwithout a cast. (#24671) by @abdulrahmancodes
🐛 Bug fixes
- Running
twenty applyortwenty devwithout atranslationsblock no longer wipes stored locale data for published apps; dev-once sync now treatstranslations: undefinedas a no-op. (#24408) by @FelixMalfait - The dev sync now queues exactly one follow-up run when file changes arrive during an active sync, instead of dropping changes or stacking redundant pipeline runs. (#24514) by @FelixMalfait
🔧 Developer & API
- Packages bumped to 2.31.0-alpha.1 as an intermediate prerelease; scaffolded apps pin to create-twenty-app's own version and pick this up automatically. (#24011) by @prastoin
- Alpha suffix removed; packages returned to a stable version string. (#24059) by @prastoin
🏗️ Internal changes (16)
- Allow going back to the previous onboarding step (#23716) by @bosiraphael
- Add native call recording transcript tab to the calendar event record page (#23909) by @ehconitin
- Enrich the onboarding chat kickoff with person and workspace context (#23970) by @bosiraphael
- feat(billing): replace the credit balance column with a credit grant ledger (#23973) by @FelixMalfait
- perf(server): remove the compact-storage flag, slice cache demotion, use a plain LIMIT on find-many (#23980) by @charlesBochet
- feat(server): ORM v2, a TypeORM-free workspace read path behind a flag (#23991) by @charlesBochet
- Send file attachments when answering an AI chat question (#24017) by @bosiraphael
- Interface scale preference via root CSS zoom (#24209) by @FelixMalfait
- refactor(i18n) - share the message-id hash and the translatable registry [1/6] (#24300) by @FelixMalfait
- fix(i18n): translate page layout names (#24315) by @FelixMalfait
- Move in-product explainer videos from feature flagged to GA (#24337) by @Bredo
- feat(workflow): add core-backed workflows index page behind a flag (#24350) by @thomtrp
- Reduce non-AI Sentry trace sampling (#24511) by @bosiraphael
- messaging: Allow sending outbound mail from a verified account alias (#24560) by @neo773
- Manage timeline activity types in application settings (#24662) by @FelixMalfait
- Remove IS_ORM_V2_READ_PATH_ENABLED and collapse to the ORM v2 path (#24692) by @charlesBochet
🎉 New contributors
- @DebadityaHait made their first contribution in #23945
- @unchainedio made their first contribution in #23976
- @atharv-sys32 made their first contribution in #23320
- @brunobuddy made their first contribution in #23695
- @pwntr made their first contribution in #24091
- @anamikasingh200 made their first contribution in #24250
- @jihadMo made their first contribution in #24380
- @caveman99 made their first contribution in #24523
Full changelog (45 PRs)
- System record page layout (#23651) by @prastoin
- Allow going back to the previous onboarding step (#23716) by @bosiraphael
- Make localStorage and sessionStorage work in app front components (#23761) by @bosiraphael
- Share front component dependencies through a per-app bundle (#23773) by @bosiraphael
- Add a deprecated attribute to app manifest variables (#23868) by @bosiraphael
- Add native call recording transcript tab to the calendar event record page (#23909) by @ehconitin
- feat(front): expand button and record actions in the side panel footer (#23965) by @FelixMalfait
- chore: bump version to 2.31.0 (#23967) by @twenty-pr
- Enrich the onboarding chat kickoff with person and workspace context (#23970) by @bosiraphael
- feat(billing): replace the credit balance column with a credit grant ledger (#23973) by @FelixMalfait
- perf(server): remove the compact-storage flag, slice cache demotion, use a plain LIMIT on find-many (#23980) by @charlesBochet
- feat(server): ORM v2, a TypeORM-free workspace read path behind a flag (#23991) by @charlesBochet
- chore: set npm packages to 2.31.0-alpha.1 (#24011) by @prastoin
- Send file attachments when answering an AI chat question (#24017) by @bosiraphael
- Remove alpha sufix to npm packages (#24059) by @prastoin
- chore: bump version to 2.32.0 (#24061) by @twenty-pr
- App media recording via standard web API polyfills (compare with #24053) (#24203) by @FelixMalfait
- Interface scale preference via root CSS zoom (#24209) by @FelixMalfait
- feat(sdk): let apps set writability on objects and fields (#24255) by @abdulrahmancodes
- refactor(i18n) - share the message-id hash and the translatable registry [1/6] (#24300) by @FelixMalfait
- fix(i18n): translate page layout names (#24315) by @FelixMalfait
- Add retryable logic function failures with queue backoff (#24317) by @ehconitin
- chore: bump version to 2.33.0 (#24319) by @thomtrp
- refactor(i18n): one runtime key space for translation catalogs (#24325) by @FelixMalfait
- refactor(i18n): one placeholder syntax for every derived label (#24326) by @FelixMalfait
- Move in-product explainer videos from feature flagged to GA (#24337) by @Bredo
- feat(workflow): add core-backed workflows index page behind a flag (#24350) by @thomtrp
- refactor(i18n): key metadata catalog entries per role with message context (#24360) by @FelixMalfait
- Edit metadata translations in the UI: per-entity side panel + translate-or-rename prompt (#24374) by @FelixMalfait
- Let a server route declare which HTTP methods it answers (#24401) by @emmanuelhb56
- Stop a manifest without translations from deleting an application's stored locales (#24408) by @FelixMalfait
- feat(logic-function): give handlers an execution context, and a choice of whose access each call uses (#24493) by @FelixMalfait
- Reduce non-AI Sentry trace sampling (#24511) by @bosiraphael
- fix(sdk): rerun dev sync when changes arrive during sync (#24514) by @FelixMalfait
- messaging: Allow sending outbound mail from a verified account alias (#24560) by @neo773
- Replace timelineActivity.name with a timelineActivityType id (#24568) by @FelixMalfait
- chore: bump version to 2.34.0 (#24609) by @twenty-pr
- Make timeline activity types a generic application contract (#24620) by @FelixMalfait
- chore: bump version to 2.35.0 (#24651) by @twenty-pr
- Validate timeline activity manifest references locally (#24661) by @FelixMalfait
- Manage timeline activity types in application settings (#24662) by @FelixMalfait
- fix(client-sdk): accept generated client options in the CoreApiClient stub (#24671) by @abdulrahmancodes
- Allow custom widgets to declare header command items (#24688) by @FelixMalfait
- Deprecate enqueueJob in favor of enqueueJobs batch mutation (#24691) by @martmull
- Remove IS_ORM_V2_READ_PATH_ENABLED and collapse to the ORM v2 path (#24692) by @charlesBochet
Full Changelog: sdk/v2.30.0...sdk/v2.35.0