ReviewOS

stacks/analyticshq

Migration plan: drop vendored storage/framework/ (adopt framework-as-dependencies)

#2
Closed glennmichael123 opened this 9 days ago ·
9 days ago

Context

Stacks is moving from a vendored framework (the whole framework tree in storage/framework/) to consuming it as published @stacksjs/* npm packages (the newer workflow; also what enables buddy extension:* browser-extension builds). ghostanalytics is already transitional: the framework is installed as node_modules deps, storage/framework/ is excluded in tsconfig.json, and @stacksjs/* resolves from node_modules. The vendored tree is now mostly dead weight held in place by a couple of references.

Current state (assessed 2026-07-20)

  • Framework-as-deps in place: ~106 @stacksjs/* packages in node_modules (via the stacks meta-package v0.70.73). Framework defaults ship as @stacksjs/defaults (node_modules/@stacksjs/defaults/resources/...).
  • Vendored storage/framework/: ~106M (core packages + defaults/), excluded in tsconfig - not used for type/module resolution.

Migration surface (small)

Load-bearing - fix before removing the tree:

  1. config/crosswind.ts (~L9-11) - CSS content globs scan ./storage/framework/defaults/resources/{views,components} and core/error-handling/src/views. Repoint to the package locations: ./node_modules/@stacksjs/defaults/resources/{views,components}/** (+ the error-handling package's views). Without this, dashboard / component / error-page CSS stops generating.
  2. package.json build:reset (~L22) - ends with cd storage/framework && bun run build. Remove that step; there is no vendored framework to build.

Cosmetic - clean up, not blocking:

  • config/code-style.ts (~L82-85): lint-ignore globs for framework-generated dirs.
  • Vendored-path mentions in comments: config/cloud.ts, resources/plugins/preloader.ts, app/README.md (and routes/api.ts where present).

Plan

  1. Branch chore/drop-vendored-framework.
  2. Repoint config/crosswind.ts content globs → node_modules/@stacksjs/defaults/... (+ error-handling package views).
  3. Remove the cd storage/framework && bun run build step from package.json build:reset.
  4. mv storage/framework storage/framework.bak (do not delete yet).
  5. Verify end-to-end: buddy dev + /stacks-browse browser QA on the dashboard/UI (render + CSS + hydration), buddy build, buddy lint, buddy test.
  6. Green → rm -rf storage/framework.bak (reclaims ~106M). Keep storage/{logs,keys,app,cloud} (runtime data / deploy state).
  7. Clean up cosmetic references; pin @stacksjs/stacks versions (let buddy-bot drive upgrades).
  8. Commit + PR.

Guardrails (learned the hard way)

  • Verify in the running app with /stacks-browse, not isolated renders. A recent framework sidebar change looked fine in headless renderView but was broken in the real dashboard (component resolution + no hydration). Browser QA is the source of truth for framework/UI changes.
  • Pilot one app first, fully verify, then apply to the sibling. The framework migration is still "in testing".
  • Rollback is trivial: nothing destructive until step 6 - mv storage/framework.bak storage/framework or git checkout.
9 days ago

Same premise, same blocker as bughq — see the pilot findings

This issue shares its premise with stacksjs/bughq#8, which I piloted end-to-end. Short version: the vendored storage/framework/ tree is not dead weight — it's live framework source that buddy build/serve/dev/publish compile and execute, and @stacksjs/server reads defaults/{functions,app/Models,app/Controllers} at boot. Dropping the tree breaks the API boot and buddy build, and the latest framework (0.70.145) still hardcodes those paths — so upgrading alone won't fix it.

Full evidence + the phased conversion plan (package-first resolver with vendored fallback → framework Phase 1 → pilot → rollout) live on stacksjs/bughq#8:

ghostanalytics is a Phase 3 rollout target — no action here until the framework (Phase 1) ships and bughq is piloted green.

9 days ago

Update: recipe proven on two apps; not blocked on unshipped work

Cross-ref bughq#8. Verified against the published 0.70.145 (not the 0.70.73 the original analysis used), the framework-as-deps resolver is largely shipped, and the migration ran green on two pilots — bench-review (#73) and postline (#14). ghostanalytics is the same near-drop-in shape.

When it's picked up: upgrade to 0.70.145 and follow the fix-what-breaks recipe rather than waiting. Known straggler to expect for buddy dev: the componentsDir hardcode in @stacksjs/actions dev/views.js.

9 days ago

Status check — this is substantially done and the issue no longer describes the remaining work.

Landed: no storage/framework/core on disk, the framework comes from npm (stacks ^0.70.190), and storage/framework/ is gitignored with 0 files tracked. Steps 1–5 are complete.

Three leftovers, and two of them just cost real time:

  1. ./buddy still pointed PANTRY_INSTALLER at storage/framework/scripts/pantry-install — a path that exists only on a developer machine, because the directory is generated and gitignored. That took CI down: lint and test failed with Pantry installer not found, deploys needs:-skipped, and it looked like a lint problem for as long as nobody read the log. Fixed — the shim now runs a system bun without demanding pantry.
  2. config/crosswind.ts globbed storage/framework/core/error-handling/src/views, which no longer exists. Silently matched zero files. Fixed — removed, with the two surviving framework globs verified to still resolve (11 views, 194 components).
  3. package.json:22 build:reset still ends cd storage/framework && bun run build. Not fixed — filed as #39.

Step 6 (rm -rf storage/framework) is blocked upstream, not by this repo: @stacksjs/actions/dist/dev/views.js hardcodes paths into it.

Recommend closing this in favour of #39, or retitling it to just the upstream blocker.

9 days ago

Done — closing.

Framework-as-dependencies is complete and has been for a while:

  • git ls-files storage/framework → 0 tracked files; the tree is gitignored build output.
  • Dependencies are down to four packages: stacks, @stacksjs/buddy, @stacksjs/ts-cloud, @ts-analytics/tracking.

Two follow-ups came out of it and are handled elsewhere:

  • The vendored storage/framework/defaults is what actually executes (defaultsAppPath() → storagePath('framework/defaults/app'), and the auto-import barrels re-export from it by relative path), and nothing refreshed it — bun install advances node_modules/@stacksjs/defaults and leaves it alone. It had drifted 592 files and was serving a months-old password endpoint. Deploy now re-vendors on both sites (30a46f1, c629b58).
  • build:reset still cds into the tree this migration removed — that is #39.

Sign in to comment on this issue.