Skip to content

Drop isInteractive and hasDOM from the renderer -- declaring we only support "browser-like" environments with the current renderer#21348

Draft
NullVoxPopuli wants to merge 1 commit intomainfrom
nvp/drop-isinteractive
Draft

Drop isInteractive and hasDOM from the renderer -- declaring we only support "browser-like" environments with the current renderer#21348
NullVoxPopuli wants to merge 1 commit intomainfrom
nvp/drop-isinteractive

Conversation

@NullVoxPopuli
Copy link
Copy Markdown
Contributor

@NullVoxPopuli NullVoxPopuli commented Apr 30, 2026

RFC: emberjs/rfcs#1178

Drop isInteractive and hasDOM; remove FastBoot codepaths.

the limitations fastboot placed on us for SSR are no longer needed, I think we can drop this stuff in a non-major release (especially so since fastboot is not compatible with vite, and... i don't know if fastboot works with latest ember even in classic, tbh -- it also is built on private apis so while we normally don't care about private api breakage, the SSR use case is important enough that it'd be in bad taste to drop to 0 SSR solutions... which brings us to the next point)

vite-ember-ssr proves that we can not only render in interactive mode, but we can await settled() if we want until rendering is finished, which gives us a lot of flexibility, and frees us from having to maintain all this cruft.

@evoactivity made vite-ember-ssr (and it's awesome)

I have a demo of it here, running modifiers: https://limber.glimdown.com/docs/embedding

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 30, 2026

📊 Package size report   -0.37%↓

File Before (Size / Brotli) After (Size / Brotli)
Total (Includes all files) 5.4 MB / 1.3 MB -0.37%↓5.3 MB / -0.39%↓1.3 MB
Tarball size 1.2 MB -0.39%↓1.2 MB
Show files (21 files)
File Before (Size / Brotli) After (Size / Brotli)
dist/dev/packages/@ember/-internals/browser-environment/index.js 161 B / 121 B
dist/dev/packages/@ember/-internals/views/lib/system/event_dispatcher.js 10.4 kB / 2.6 kB -6.5%↓9.7 kB / -5.52%↓2.5 kB
dist/dev/packages/@ember/application/index.js 36.4 kB / 9 kB -0.31%↓36.3 kB / -0.11%↓9 kB
dist/dev/packages/@ember/application/instance.js 15.9 kB / 4.4 kB -19.3%↓12.8 kB / -17.9%↓3.6 kB
dist/dev/packages/@ember/debug/index.js 6.8 kB / 1.7 kB 2%↑6.9 kB / 2%↑1.7 kB
dist/dev/packages/shared-chunks/index-BUPd6pkm.js 199.2 kB / 43.7 kB -1.37%↓196.4 kB / -1.08%↓43.2 kB
dist/dev/packages/shared-chunks/render-DX-LNqEQ.js 38.4 kB / 8.4 kB -0.46%↓38.2 kB / -0.44%↓8.3 kB
dist/prod/packages/@ember/-internals/browser-environment/index.js 222 B / 119 B
dist/prod/packages/@ember/application/index.js 32.9 kB / 8.5 kB -0.35%↓32.8 kB / -0.59%↓8.4 kB
dist/prod/packages/@ember/application/instance.js 14.8 kB / 4.1 kB -21%↓11.7 kB / -19.5%↓3.3 kB
dist/prod/packages/shared-chunks/has-dom-DdQORPzI.js 601 B / 191 B
dist/prod/packages/shared-chunks/index-BqTKF5sS.js 172 kB / 38.5 kB -65.4%↓59.5 kB / -68.7%↓12 kB
dist/prod/packages/shared-chunks/render-vnNWJGYe.js 36.2 kB / 7.9 kB -0.49%↓36 kB / -0.42%↓7.9 kB
package.json 22.6 kB / 3.4 kB -0.53%↓22.5 kB / -0.44%↓3.4 kB
types/stable/@ember/-internals/browser-environment/index.d.ts 406 B / 168 B
types/stable/@ember/-internals/browser-environment/lib/has-dom.d.ts 128 B / 94 B
types/stable/@ember/-internals/glimmer/lib/environment.d.ts 477 B / 204 B -40.9%↓282 B / -19.1%↓165 B
types/stable/@ember/-internals/glimmer/lib/renderer.d.ts 9.1 kB / 2.1 kB -6.59%↓8.5 kB / -3.95%↓2 kB
types/stable/@ember/application/instance.d.ts 11.3 kB / 3 kB -19.7%↓9.1 kB / -18.5%↓2.4 kB
types/stable/@glimmer/runtime/lib/environment.d.ts 2.8 kB / 669 B -8.83%↓2.6 kB / -3.29%↓647 B
types/stable/index.d.ts 43 kB / 4 kB -0.37%↓42.8 kB / -0.53%↓4 kB

🤖 This report was automatically generated by pkg-size-action

@NullVoxPopuli NullVoxPopuli force-pushed the nvp/drop-isinteractive branch from 529ce25 to f4be99d Compare April 30, 2026 02:11
@NullVoxPopuli NullVoxPopuli changed the title Drop isInteractive from the renderer Drop isInteractive and hasDOM from the renderer -- declaring we only support "browser-like" environments with the current renderer Apr 30, 2026
@kategengler
Copy link
Copy Markdown
Member

fastboot was never formally supported
I don't believe this is true.

Fastboot, if it doesn't work in classic in v7, could be made to work with clean up of deprecations. I think this would be a breaking change.

@NullVoxPopuli
Copy link
Copy Markdown
Contributor Author

thanks, updated the verbiage.

I'm also willing to backport a deprecation to 6.10

@kategengler
Copy link
Copy Markdown
Member

Discussed in discord but putting here for the world:

I'm also willing to backport a deprecation to 6.10

We don't backport deprecations. That defeats the purpose of having a cutoff for when new deprecations are introduced as well as opens the possibility that someone already on 6.10 or higher would suddenly upgrade to 7 and see breakage without ever seeing a deprecation.

Since we always have a DOM and modifiers always run, the entire
isInteractive/hasDOM split is dead weight. Tear it out.

Glimmer-vm:
- @glimmer/runtime/lib/environment.ts: drop the isInteractive field on
  EnvironmentImpl and EnvironmentDelegate. scheduleInstallModifier and
  scheduleUpdateModifier always schedule.
- @glimmer/runtime/lib/compiled/opcodes/dom.ts: drop the early-returns
  in VM_MODIFIER_OP and VM_DYNAMIC_MODIFIER_OP. Modifiers always run.
- @glimmer/interfaces: drop isInteractive from the Environment interface.

Ember component layer:
- curly + root component managers: lifecycle hooks (willRender,
  willInsertElement, didInsertElement, willUpdate, didUpdate, didRender,
  willDestroyElement, willClearRender) always fire.
- ComponentStateBucket no longer carries isInteractive.
- BootEnvironment loses both fields.

Renderer:
- BaseRenderer / Renderer / renderComponent no longer take isInteractive
  or hasDOM env config.
- Renderer.getElement always returns the element (no more "not allowed in
  non-interactive environments" throw).
- Renderer.remove always triggers didDestroyElement.
- Drop the _isInteractive getter and the debug.isInteractive field.
- EmberEnvironmentDelegate has no constructor args.

Application/engine boot:
- BootOptions drops isInteractive and isBrowser.
- _BootOptions no longer threads isInteractive through isBrowser /
  shouldRender / option override; just _renderMode, location,
  shouldRender, document, rootElement.
- ApplicationInstance always calls setupEventDispatcher.
- EngineInstance's singleton list always includes event_dispatcher:main.
- EventDispatcher.setup drops the "should never be setup in fastboot"
  assertion.
- @ember/-internals/views/lib/system/event_dispatcher.ts no longer
  imports from @ember/-internals/glimmer.

Component:
- The DEBUG tagless event-handler check no longer needs renderer._isInteractive.
- _dispatcher always looks up event_dispatcher:main.
- appendTo always uses document.querySelector for string selectors;
  the "no DOM" branch is gone. matches() drops its fastboot guard.

@ember/-internals/browser-environment package: deleted entirely.
- isChrome/isFirefox were the only remaining consumers (in @ember/debug);
  inlined there with `typeof window !== 'undefined'` guards.
- self/location/history/window references were the only hasDOM users.
- Removed from @ember/-internals package exports, root package.json
  embedded-package map, types/stable manifest, and lib/index.js
  implicit-modules list.
- Test files that imported `window`/`isChrome`/`isFirefox` from
  browser-environment now use globals directly.

<Input> lazily initializes its INPUT_ELEMENT probe (instead of at module
-load time) so node-side build tooling that imports the package without
a DOM in scope still loads. The DOM is required at render time, which
is the contract.

Tests:
- Drop the non-interactive variants of the lifecycle, custom-modifier,
  and on-modifier integration tests. Drop the lifecycle test's
  isInteractive/nonInteractive split — assertHooks always uses the
  interactive expectations.
- Drop the visit_test that checked event_dispatcher:main wasn't created
  for isInteractive: false.
- OutletView render-queue test now appends to a real DOM element rather
  than a CSS-selector string.
- type-tests for BootOptions no longer mention isBrowser.

Smoke tests:
- Delete app-boot, component-rendering, fastboot-sandbox, and visit
  tests in node-template, plus their setup-app/setup-component/
  build-owner/assert-html-matches helpers. They were FastBoot-only —
  every one of them used SimpleDOM as a stand-in for document.

tests/docs/expected.js: drop the isBrowser, isInteractive, and matches
entries (the public surfaces that have been removed).

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
@NullVoxPopuli NullVoxPopuli force-pushed the nvp/drop-isinteractive branch from f4be99d to f65171d Compare May 2, 2026 22:13
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 2, 2026

📊 Size report

Tarball size1.2 MB1.2 MB

dist/dev   -0.4%↓

File Before (Size / Brotli) After (Size / Brotli)
./packages/@ember/-internals/browser-environment/index.js 161 B / 121 B
./packages/@ember/-internals/views/lib/system/event_dispatcher.js 10.4 kB / 2.6 kB -6.5%↓9.7 kB / -5.52%↓2.5 kB
./packages/@ember/application/index.js 36.4 kB / 9 kB -0.31%↓36.3 kB / -0.11%↓9 kB
./packages/@ember/application/instance.js 15.9 kB / 4.4 kB -19.3%↓12.8 kB / -17.9%↓3.6 kB
./packages/@ember/debug/index.js 6.8 kB / 1.7 kB 2%↑6.9 kB / 2%↑1.7 kB
./packages/shared-chunks/index-{hash}.js 199.2 kB / 43.7 kB -1.37%↓196.4 kB / -1.08%↓43.2 kB
./packages/shared-chunks/render-{hash}.js 38.4 kB / 8.4 kB -0.46%↓38.2 kB / -0.44%↓8.3 kB
Total (Includes all files) 2 MB / 476.3 kB -0.4%↓2 MB / -0.41%↓474.4 kB

dist/prod   -0.39%↓

File Before (Size / Brotli) After (Size / Brotli)
./packages/@ember/-internals/browser-environment/index.js 222 B / 119 B
./packages/@ember/application/index.js 32.9 kB / 8.5 kB -0.35%↓32.8 kB / -0.59%↓8.4 kB
./packages/@ember/application/instance.js 14.8 kB / 4.1 kB -21%↓11.7 kB / -19.5%↓3.3 kB
./packages/shared-chunks/has-dom-DdQORPzI.js 601 B / 191 B
./packages/shared-chunks/index-{hash}.js 172 kB / 38.5 kB -1.19%↓169.9 kB / -0.85%↓38.1 kB
./packages/shared-chunks/render-{hash}.js 36.2 kB / 7.9 kB -0.49%↓36 kB / -0.42%↓7.9 kB
Total (Includes all files) 1.9 MB / 436 kB -0.39%↓1.8 MB / -0.44%↓434.1 kB

smoke-tests/v2-app-hello-world-template/dist   -0.45%↓

File Before (Size / Brotli) After (Size / Brotli)
./assets/main-{hash}.js 251.1 kB / 68.6 kB -0.45%↓249.9 kB / -0.22%↓68.5 kB
Total (Includes all files) 251.4 kB / 68.8 kB -0.45%↓250.2 kB / -0.22%↓68.6 kB

🤖 This report was automatically generated by wyvox/pkg-size

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants