Tearing Down the Build: The Vite/Source Admin Rebuild
On October 1, 2025, Brett decided to change the method of construction for the RABS admin frontend. The compiled dist/vendor-template pages that had served the project since its earliest days were being scrapped in favor of source HTML under src/html, Vite-built static/multi-page output, and modular per-page JavaScript loaded on demand. Over five turbulent days — punctuated by context window overflows, terminal crashes, and the discovery that an entire night's work had been destroyed — the admin frontend was restructured from the ground up.
Context
The RABS admin frontend had been built as a traditional multi-page HTML application, but the pages were compiled output from a purchased vendor template — pre-built HTML files served out of dist/ with inlined sidebars, headers, and script tags baked into each page. The vendor template provided a rich component library, but the compiled output was opaque when things went wrong: every page duplicated the shared chrome, changes required rebuilding the entire dist folder, and there was no clean way to make a shared partial or load page-specific JavaScript on demand.
This was not a conversion to a single-page application. The admin frontend remained a multi-page site throughout — each page stayed its own HTML file, with its own URL and full page load. What changed was how those pages were built: moving from opaque compiled dist output to source HTML files under src/html that Vite would build into clean static pages, with shared partials (header, sidebar, scripts) injected at build time and each page's JavaScript loaded lazily via ES modules.
The navigation and user system work from Arc 1 had introduced the <script type="module"> pattern and per-page JS module hooks — a natural stepping stone toward a modular source-build architecture. The decision to move to Vite was the next logical step: native ES modules in the browser during development, a build pipeline that could produce static multi-page output from source files, and per-page JavaScript that loaded only when needed.
What happened
The pivot — changing the method of construction
The first session of the week opened with a decisive statement: Brett wanted to change the method of construction for the admin frontend. The session was large — over 3 MB of transcript — and it laid out the architectural shift from compiled dist/vendor-template output to a Vite source-build architecture. The core idea was simple but the execution was massive: every HTML page, every JavaScript module, every style sheet, and every vendor dependency had to be restructured to work with Vite's expectations.
The session covered the initial setup of Vite in the admin project, the configuration of vite.config.js, and the migration of shared partials (header, sidebar, script tag) to work with Vite's dev server and proxy configuration. The Express backend would continue to serve the API, but the frontend development flow would now use Vite's dev server, which could serve source files directly during development and build clean static output for production.
Context window overflow — the first disruption
The second session on October 1 was short but significant. Brett hit the maximum context window limit — the AI session couldn't continue because the token budget was exhausted. This was a recurring problem in the project's early months: complex multi-file implementation tasks would generate so much code and discussion that the session would hit its limit, requiring Brett to reset and manually provide context about where the previous session left off.
Terminal crash mid-process
The third session was a continuation after another disruption — the terminal had crashed while work was in progress. Brett had to reconnect and provide context about what was being done when the crash occurred. The Vite migration was mid-process, with some files partially migrated and others still in the old format.
The previous night's work was broken
The fourth session on October 1 delivered a gut punch: Brett reported that the task done the previous night was "totally fucked." The Vite migration work had introduced errors or broken existing functionality. Rather than trying to patch the broken state, the approach was to assess the damage and rebuild from a known-good point. This pattern — where a session's work would be broken by the next session's changes or by crashes — would repeat throughout the project's history.
Rebuilding the admin frontend from compiled dist to source
October 2 was the biggest session of the arc at nearly 6 MB of transcript. The work was a comprehensive rebuild of the admin frontend, continuing the Vite migration. Every page was touched: HTML files were updated to use Vite's module system, JavaScript was restructured into ES modules with proper imports and exports, and the shared partials (header, sidebar) were refactored to work with the new build system.
The key architectural decisions from this session:
- Single script entry with lazy page modules —
src/app.jsbecame the main entry, readingdocument.body.dataset.pageModuleand dynamically importing the matching page module viaimport(). Each page was still its own standalone HTML file — this was not an SPA — but the page-specific JavaScript loaded only when that page was visited. - Lazy page modules — Each page's JavaScript lived in
src/js/pages/<page-key>.jsand was loaded on demand via the dynamic import map. Apage-loader.jshelper handled the lazy-loading logic alongsideapp.js. - Shared chrome and styles — Shared header, sidebar, and script partials lived in
src/html/partials/. Global CSS was loaded via<link>tags in the shared head partial, while page-specific styles could be co-located with their page modules. - No per-page script tags — The script partial contained only the single
<script type="module" src="/@src/js/app.js">entry, replacing the old pattern of each HTML page including its own inline scripts.
Structuring the project
October 3 focused on structuring the RABS admin frontend project. The directory layout was formalized: src/html/ for page HTML, src/js/pages/ for page modules, src/js/ for shared utilities (session, auth, boot), src/scss/ for styles, and src/html/partials/ for shared chrome. This session also dealt with Vite configuration details — the dev server proxy settings that forwarded API calls to the Express backend, and the alias configuration that made /@src/ imports work.
Fundamental project changes
October 4 brought more fundamental changes. The project had been through several days of restructuring and the accumulated changes were significant. This session addressed the ripple effects: vendor scripts that needed different paths under Vite, CSS imports that had to be updated, and page modules that needed their route entries added to src/app.js. The session also dealt with the practical issue of making the dev experience smooth — ensuring the Vite dev server proxied API calls correctly to the Express backend, and page-specific code loaded only when needed.
Boot analysis and preparation for bigger modules
October 5 wrapped up the arc with two sessions. The first analyzed a critical boot bug on macOS — after logging in on Chrome for Mac, the browser was bouncing between page_pending.html and index.html in a rapid redirect loop ("about a million times a second" as Brett described it). The issue was in the boot sequence's auth and location-enforcement logic, which was too strict for macOS environments where iCloud Private Relay blocked geolocation requests. The second session prepared for the next phase: creating additional settings files and laying groundwork for the more significant modules (HR, Reggie, logs, notifications) that would now be easier to integrate because the Vite architecture was in place.
What changed
Before this arc, the admin frontend served compiled dist/vendor-template pages where every HTML file duplicated the shared chrome and carried its own inline scripts. After five days of turbulent work:
- Vite source-build architecture — The admin frontend now used Vite for development and build, producing clean static/multi-page output from source HTML files under
src/html. Each page remained a standalone HTML file with its own URL — this was a multi-page application, not a single-page app. - Single script entry with lazy page modules —
src/app.jsread the body'sdata-page-moduleattribute and dynamically imported only the JavaScript needed for that page. The page modules lived undersrc/js/pages/as flat files (e.g.,page_messenger.js) and loaded on demand. - Formalized directory structure —
src/html/,src/js/pages/,src/js/,src/html/partials/became the canonical layout. Shared chrome (header, sidebar, scripts) lived in partials and was injected at build time rather than duplicated in every page. - No per-page script tags — The old pattern of each HTML page including its own scripts was replaced by the single module entry point and lazy page modules.
- The survival pattern evolved — When sessions hit context limits or terminals crashed, context documents and task specifications became the primary way to bridge between sessions.
Work produced
| Area | Key files created or heavily modified |
|---|---|
| Vite configuration | vite.config.js — dev server proxy, aliases, build settings |
| Application entry | src/app.js — single entry with lazy route map |
| Page modules | src/js/pages/*/index.js — per-page modules refactored for ES imports |
| Shared utilities | src/js/session.js, src/js/boot_user.js, src/js/auth-*.js |
| Shared chrome | src/html/partials/ — header, sidebar, script partial |
| Styles | src/scss/styles.scss, src/scss/font.scss |
| HTML pages | All src/html/*.html updated for Vite module system |
What we learned
The Vite migration demonstrated that a source-build architecture with lazy page modules dramatically improved the development experience for a multi-page application. Building from source HTML under src/html rather than compiled dist output meant the project structure was transparent and each page's code was easy to trace. The lazy module pattern meant only the JavaScript for the current page was loaded, keeping the initial payload small even as the number of pages grew.
But the arc also demonstrated the cost of infrastructure changes. Five sessions — four of which were interrupted or recovering from interruptions — were needed to complete the migration. The context window limit was a hard constraint on how much work a single session could accomplish, and the terminal crashes meant work had to be carefully saved and documented between sessions.
The lesson that stuck: when doing foundational infrastructure work, every session should leave the project in a buildable state. The "previous night's work was totally fucked" moment was a direct result of a session ending mid-migration without verifying the build still worked.
Where this led next
With the Vite source-build architecture in place, the next arc turned to the first major module integrations: the HR page, Reggie (the AI assistant), and the logging and notifications system. The Vite structure made it straightforward to add new page modules — just create the directory, write the module, and add a route entry — but the modules themselves would bring their own complexity and breakage.