Skip to content

Desktop artifacts ship the renderer's dependency tree twice #3146

Closed

Description

@Joob1n

Problem

app.asar carries the raw sources of packages that exist only to be bundled into the renderer. Vite already emits everything the renderer loads into dist-renderer; the second copy in node_modules is never read.

Measured against main@794e760a9:

Size
dist-renderer — what the renderer actually loads 7.5 MB
Same libraries again as raw node_modules inside app.asar ~183 MB

Largest contributors: mermaid 80 MB, lucide-react 30 MB, @astryxdesign 22 MB, @mermaid-js 12 MB, cytoscape-fcose 9 MB, react-dom 7 MB.

Why it happens

electron-builder.config.mjs declares files: ['dist/**/*', 'dist-renderer/**/*', 'package.json', ...], which does not mention node_modules. electron-builder then adds the full production dependency closure on its own. @maka/ui is a production dependency of @maka/desktop, and it pulls in mermaid, lucide-react, @astryxdesign/* and react, so all of them ship whole.

Nothing loads them at runtime:

  • dist/main/** and dist/preload/** contain no require/import of @maka/ui, mermaid, lucide-react, react, react-dom, @astryxdesign/*, @xterm/xterm or @dnd-kit/*.
  • No main-process package depends on @maka/ui. The single hit in packages/core/dist/display-redaction.js is a comment, not an import.
  • dist-renderer/index.html references only relative ./assets/* paths, so the bundle resolves nothing from node_modules.

One package needs care: @xterm/headless is required by packages/runtime and must keep shipping. Only @xterm/xterm and @xterm/addon-fit are renderer-side.

How it got here

Not any one change — three that were each reasonable alone:

Date Change Effect
07-26 #1506 established the macOS release pipeline production dependencies ship whole by default
08-03 #1929 added Mermaid rendering to Markdown +80 MB, correctly code-split for the renderer
08-05 #2199 bundled a hermetic Git runtime +151 MB (separate issue)

Each author saw only their own slice, and CI has no artifact-size gate, so nothing reported the step changes.

Proposal

  1. Exclude the renderer-only tree from files in the electron-builder config, keeping @xterm/headless.
  2. Add a packaged-size check to CI so a future step change is visible in the PR that causes it. Worth doing first — otherwise the reclaimed space returns in some other form within a couple of months.

Happy to take this one. Filing separately rather than folding it into a PR because the exclusion mechanism is a packaging-policy decision.

Not included here

The bundled Git runtime is a larger and separate finding: of its 151 MB, ~78 MB is a .NET runtime and ~17 MB is a 2D graphics library, both belonging to Git Credential Manager, which Maka does not use — it keeps credentials in its own credentials.json. A further ~13 MB comes from the 27 git builtins having lost their hardlinks (414 files, 415 inodes). I will file that separately if it is wanted.

Activity

  1. added a commit that references this issue on Aug 17, 2026
    93ba39c
  2. Joob1n commented on Aug 24, 2026

    @Joob1n
    MemberAuthor

    Claiming this one.

    The baseline in the body is from 794e760a9 and has moved twice since: #3457 removed the bundled Git runtime entirely, and the renderer-only tree has grown. Current sizes on main:

    Then Now
    dist-renderer — what the renderer loads 7.5 MB 7.9 MB
    mermaid 80 MB 84 MB
    lucide-react 30 MB 40 MB
    @astryxdesign 22 MB 33 MB
    @mermaid-js 12 MB 12 MB
    cytoscape-fcose 9 MB 9.1 MB
    react-dom 7 MB 7.1 MB

    The diagnosis still holds: files in apps/desktop/electron-builder.config.mjs names dist/**/*, dist-renderer/**/* and package.json but nothing about node_modules, so electron-builder adds the production closure on its own.

    First step, because it decides the shape of the rest: establish what the packaged app actually reads at runtime, from the artifact rather than from the dependency graph. The body's exclusion list is derived from what imports what in dist/main and dist/preload, which is the right reasoning but not the same as evidence. A package that is only reached through a dynamic import, a worker entry, or a native binding would not appear in that scan and would fail at runtime rather than at build time. I will produce that list against a real mac-arm64 build before writing any exclusion.

    @xterm/headless is the case the body already flags — required by packages/runtime, while @xterm/xterm and @xterm/addon-fit are renderer-side — and it is the shape I expect more of.

    Then, in order:

    1. Exclude the renderer-only tree from files, keeping whatever step 1 proves is reached.
    2. Verify against the built artifact, not the config: package, unpack, and diff the shipped module list against the previous build, then launch the packaged app so a missing runtime dependency surfaces as a failure here rather than in a release.
    3. Extend scripts/verify-packaged-app.mjs so a renderer-only package reappearing in the archive fails the check. Without that this regresses the first time someone adds a production dependency to @maka/ui, which is exactly how it got here.

    The size gate the body asks for is #3146's natural companion but a larger argument (what threshold, measured where, failing whose build), so I would rather land the exclusion plus the specific check first and open the gate separately unless a maintainer prefers otherwise.

  3. added theissue type on Aug 29, 2026
  4. sheng198298 commented on Sep 8, 2026

    @sheng198298

    take

  5. drakeo338 commented on Sep 17, 2026

    @drakeo338
    Contributor

    Take

  6. Astro-Han commented on Sep 17, 2026

    @Astro-Han
    Contributor

    Fixed by #3148 (22b79c5e1): the files list in apps/desktop/electron-builder.config.mjs now excludes dist/renderer/** and the renderer-only dependency closure, so that tree no longer ships inside app.asar.

    The packaged-size CI gate proposed as the second step is not implemented; it is a separate change and is worth filing as its own issue rather than keeping this one open.

  7. drakeo338 commented on Sep 17, 2026

    @drakeo338
    Contributor
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinggood first issueGood for newcomershelp wantedExtra attention is needed

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions