Skip to content

feat(ember)!: Update to v2 addon format#19229

Open
aklkv wants to merge 2 commits into
getsentry:developfrom
aklkv:feat/ember-v2-format
Open

feat(ember)!: Update to v2 addon format#19229
aklkv wants to merge 2 commits into
getsentry:developfrom
aklkv:feat/ember-v2-format

Conversation

@aklkv
Copy link
Copy Markdown

@aklkv aklkv commented Feb 8, 2026

Before submitting a pull request, please take a look at our
Contributing guidelines and verify:

  • If you've added code that should be tested, please add tests.
  • Ensure your code lints and the test suite passes (yarn lint) & (yarn test).
  • Link an issue if there is one related to your pull request. If no issue is linked, one will be auto-generated and linked.

Summary

Migrates @sentry/ember from the legacy v1 addon format to the Ember v2 addon format. This modernizes the package to work with both classic Ember builds and Embroider-optimized builds, and removes the runtime dependency on @embroider/macros.

Changes

  • Build system: Replaced ember-cli build pipeline with rollup (transpilation → dist/) + tsc (declarations → declarations/)
  • Addon entry: Added addon-main.cjs using @embroider/addon-shim as the addon entry point
  • Package.json: Set ember-addon.version: 2, updated exports map, added ember-addon.app-js mapping
  • Config format: Replaced @embroider/macros getOwnConfig() with explicit Sentry.init() calls and a new setupPerformance() export

API changes:

  • init() is now called directly in app.ts or an initializer (no more ENV['@sentry/ember'] config)
  • setupPerformance() must be called from an instance-initializer to opt into performance instrumentation
  • Initial load instrumentation requires manual <script> tags in index.html
  • Added UPGRADE.md with detailed migration guide

Test & CI updates:

  • All 21 unit tests passing (acceptance tests for errors, performance, and replay)
  • Updated e2e test apps (ember-classic, ember-embroider) to use v2 patterns:
    • Added instance-initializers for performance setup
    • Migrated config from ENV['@sentry/ember'] to Sentry.init() in app.ts
    • Added initial load <script> tags to index.html
  • Updated .github/workflows/build.yml CACHED_BUILD_PATHS from packages/ember/*.d.ts to packages/ember/dist + packages/ember/declarations

TypeScript fixes:

  • Added "types": ["ember-source/types"] to tsconfig.publish.json for Ember module resolution during declaration generation
  • Fixed transition type imports (removed non-existent @ember/routing/-private/transition)
  • Simplified instrumentFunction generic to avoid tuple mismatch errors

Breaking Changes

  • ENV['@sentry/ember'] config in config/environment.js is no longer supported — use Sentry.init() directly
  • Performance instrumentation is no longer automatic — call setupPerformance() from an instance-initializer
  • Initial load tracking requires manual <script> tags in app/index.html

Closes JS-217

@aklkv aklkv marked this pull request as ready for review February 8, 2026 09:40
@aklkv aklkv force-pushed the feat/ember-v2-format branch 3 times, most recently from 53dd617 to 822ed0a Compare February 8, 2026 11:01
Copy link
Copy Markdown
Member

@nicohrubec nicohrubec left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey, thanks for contributing. A few notes:

  1. This PR is way too large. Please split it up into smaller pieces so we can review it properly.
  2. Is there a way to get this done without introducing breaking changes? If no, then we need to wait with this until our next major.

@aklkv
Copy link
Copy Markdown
Author

aklkv commented Feb 9, 2026

Hey, thanks for contributing. A few notes:

  1. This PR is way too large. Please split it up into smaller pieces so we can review it properly.
  2. Is there a way to get this done without introducing breaking changes? If no, then we need to wait with this until our next major.

Hi @nicohrubec, thanks for the feedback!

I understand the concern about PR size. Unfortunately, the v1 → v2 addon migration is an atomic change — you can't incrementally migrate between formats. The build pipeline, entry point structure, and package.json layout must change together for the addon to function.

That said, the core SDK functionality is unchanged — the same instrumentation, error handling, and performance tracking code. The changes fall into two categories:

  1. Consumer-facing setup — how users configure the SDK (direct Sentry.init() calls instead of ENV['@sentry/ember'])
  2. Build/packaging scaffolding — the surrounding v2 addon infrastructure (Rollup config, addon-main.cjs, exports map, etc.)

The actual instrumentation logic in src/ is largely untouched. So while the diff is large, most of it is build tooling and test app updates to match the new setup pattern — not changes to Sentry functionality itself.

I'm happy to:

  • Add a review guide in the PR description highlighting which files contain meaningful changes vs. scaffolding
  • Split into multiple logical commits (build system, config API, test updates) to make review easier

Regarding breaking changes — the v2 format requires explicit Sentry.init() calls, so this would need to target the next major release.

Let me know how you'd like to proceed!

@aklkv aklkv force-pushed the feat/ember-v2-format branch from 822ed0a to 4874c99 Compare February 9, 2026 12:25
Comment thread packages/ember/src/index.ts Outdated
@johanrd
Copy link
Copy Markdown

johanrd commented Feb 9, 2026

@aklkv thanks a lot for doing this!🙏

FWIW: While waiting for this, I realized I didn't use the performance part of the addon, and was able to just use the @sentry/browser package without the need of any ember specific addon at all.

That also means that the 'breaking change' mentioned in the PR is a very welcome change to reduce the scope of what is delegated to the 'ember' part of the addon. Most is now just handled by the core apis, which it how it should be👍

(the link to Ember v2 addon format is broken in the pr description, btw)

Copy link
Copy Markdown

@NullVoxPopuli NullVoxPopuli left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a good PR.

I understand the maintainer's perspective of wanting it split up tho.

The only way to do so would be rearranging the monorepo a bit to make a separate test app package.

This would mean the goal of that PR is to just delete the dummy app from the existing v1 addon.

That will still be a large pr, and i don't really see a way to get better than 2 large prs for this needed work.

Maintainers,
You mentioned breaking change timing - i suspect that is because all packages in this repo are released at once?

May i introduce you to https://github.com/release-plan/release-plan ?
It allows each package to be published independently with correct semver inference based on changes in git (and labels assessing impact on a pr) it helps a lot!

Comment thread dev-packages/e2e-tests/test-applications/ember-classic/app/index.html Outdated
Comment thread packages/ember/addon/runloop.d.ts Outdated
Comment thread packages/ember/demo-app/routes/with-loading/index.ts
Comment thread packages/ember/src/index.ts Outdated
Comment thread packages/ember/UPGRADE.md
@aklkv aklkv force-pushed the feat/ember-v2-format branch from 4874c99 to 34b116c Compare February 9, 2026 22:18
Comment thread packages/ember/package.json Outdated
@aklkv aklkv force-pushed the feat/ember-v2-format branch from 34b116c to 3f38914 Compare February 9, 2026 22:56
Comment thread packages/ember/src/performance.ts Outdated
Comment thread packages/ember/tests/helpers/utils.ts Outdated
@aklkv aklkv force-pushed the feat/ember-v2-format branch from 3f38914 to a52e388 Compare February 10, 2026 03:30
Comment thread packages/ember/src/performance.ts Outdated
Comment thread packages/ember/src/performance.ts Outdated
@aklkv aklkv force-pushed the feat/ember-v2-format branch from a52e388 to c99ff39 Compare February 10, 2026 06:57
Comment thread packages/ember/src/utils/sentry/setup-performance.ts Outdated
Comment thread packages/ember/src/types.ts Outdated
Comment thread packages/ember/src/types.ts Outdated
@aklkv aklkv force-pushed the feat/ember-v2-format branch from c99ff39 to e2a465d Compare February 10, 2026 10:32
Comment thread packages/ember/src/utils/sentry/setup-performance.ts Outdated
@aklkv aklkv force-pushed the feat/ember-v2-format branch from e2a465d to 1f697a9 Compare February 10, 2026 11:06
Comment thread packages/ember/src/performance.ts Outdated
@aklkv aklkv force-pushed the feat/ember-v2-format branch from 1f697a9 to 5884677 Compare February 10, 2026 11:23
@ijlee2
Copy link
Copy Markdown

ijlee2 commented Feb 10, 2026

I left my review and suggestions for this pull request in aklkv#1.

Here's my message to @aklkv on Ember Discord:

Overall, nice job. I only checked the source code, not the files or configuration for demo-app or tests.

I think it'd help users of @sentry/ember if the only import path that they need to know is the barrel file, and help reviewers of your PR if you split the source code into multiple files. The latter has the benefit of improving the maintainability for the future.

I saw that you pushed a new commit after I was about to open my PR. It's possible that I missed something from your new commit while fixing the merge conflicts.

@aklkv
Copy link
Copy Markdown
Author

aklkv commented Feb 10, 2026

I left my review and suggestions for this pull request in aklkv#1.

@ijlee2 this is great 💚 would you mind rebasing pleas, I would be happy integrating this changes

Comment thread packages/ember/src/index.ts Outdated
@ijlee2
Copy link
Copy Markdown

ijlee2 commented Feb 10, 2026

I left my review and suggestions for this pull request in aklkv#1.

@ijlee2 this is great 💚 would you mind rebasing pleas, I would be happy integrating this changes

@aklkv Done rebasing.

@aklkv aklkv force-pushed the feat/ember-v2-format branch 2 times, most recently from 7cbad07 to 03d2cd6 Compare February 10, 2026 12:19
@nicohrubec nicohrubec removed their request for review April 21, 2026 07:13
import type ApplicationInstance from '@ember/application/instance';
import { setupPerformance } from '@sentry/ember';

export function initialize(appInstance: ApplicationInstance): void {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey, I am taking another look over this as we are getting closer to planning the next major, where this could go in.

Ideally, we'd align this more closely with how we handle sentry init in other places as well - which would be, to keep things centralized in Sentry.init(). Is there a way we can make this work reliably? I am thinking of something like this:

// app.ts
export default class App extends Application {
  modulePrefix = config.modulePrefix;
  podModulePrefix = config.podModulePrefix;
  Resolver = Resolver;
}

Sentry.init({
  // ...
  integrations: [
    Sentry.browserTracingIntegration({ emberApp: App })
  ]
});

and somehow derive/wrap the necessary thing inside of this? That would be the ideal solution IMHO, or something along these lines. then we can also get rid of all the async import and special options for performance etc. and just pass this directly to the (ember-specific) browser tracing integration 🤔

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or alternatively, if this cannot be made to work nicely, we could also do this in the initializer, which would be more "sentry native":

import * as Sentry from '@sentry/ember';

export function initialize(appInstance) {
  Sentry.addIntegration(Sentry.browserTracingIntegration({ 
    appInstance,
    // other options here
  }); 
}

this would possibly loose tiny bits of timing info but should overall be likely OK...

Then, we need to export a custom browserTracingIntegration from the ember package here, similar to e.g. the vue browserTracingIntegration, where we can run the actual logic.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will look into PRing into this PR some changes for this!

<meta name="description" content="" />
<meta name="viewport" content="width=device-width, initial-scale=1" />

<script>if(window.performance&&window.performance.mark){window.performance.mark('@sentry/ember:initial-load-start');}</script>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

honestly if we are doing such a big refactor I'd just drop this stuff as built-in functionality - you can build this yourself if needed but likely for simplicity this can go away.

@mydea mydea changed the title feat(ember): v2 feat(ember)!: Update to v2 addon format May 6, 2026
@aklkv
Copy link
Copy Markdown
Author

aklkv commented May 6, 2026

@mydea thank you for looking at this PR, I will circle back closer to the end of the week

@mydea
Copy link
Copy Markdown
Member

mydea commented May 6, 2026

Kind-of extracted/refactored some of this out into a PR that is backwards compatible: #20702

once this is merged, I'll change this PR to use this instead, which should reduce the noise in this specific PR and keep things to a minimum. I'll also move the demo-app into a e2e test application, keeping to our general structure of things. then the ember package itself and the changes in this PR should be relatively reasonably small!

@aklkv aklkv force-pushed the feat/ember-v2-format branch from cc80587 to 1b8bf6b Compare May 9, 2026 22:36
@aklkv aklkv requested a review from a team as a code owner May 9, 2026 22:36
@aklkv aklkv force-pushed the feat/ember-v2-format branch from 3dd2872 to 8870fb2 Compare May 9, 2026 23:43
Comment thread packages/ember/src/utils/sentry/setup-performance.ts Outdated
@aklkv aklkv force-pushed the feat/ember-v2-format branch from 8870fb2 to 90b045f Compare May 9, 2026 23:47
@github-actions
Copy link
Copy Markdown
Contributor

👋 @getsentry/team-javascript-sdks-framework — Please review this PR when you get a chance!

mydea added a commit that referenced this pull request May 13, 2026
…Integration` (#20702)

Kind of extracted/inspired by
#19229, this
refactors the ember logic for performance monitoring to use the more
general pattern we already have in our code, delegating this fully into
an ember-specific `browserTracingIntegration`.

For now, this should not be breaking, as the auto-wiring etc. remains
the same - it just uses this integration under the hood instead of
manually calling stuff etc.

In a follow up, this should make it much easier to use this in a more
standalone fashion in the v2 addon.

I've split the logic into separate files as this was all a bit
convoluted together, hopefully this makes it a bit easier to follow what
belongs where etc.

This also generally aligns the ember package more with our own broader
way of handling things, which is also nice IMHO. If you add the
integration, you get everything set up, and if not, not - easy! :D

## Status quo

This is still being added automatically - this is what
`instance-initializers/sentry-performance.ts` does. that auto-runs and
adds the browser tracing integration so it has access to the ember app
instance, which we need to setup tracing stuff properly.

## Future (v11)

We'll no longer have the auto instance-initializer, but instead users
will have to manually add this. but this can be simplified then in their
app code to:

```js
import * as Sentry from '@sentry/ember';

export function initialize(appInstance) {
  Sentry.addIntegration(Sentry.browserTracingIntegration({ appInstance }));
}
```
@aklkv aklkv force-pushed the feat/ember-v2-format branch from 90b045f to 854f981 Compare May 13, 2026 21:48
Comment thread packages/ember/src/utils/sentry/setup-performance.ts Outdated
@aklkv aklkv force-pushed the feat/ember-v2-format branch 2 times, most recently from 5aff5c3 to 9d80849 Compare May 13, 2026 21:54
Comment thread packages/ember/src/utils/sentry/setup-performance.ts Outdated
Comment thread packages/ember/tests/helpers/setup-sentry.ts Outdated
@github-actions
Copy link
Copy Markdown
Contributor

👋 @getsentry/team-javascript-sdks-framework — Please review this PR when you get a chance!

@mydea
Copy link
Copy Markdown
Member

mydea commented May 18, 2026

Opened a PR here towards this branch with some adjustments: aklkv#2

fromRoute,
toRoute,
},
});
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Router mount flag never set

High Severity

The refactor checks routerService._hasMountedSentryPerformanceRouting to avoid double router instrumentation but never sets it to true after registering listeners (the v1 code did). Each browserTracingIntegration afterAllSetup run attaches duplicate routeWillChange/routeDidChange handlers, causing duplicated navigation/pageload transactions.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 44712d2. Configure here.

appInstance,
}),
);
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FastBoot guard removed

Medium Severity

The built-in instance initializer used to skip performance setup when service:fastboot isFastBoot is true. instrumentAppInstancePerformance has no equivalent guard, so SSR/FastBoot app instances can still register browser tracing and router listeners on the server despite UPGRADE.md claiming automatic FastBoot detection.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 44712d2. Configure here.

_initialized = true;
});
instrumentGlobalsForPerformance(globalsPerformanceConfig);
_initialized = true;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing macros runtime dependency

High Severity

browserTracingIntegration still imports @embroider/macros (isTesting, macroCondition), but v2 package.json no longer lists that package under dependencies and publish Babel config does not macro-strip it. Apps without @embroider/macros can fail at module load after upgrading.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 44712d2. Configure here.

Comment on lines 36 to 38
if (routerService._hasMountedSentryPerformanceRouting) {
// Routing listens to route changes on the main router, and should not be initialized multiple times per page.
return;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: The guard _hasMountedSentryPerformanceRouting in instrumentEmberAppInstanceForPerformance is never set, causing duplicate event listeners to be registered on multiple calls, especially in tests.
Severity: HIGH

Suggested Fix

After the guard check at line 36, add the statement routerService._hasMountedSentryPerformanceRouting = true;. This will ensure that the instrumentation logic and event listener registration only run once per routerService instance, as intended by the existing guard mechanism.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.

Location: packages/ember/src/utils/instrumentEmberAppInstanceForPerformance.ts#L36-L38

Potential issue: The function `instrumentEmberAppInstanceForPerformance` includes a
guard `if (routerService._hasMountedSentryPerformanceRouting)` to prevent
re-initialization. However, the flag `_hasMountedSentryPerformanceRouting` is never set
to `true` after the check. Consequently, every call to this function, such as during
Ember's instance-initializers in test environments, will re-register `'routeWillChange'`
and `'routeDidChange'` event listeners. This leads to the creation of duplicate spans
for each route change and corrupted transaction data being sent to Sentry, along with
performance degradation from the redundant instrumentation.

aklkv and others added 2 commits May 19, 2026 22:19
- Convert from v1 addon to v2 addon using rollup + @embroider/addon-dev
- Export ember-specific browserTracingIntegration (following Vue pattern)
- Drop initial load instrumentation (constants, scripts, _instrumentInitialLoad)
- Add UPGRADE.md migration guide
- Create ember-vite e2e test app (Vite + @embroider/vite)
- Update ember-classic and ember-embroider e2e apps to new API

Co-Authored-By: Claude <[email protected]>
* improvements for ember-v2

* remove addon files??

* remove config

fix version

* fix test app

* fixes and stuff

* moar fixes

* small ref

* rename to strict resolver

* add instrumentAppInstancePerformance

* fix ember-vite app

* fix type
@aklkv aklkv force-pushed the feat/ember-v2-format branch from 44712d2 to 52d4ffa Compare May 20, 2026 05:20
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

There are 6 total unresolved issues (including 4 from previous reviews).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 52d4ffa. Configure here.

startBrowserTracingPageLoadSpan: typeof startBrowserTracingPageLoadSpanType,
startBrowserTracingNavigationSpan: typeof startBrowserTracingNavigationSpanType,
): void {
const { disableRunloopPerformance, instrumentPageLoad, instrumentNavigation } = config;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wrong name on loading routes

Medium Severity

getCurrentScope().setTransactionName runs before transitionIsIntermediate returns, so intermediate loading/error transitions can overwrite the active transaction name (e.g. route:*.loading) used for errors captured during that transition.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 52d4ffa. Configure here.

Comment thread packages/ember/UPGRADE.md

### FastBoot / SSR

The performance instrumentation automatically detects FastBoot and disables client-side instrumentation during server rendering. No changes needed.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FastBoot guard removed

High Severity

The v1 instance initializer skipped performance setup when service:fastboot reported FastBoot; that guard was removed with no replacement in instrumentAppInstancePerformance, yet the upgrade guide still claims FastBoot is detected automatically.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 52d4ffa. Configure here.

Comment on lines +81 to +91
export function instrumentAppInstancePerformance(
appInstance: ApplicationInstance,
options?: Partial<Parameters<typeof browserTracingIntegration>[0]>,
): void {
addIntegration(
browserTracingIntegration({
...options,
appInstance,
}),
);
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: The guard _hasMountedSentryPerformanceRouting is checked but never set, allowing duplicate event listeners if instrumentEmberAppInstanceForPerformance is called multiple times.
Severity: MEDIUM

Suggested Fix

Set the _hasMountedSentryPerformanceRouting property on the router service to true within the instrumentEmberAppInstanceForPerformance function after the initial setup is complete. This will ensure the guard correctly prevents the function's logic from running more than once.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.

Location: packages/ember/src/utils/browserTracingIntegration.ts#L81-L91

Potential issue: The function `instrumentEmberAppInstanceForPerformance` includes a
check on the `_hasMountedSentryPerformanceRouting` property to prevent duplicate
initialization and the registration of multiple event listeners. However, this property
is never set to `true` anywhere in the codebase. As a result, this guard is ineffective.
If `instrumentEmberAppInstanceForPerformance` is invoked more than once through any code
path, it will lead to the registration of duplicate event listeners, potentially causing
performance issues or incorrect behavior.

@mydea
Copy link
Copy Markdown
Member

mydea commented May 20, 2026

There are a bunch of bot review comments, most of them seem reasonable/accurate to me to work through!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants