Repository navigation
Epic Stack catch-up 5/7: Server index.ts / drop server-build / Express 5 #28
Copy link
Copy link
Open
Description
Parent issue: #23
Parent: search for issue titled “Epic Stack catch-up: tracking”. Do this only after packages 1 and 4 are on dev (RR bump + LiteFS/cache/fallthrough). Package 2–3 are nice-to-have first.
Goal
Match Epic Stack’s server boot: TypeScript entry, no server-build / other/build-server.ts, Vite SSR server/app.ts, Express 5 path matching, rate-limit IPv6 helper.
This is medium-high risk. Do not also do Vite 7, Sentry 10, or the routing migration.
Upstream
- Migrate server code to
server/index.tsand simplify processes epicweb-dev/epic-stack#1066 / epicweb-dev/epic-stack@bac7bd4 — migrate toserver/index.ts, deletebuild-server - Fix express middleware and dev script loading mocks epicweb-dev/epic-stack#1076 / epicweb-dev/epic-stack@1c09b52 — load Express middleware (https, slash redirect, helmet, rate limit) before Vite/dev handler so mocks still work
- Express 5:
app.get('*')→app.get(/.*/)(or regex Epic Stack uses);/img/*→/^\/img\/.*/;app.all('*', ...)goes away because the RR handler isserver/app.ts - Rate limiter:
ipKeyGeneratorfromexpress-rate-limit(Epic Stackserver/index.ts) - Node engines:
"node": "^22.18.0"(keep Node 22; this is a range, not a jump to 24)
Reference files (current Epic Stack):
- https://github.com/epicweb-dev/epic-stack/blob/main/index.ts
- https://github.com/epicweb-dev/epic-stack/blob/main/server/index.ts
- https://github.com/epicweb-dev/epic-stack/blob/main/server/app.ts
- https://github.com/epicweb-dev/epic-stack/blob/main/package.json (scripts only)
- https://github.com/epicweb-dev/epic-stack/blob/main/other/Dockerfile
- https://github.com/epicweb-dev/epic-stack/blob/main/vite.config.ts (
build.rollupOptions.inputfor SSR)
Do this
Branch off origin/dev. PR into dev.
-
Entry
- Replace
index.jswithindex.tsmatching upstream: load dotenv, source-map-support, mocks ifMOCKS=true, then alwaysimport('./server/index.ts')(noserver-buildbranch) - Update
package.jsonscripts:dev,dev:no-mocks,start,start:mocksshould runnode index.ts(keep this site’sdev:scan/localtunnelscripts) - Remove
build:remix/build:serversplit if upstream is justreact-router build. Removeother/build-server.ts. Dropserver-buildfrom.gitignore/.prettierignore/ Dockerfile copy if present eslintIgnorecan drop/server-build
- Replace
-
server/app.ts- Split the React Router
createRequestHandlerintoserver/app.tsas upstream does - Vite config: for SSR builds,
rollupOptions.input='./server/app.ts' - Dev:
appType: 'custom',ssrLoadModule('./server/app.ts')after security/rate-limit middleware (see #1076)
- Split the React Router
-
Express 5
- Bump
expressto 5.x and@types/expressto 5.x (Epic Stack^5.2.1/^5.0.6) - Bump
express-rate-limitto 8.x and useipKeyGeneratorinkeyGenerator(keepfly-client-ipfirst) - Convert wildcard paths to what Express 5 / path-to-regexp needs (Epic Stack uses regexes). Do not guess
/:path(*)unless that is what current Express 5 in this PR actually requires — match upstreamserver/index.ts - Add
/dashboardtostrongPaths(this site’s admin UI)
- Bump
-
Dockerfile
- Stop copying
server-build - Keep Sentry build secrets this site already uses if still needed
- Keep LiteFS copy /
CMD ["litefs", "mount"] - Do not change Fly app name or region
- Stop copying
-
Vite
- Keep localtunnel
allowedHosts - Keep Sentry plugin wiring from package 2 if already merged; do not regress hidden sourcemaps
- Do not add react-router-devtools here unless it is required to compile (it is not)
- Keep localtunnel
-
engines.node:"^22.18.0"
Files allowed
index.js(delete) /index.ts(add)server/index.ts,server/app.ts(new),server/dev-server.js(delete if unused)other/build-server.ts(delete)other/Dockerfilepackage.json,package-lock.json(express, express-rate-limit, @types/express, and whatever those require — not vite/vitest/sentry major)vite.config.ts(SSR input + keep localtunnel/sentry).gitignore,.prettierignore,eslint.config.js/eslintIgnoreas needed- Tests that import server boot
Do not
- Do not bump
vite6→7,vitest3→4,@sentry/*9→10,prismabeyond patch/minor - Do not switch to
react-router-auto-routes - Do not edit
dashboard+route files - Do not remove extra UI dependencies
- Do not base on PR P/patn dev stack updater #21
Acceptance
- No
server-build/build-server.tsin the repo or Dockerfile node index.tsis the dev and prod entry (withMOCKS=truefor mocked dev)- Express 5; rate limiter uses
ipKeyGenerator - Localtunnel
allowedHostsstill works npm run build,typecheck,test -- --runpass; Playwright on the PR is green- PR targets
dev
Staging smoke (human) — required
Staging must boot. Check:
- HTTPS / no trailing-slash issues
/resources/healthcheck- Login, notes, dashboard
- Static
/assetsand favicons - Rate limit does not lock you out while clicking around
PR target: dev (never main). Implement only this issue.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels
Activity