You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This is the umbrella issue for a full application UI migration only if #577 concludes that Preact will make the production application smaller and simpler. The phase boundaries, measurements, and retained modules must be updated from the ADR before implementation begins.
Goal
Migrate suitable UI composition and lifecycle ownership to Preact in several bounded phases while making the final production application shorter, less imperative, and easier to reason about.
The migration is not successful merely because the application renders through Preact. It must delete replaced vanilla lifecycle code and reduce total production UI complexity.
Success definition
At completion:
production UI TypeScript/JavaScript LOC is lower than the documented baseline, excluding tests, docs, generated files, and temporary migration tooling;
app-shell.ts is deleted or reduced to a narrow bootstrap/integration boundary;
each DOM subtree has one rendering owner;
manual DOM synchronization, listener cleanup, and cross-effect presentation coordination are materially reduced;
there is no permanent parallel vanilla/Preact implementation for migrated regions;
proven domain reducers, controllers, persistence, schemas, generation tokens, and async validity rules are retained unless separately justified;
Chromium and WebKit pass the full interaction matrix.
A migration that increases production UI code while retaining equivalent lifecycle complexity does not meet this issue’s goal.
Migration principles
Delete while migrating. A phase is incomplete until the replaced renderer, effects, listeners, and disposal paths are removed.
One owner per subtree. Vanilla code and Preact must never mutate the same DOM region.
Keep domain logic outside components. Pure reducers, controllers, schemas, persistence, and reusable state machines remain framework-independent.
Use narrow imperative adapters. CodeMirror, Chart.js, virtualized grids, and similar libraries mount, update, and dispose behind explicit component boundaries.
Avoid state churn. Keep Signals or existing controllers where they remain the simplest source of truth; do not rewrite state only to match framework conventions.
Preserve distribution. Every phase must continue to produce the self-contained application artifact.
Measure every phase. Record production LOC removed/added, bundle impact, deleted ownership paths, and browser test coverage.
No migration-only redesign. Visual or product redesign requires its own scope.
Proposed phases
The final boundaries must follow the #577 ADR, but the expected migration sequence is:
Define the exact production LOC baseline and counting script/method.
Define bundle, startup, and browser-performance budgets.
Classify modules as retain, adapt, migrate, replace, or delete.
Define DOM ownership boundaries and the temporary interoperability rule.
Confirm how Signals integrate with Preact.
Confirm how the single-file build bundles Preact and JSX/TSX.
Exit criterion: the migration is approved with measurable simplification targets. Otherwise close this issue as not planned.
Phase 1 — Preact bootstrap and shell ownership
Add the minimal Preact build/runtime integration.
Establish one application root and explicit non-Preact mounting islands where temporarily required.
Move shell geometry, header slots, centre host selection, mobile projection, and top-level disposal into declarative ownership.
Prove workspace switch, sign-out, remount, and repeated disposal without leaked listeners or stale callbacks.
Delete the replaced shell rendering/effect paths.
Exit criterion: the shell has one owner, the single-file build works, and production code for the migrated shell is smaller than the replaced implementation.
Exit criterion: #487 is complete, and the migrated navigation has fewer production lines and lifecycle ownership points than the implementation it replaces.
Exit criterion: one right-inspector implementation exists, migrated tool code is smaller than the removed desktop composition code, and no stale result-bound content can appear.
Phase 4 — centre surfaces and shared application chrome
Migrate Query/Dashboard host composition and shared toolbars where it removes lifecycle complexity.
Put CodeMirror, results grids, charts, and Dashboard layout engines behind narrow adapters without rewriting their domain state.
Migrate mobile navigation and shared shell chrome.
Verify resizing, fullscreen/detached views, query execution, and Dashboard execution across mount and surface transitions.
Delete replaced vanilla render/effect paths.
Exit criterion: shell and centre composition have declarative ownership, imperative integrations have bounded adapters, and no feature has dual DOM ownership.
Phase 5 — remaining UI regions
Inventory remaining manually rendered regions.
Migrate only regions where Preact removes more code and lifecycle complexity than it adds.
Keep small isolated imperative modules when they are demonstrably simpler.
Consolidate reusable tabs, disclosures, menus, drawers, and dialog composition without creating an oversized internal component framework.
Delete obsolete builders and shared chrome that no longer have callers.
Exit criterion: all remaining exceptions are documented and intentionally retained.
Phase 6 — cleanup, proof, and final cutover
Remove temporary interoperability bridges, feature flags, duplicate CSS, dead dependencies, and migration helpers.
Run architecture-boundary and dead-code checks.
Recalculate production UI LOC and lifecycle metrics using the Phase 0 method.
Compare final bundle/startup/runtime measurements with the approved budgets.
Run the full Chromium/WebKit interaction and accessibility matrix.
Update architecture, development, roadmap, and changelog documentation.
Exit criterion: the final production application is measurably shorter and simpler than the baseline, and there is no permanent migration scaffolding.
Required per-phase report
Each phase PR must include:
files and ownership boundaries migrated;
production LOC removed and added;
replaced listeners/effects/disposers deleted;
bundle delta;
retained domain modules;
temporary bridge introduced, owner, and removal phase;
browser tests added or updated;
rollback boundary;
confirmation that no DOM subtree has dual ownership.
Focus and accessibility
Preact is not itself the focus policy. Structural transitions must still satisfy the product behavior established in #487 and #488:
semantic intent is captured before a focused subtree is removed;
stale transition work is cancelled;
the destination is resolved after rendering/layout;
a newer user focus is not stolen;
modal and non-modal surfaces preserve their distinct contracts;
real-browser tests, not DOM-only tests, prove the behavior.
The exact implementation—component lifecycle, hook, scheduler plus policy, or small service—must follow the #577 decision and should not become a global focus manager unless evidence requires it.
Status and dependency
Blocked on the architecture decision in #577.
This is the umbrella issue for a full application UI migration only if #577 concludes that Preact will make the production application smaller and simpler. The phase boundaries, measurements, and retained modules must be updated from the ADR before implementation begins.
Goal
Migrate suitable UI composition and lifecycle ownership to Preact in several bounded phases while making the final production application shorter, less imperative, and easier to reason about.
The migration is not successful merely because the application renders through Preact. It must delete replaced vanilla lifecycle code and reduce total production UI complexity.
Success definition
At completion:
app-shell.tsis deleted or reduced to a narrow bootstrap/integration boundary;A migration that increases production UI code while retaining equivalent lifecycle complexity does not meet this issue’s goal.
Migration principles
Proposed phases
The final boundaries must follow the #577 ADR, but the expected migration sequence is:
Phase 0 — decision, baseline, and migration map
Exit criterion: the migration is approved with measurable simplification targets. Otherwise close this issue as not planned.
Phase 1 — Preact bootstrap and shell ownership
Exit criterion: the shell has one owner, the single-file build works, and production code for the migrated shell is smaller than the replaced implementation.
Phase 2 — left navigation and completion of #487
Exit criterion: #487 is complete, and the migrated navigation has fewer production lines and lifecycle ownership points than the implementation it replaces.
Phase 3 — right inspector and #488
Exit criterion: one right-inspector implementation exists, migrated tool code is smaller than the removed desktop composition code, and no stale result-bound content can appear.
Phase 4 — centre surfaces and shared application chrome
Exit criterion: shell and centre composition have declarative ownership, imperative integrations have bounded adapters, and no feature has dual DOM ownership.
Phase 5 — remaining UI regions
Exit criterion: all remaining exceptions are documented and intentionally retained.
Phase 6 — cleanup, proof, and final cutover
Exit criterion: the final production application is measurably shorter and simpler than the baseline, and there is no permanent migration scaffolding.
Required per-phase report
Each phase PR must include:
Focus and accessibility
Preact is not itself the focus policy. Structural transitions must still satisfy the product behavior established in #487 and #488:
The exact implementation—component lifecycle, hook, scheduler plus policy, or small service—must follow the #577 decision and should not become a global focus manager unless evidence requires it.
Acceptance criteria
app-shell.tsis removed or reduced to a narrow bootstrap/integration role.Non-goals
Related