From 26906951b3532f79f61eb9ddc78084df7c6def3f Mon Sep 17 00:00:00 2001 From: 8Maverik8 Date: Mon, 1 Jun 2026 11:13:55 +0300 Subject: [PATCH] fix(twenty-sdk): minify front-component bundles & set NODE_ENV=production in deploy build (#20937) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary `twenty deploy` (and `twenty build`) currently ship front-component `.mjs` bundles **unminified**, with `process.env.NODE_ENV` undefined at build time. Two missing options in `get-base-front-component-build-options.ts` — fix is two lines. ## Why this matters Each front-component bundle includes React + ReactDOM + the design system AOT (only `twenty-client-sdk/{core,metadata}` are listed in `FRONT_COMPONENT_EXTERNAL_MODULES`). A trivial widget measures **~2 MB** unminified. Because every widget mount spawns a fresh Web Worker that re-fetches and re-parses the bundle (`FrontComponentWorkerEffect.tsx`), that 2× size translates directly into 2× cold-start latency on **every record-page navigation and every browser refresh**. On a CRM with even a handful of custom widgets this dominates perceived UI latency. ## Why it bites every app, not one user Reference apps in this repo (`packages/twenty-apps/fixtures/{minimal,rich}-app`, `community/github-connector`, `internal/twenty-for-twenty`) ship the same way — verified by inspecting the released `twenty-sdk@2.5.0` bundle. There's no CLI flag, env var, or config option to opt into a production build. A search of issues/PRs for "minify", "bundle size", "production build" surfaces nothing tracking this. ## Fix Enable `minify: true` and `define: { 'process.env.NODE_ENV': '"production"' }` in the base front-component build options. These flow through `build-application.ts` (the orchestrator for `twenty deploy` and `twenty build`). **Watch mode (`twenty dev`) is intentionally untouched.** `esbuild-watcher.ts` has its own configuration path that doesn't consume `getBaseFrontComponentBuildOptions()`; it stays unminified so local rebuilds remain fast and stack traces remain readable during development. ## Measured impact Two production extension apps using `twenty-sdk@2.5.0`: | File | Before | After | Δ | |---|---:|---:|---:| | `oapps-deal-items` (single widget) | 2,114,953 B | 863,444 B | **−59%** | | `oapps-document-hub/documents-panel` | 2,120,341 B | 872,478 B | **−59%** | | `oapps-document-hub/hub-document-record` | 2,077,013 B | 852,544 B | **−59%** | | `oapps-document-hub/field-mapping-editor` | 1,168,941 B | 255,787 B | **−78%** | End-user effect: opening an Opportunity record with two custom-widget tabs went from ~3-4s widget paint to under 1s on the same machine, same browser, same record. ## Risk / scope - **No behavior change.** Minification is a transparent transform; `NODE_ENV=production` is the standard signal libraries already gate on. No app code changes needed. - **No effect on `twenty dev`** — separate code path. - **No effect on logic functions** — they use their own build-options object. - One file touched. ## Test plan - [ ] `yarn twenty deploy` on `packages/twenty-apps/fixtures/minimal-app` → output `.mjs` is mangled and `process.env.NODE_ENV` no longer appears literally inside the bundle. - [ ] `yarn twenty dev` on the same app → output `.mjs` remains readable. - [ ] Existing CI green. Happy to add a feature-flag (`TWENTY_BUILD_MODE` env var or `twenty deploy --no-minify` escape hatch) if maintainers prefer that over unconditional minification. --------- Co-authored-by: 8Maverik8 <8maverik8@users.noreply.github.com> Co-authored-by: martmull --- .../utils/get-base-front-component-build-options.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/twenty-sdk/src/cli/utilities/build/common/front-component-build/utils/get-base-front-component-build-options.ts b/packages/twenty-sdk/src/cli/utilities/build/common/front-component-build/utils/get-base-front-component-build-options.ts index c9bd80f631..9a5f9976d7 100644 --- a/packages/twenty-sdk/src/cli/utilities/build/common/front-component-build/utils/get-base-front-component-build-options.ts +++ b/packages/twenty-sdk/src/cli/utilities/build/common/front-component-build/utils/get-base-front-component-build-options.ts @@ -13,5 +13,7 @@ export const getBaseFrontComponentBuildOptions = (): esbuild.BuildOptions => ({ sourcemap: true, metafile: true, logLevel: 'silent', + minify: true, + define: { 'process.env.NODE_ENV': '"production"' }, plugins: [...getFrontComponentBuildPlugins()], });