From ember-claude-skills
The 2.18 LTS → 3.28 LTS migration path — the LTS-by-LTS sequence, ember-cli-update, the deprecation workflow, jQuery removal, the test API conversion, and the addon survival list. Use when planning, scoping, or executing a 2.x upgrade. Hands off to the ember-3-migrator agent once you reach 3.28.
How this skill is triggered — by the user, by Claude, or both
Slash command
/ember-claude-skills:ember-2-to-3-migrationThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
The fastest, safest path from Ember 2.x is to walk the LTS chain. Each LTS is a stable target; each hop fixes the deprecations the next hop expects to be gone.
The fastest, safest path from Ember 2.x is to walk the LTS chain. Each LTS is a stable target; each hop fixes the deprecations the next hop expects to be gone.
2.18 LTS ─┐
├→ 3.4 LTS ─┐
├→ 3.8 LTS ─┐
├→ 3.12 LTS ─┐
├→ 3.16 LTS ─┐
├→ 3.20 LTS ─┐
├→ 3.24 LTS ─┐
├→ 3.28 LTS
(last 3.x)
You do not jump directly. The shortest path that works in practice is 2.18 → 3.4 → 3.8 → 3.12 → 3.16 → 3.20 → 3.24 → 3.28. Each hop is one or two days of work for a typical mid-size app; it can be many weeks for a 2014-era monolith.
Once at 3.28, hand off to the ember-3-migrator agent (and the ember-3-octane-adoption / ember-3-to-4-migration skills) to plan 3 → 4.
ember-cli-updateember-cli-update regenerates the project files for a target Ember/CLI version, then asks you to merge the diff. It's the single best leverage point in the upgrade.
# install once
pnpm add -D ember-cli-update
# bump to a target version
pnpm exec ember-cli-update --to 3.4
# resolve the conflicts it surfaces, then:
pnpm exec ember-cli-update --run-codemods
Codemods you'll meet:
| Codemod | Purpose |
|---|---|
ember-modules-codemod | Ember.Component → import Component from '@ember/component' (and the rest of the Ember.X namespace explosion). |
ember-test-helpers-codemod | 2.x global helpers → await visit(...) style. |
ember-no-implicit-this-codemod | {{foo}} (when foo is a class field) → {{this.foo}}. |
ember-angle-brackets-codemod | {{user-card}} → <UserCard>. |
ember-on-modifier-codemod | {{action "x"}} on elements → {{on "click" this.x}}. |
ember-tracked-properties-codemod | computed → @tracked (run during the Octane phase). |
Codemods are helpers, not magic. Always review the diff and run tests.
The repeated pattern at every hop:
1. Update ember-source, ember-cli, ember-data to the next LTS.
2. Boot the app, watch the console.
3. For every deprecation message:
a. Find the offending line via the stack.
b. Either fix it or stash it via ember-cli-deprecation-workflow.
4. Run the test suite. Fix breakage.
5. Smoke-test the top user flows manually.
6. Commit per-deprecation when reasonable, so the diff is reviewable.
7. Move to the next LTS.
Use ember-cli-deprecation-workflow to silence deprecations you don't have time to fix yet:
// config/deprecation-workflow.js
self.deprecationWorkflow = self.deprecationWorkflow || {};
self.deprecationWorkflow.config = {
workflow: [
{ handler: 'silence', matchId: 'ember-component.send-action' },
{ handler: 'silence', matchId: 'ember-views.curly-components.jquery-element' }
]
};
This unblocks the hop without committing to fixing every deprecation in the same week. Track silenced deprecations in an issue and burn them down later.
This is the deepest hop because it crosses the major version line. The rest are easier.
What changes:
Ember.X global access starts emitting deprecations everywhere → run ember-modules-codemod.ember-cli configuration changes (ember-cli-build.js shape, addon hooks).bower.json must move to npm.ember-data 3.x requires explicit relationship inverses to be set if you customize them.ember-qunit@^4 adds the new style alongside.What to watch:
Ember.$ and this.$(), but it's not removed yet.(action "save" post)) replace sendAction everywhere.componentName.toString() deprecations._super chain warnings.RouterDSL (e.g. nested route paths must not start with /).@glimmer/component, @tracked, modifiers, native classes, decorators are all stable but optional. Don't adopt yet — finish the deprecation pass first.@ember/optional-features). You can disable it now — many tests will need updating from this.$() to find().pnpm exec ember feature:disable jquery-integration
Ember.run namespace deprecations: rename to @ember/runloop imports.Ember.String extensions ('foo'.camelize() etc.) — import explicitly from @ember/string.tagless components emit clearer deprecations.The final 3.x. 3.28 LTS is the canonical "stop here, take stock, plan the 4.x jump" station.
What to do at 3.28:
Ember.* global access is gone (or silenced).module + setupApplicationTest + await).config/optional-features.json:
{
"application-template-wrapper": false,
"default-async-observers": true,
"jquery-integration": false,
"template-only-glimmer-components": true
}
@glimmer/component — usually the leaf components first.This is a great moment to add CI gates: error on new deprecations, fail on new Ember.* imports, lint rules against extend()-style classes.
jQuery removal cuts across templates, components, and tests. A practical order:
this.$(...) with find(...), findAll(...), assert.dom(...). Smaller blast radius.didInsertElement(){ this.$('.x').focus(); } → modifier ({{auto-focus}}).Ember.$.ajax(...) → fetch or ember-fetch. Keep response shape identical to avoid serializer changes.Disable the integration with ember feature:disable jquery-integration only after the four steps above are done. If you turn it off prematurely, every render will break loudly.
ember-data 2.x → 3.x → 3.28 is a parallel track:
DS.Model.extend({...}) still works in 3.x but begins emitting deprecations late in 3.x.@belongsTo/@hasMany to specify inverse: 'fieldName' at every site.import DS from 'ember-data' is gradually replaced by import Model, { attr, belongsTo, hasMany } from '@ember-data/model'.RESTSerializer/JSONAPISerializer defaults stayed stable; don't rewrite them mid-migration.Common 2.x addons and their fate:
| Addon | Status | Action |
|---|---|---|
ember-cli-mirage | Alive, well-maintained. | Keep. |
ember-power-select | Alive. | Bump to current major. |
ember-cli-page-object | Alive. | Keep. |
ember-test-selectors | Alive. | Keep. |
ember-cli-deprecation-workflow | Alive. | Use it during the migration, remove after 3.28. |
ember-truth-helpers | Alive (now @ember/truth-helpers in 5+). | Keep, rename later. |
ember-svg-jar | Alive. | Keep. |
ember-i18n | Replaced by ember-intl. | Migrate translations. |
ember-data-table-of-the-week (any 2.x table addon) | Almost certainly dead. | Replace with a hand-rolled table component or a current addon. |
liquid-fire | Lower maintenance. | If used heavily, evaluate ember-animated; otherwise delete. |
Any addon last released > 4 years ago and used in < 3 files | Inline the code or replace. | Don't try to upgrade an abandoned addon. |
Run pnpm exec ember-cli-update --addons (in newer versions of the tool) to surface addons that block the bump.
Before each hop:
If your suite is thin, the first investment is more tests, not the upgrade. Migrating a flaky test suite is worse than not migrating.
| Hop | Calendar days | Notes |
|---|---|---|
| 2.18 → 3.4 | 5–10 | Heaviest. Ember.X rewrite + bower removal. |
| 3.4 → 3.8 | 1–3 | Mostly deprecation cleanup. |
| 3.8 → 3.12 | 2–5 | jQuery starts coming out. Optional, but worth it. |
| 3.12 → 3.16 | 1–3 | Run-loop and string-extension imports. |
| 3.16 → 3.20 | 1–2 | Quiet hop. |
| 3.20 → 3.24 | 1–2 | Quiet hop. |
| 3.24 → 3.28 | 2–5 | Set up Octane optional features; convert leaf components. |
| Total | ~3–5 calendar weeks | For an experienced engineer working full-time. |
Add a multiplier for:
ember-source is ~3.28.x.ember-cli-update reports no pending diffs for 3.28.Ember.X direct imports have been replaced or silenced.jquery-integration optional feature is false.module + setupApplicationTest); andThen is gone.ember-cli-deprecation-workflow.js is empty or has only well-known, owner-assigned silences.config/optional-features.json.pnpm test is green; CI is green.When the box is fully checked, switch to the ember-3-to-4-migration skill.
ember-2-recommendations — surviving while you plan.ember-3-to-4-migration — the next hop.ember-cli-update.npx claudepluginhub artemgurzhii/ember-claude-skills --plugin ember-claude-skillsProvides CDSS development patterns for drug interaction checking, dose validation, clinical scoring (NEWS2, qSOFA), and alert classification integrated into EMR workflows.