Build1 distinct publisher3 min readUpdated
The Vite config came to 23 lines. The merge request came to 166 files and 70 days, nearly all of it paying down what Create React App had been quietly supplying.
The Engineer · Build desk

Compiled by The EngineerSomething wrong?How this is made
The load-bearing sentence in the whole account is that Create React App was never a bundler in the first place, it was an API [16]. Over five years, DreamNet's source had absorbed webpack's semantics: `process.env` reads in browser code, `%PUBLIC_URL%`, `import { ReactComponent as Icon }`, JSX living in `.js` files, implicit Node globals, and automatic Babel transpilation of every CommonJS dependency the team had ever installed [17]. None of those are React features and all of them were holding something up, the author writes [17]. So the first task was not the config file but a survey of every place the source assumed only webpack could satisfy, and that list came out roughly ten times the size of the config [18].
The `constants.js` episode is the mechanism in miniature. It was a data module that had quietly grown JSX inside it, nav configs and ingredient lists and session-OS maps each carrying an `icon: <AacIngredientIcon />` [15]. What exposed it was esbuild's refusal to parse JSX in a `.js` file, which Babel had been doing without complaint [13]. The fix was to split the JSX-bearing exports into `constant.jsx` and leave `constants.js` as data, a change the author says was worth making on its own merits [15]. Note the direction of causation. The new toolchain did not create that mess; it declined to keep concealing it.
Then there is the shape of the review. Twenty-eight or more diff revisions attracted 19 review comments [2], which is fewer than one comment per revision [22], spread across 70 days at roughly one revision every two and a half days [23]. That is not a merge request stuck in an argument. That is one engineer repeatedly finding the next thing the old build had been supplying for free. The 166 changed files also exceed the roughly 130 source files in `src/scene` alone [24], so the blast radius reached well past the screens.
Two things temper the read. This is a single first-person write-up, submitted to DEV's Summer Bug Smash powered by Sentry [21], and the payoff is stated as intent rather than measurement: faster cold start, near-instant HMR, better production builds [19]. The old feedback loop is described in units of checking Slack and, on a cold start, making coffee [20]. Anyone approving this work on those grounds is buying 70 days of attention against a number nobody in the account has yet published.
The transferable part is the discipline around the deployment contract. Vite defaults to `dist` and port 5173, but the GitLab CI jobs, Docker image and deploy scripts expected `build/` on port 3000, so both were pinned in config [7]. The author's rule: absorb the churn in configuration, not in infrastructure, because changing the bundler and the deployment contract together produces a broken pipeline you cannot attribute to either [8].
Follow any of these and your For You feed starts watching them — no settings page required.
Ranked by verification strength, evidence, and original report placement.
MR !907 migrated DreamNet from Create React App plus Webpack to Vite plus SWC: 166 changed files and 70 days between the proposal to swap the bundler and green on production.
MR !907 carried 28 or more diff revisions and 19 review comments.
DreamNet is the internal admin platform for ZURU's housing division, covering user management, RBAC, asset catalogues, project publishing, release builds, an order-pricing engine, event management and dashboards with charts and maps.
The app was scaffolded with Create React App and was still running [email protected], a 2019 release, held together with rewire, env-cmd and [email protected], which needed a specific Node version to compile.
The replacement vite.config.mjs is 23 lines, using @vitejs/plugin-react-swc and vite-plugin-svgr with envDir set to 'environments'.
Evidence-backed comparisons of source perspectives and observed adoption signals. Read the methodology
Which Builder, Operator, and Investor concerns the observed source mix emphasized—not a truth score.
Evidence, demonstrated adoption, hype gap, incentives, and confidence are assessed independently, each on its own current evidence. How these are measured.
Detailed but single-source and self-reported
The account is unusually specific for a first-person migration story: the complete vite.config.mjs, named package versions, concrete file renames, a reproduced process.env-to-import.meta.env diff, and MR-level counts. All of it rests on one publisher and one author with no independent artefact in the cluster — no linked merge request, repository, CI output or timing measurement — and the supplied body is truncated mid-section, so the later stages of the migration cannot be checked. Mechanism claims about esbuild and ESM are verifiable in principle against documented tool behaviour; the project-specific numbers are not verifiable from the supplied material.
One internal platform in production
Adoption evidence is exactly one deployment: a single company's internal admin platform reporting a Vite plus SWC build green on production, with the legacy stack it replaced disclosed. There is no second organisation, no fleet or usage statistics, no benchmark result and no external corroboration, and the migrated app still runs React 16, so this is a narrow single-site data point rather than a signal about broader migration uptake.
Mostly deflationary, with an unmeasured speed pitch
The post argues against its own easy narrative — the headline concedes the build was the easy part, and the cost detail is granular rather than triumphal, which pulls the gap toward zero or below. The residual overstatement is confined to the justification: the migration was pitched on faster cold start, near-instant HMR and better production builds, and the only performance evidence supplied is anecdotal Ctrl+S-to-Slack framing with no measured before-or-after numbers. A modest positive gap reflects an unverified benefit claim carried by an otherwise conservatively framed account.
Contest submission and practitioner self-presentation
Two disclosed incentives shape the telling: the piece is an entry in DEV's Summer Bug Smash: Smash Stories powered by Sentry, which rewards dramatic war-story framing, and it is a first-person account by the engineer who owned the merge request describing work at their own employer, which favours decisions that look vindicated. Offsetting factors keep this mid-range: the incentive is toward narrative, not toward a product — no vendor sponsorship of Vite, SWC or esbuild is disclosed or implied, and the author volunteers costs and a day lost to a one-line change rather than only wins.
Moderate: internally coherent, externally unchecked
Confidence is capped by structure rather than plausibility. A single publisher, a single first-person author, a truncated body and no independent artefact mean the specific counts and the production outcome cannot be corroborated, and the derived rates simply restate the self-reported figures. What raises it above low is internal consistency and the fact that the generalisable mechanisms — ESM reclassification under "type": "module", esbuild's JSX extension rule, Vite's import.meta.env with VITE_ prefixes and its dist/5173 defaults — are documented tool behaviours consistent with the account.
build
With CRA out of React's docs, the new project default is a rendering decision1 distinct publisher
build
A buildless app still has a build step: 41 pinned URLs and a sed pass that missed two1 distinct publisher
build
Three frozen components, one helper: Framer Motion's whileInView can strand elements for good1 distinct publisher
build
A GPU SQL Engine Lost to One CPU Thread Because a Dispatcher Constant Was 128x Too Small1 distinct publisher
Distinct publishers with included, body-backed reporting in this cluster.
dev.to
1 article · August 23, 2026