Skip to content

Build a second client without the embedded server - #391

Merged
sivert-io merged 2 commits into
mainfrom
claude/client-slim-variant
Sep 4, 2026
Merged

Build a second client without the embedded server#391
sivert-io merged 2 commits into
mainfrom
claude/client-slim-variant

Conversation

@sivert-io

Copy link
Copy Markdown
Member

Replaces #389, which GitHub closed when its base branch was deleted on the
#388 merge. Same work, rebased onto main.

GRYT_VARIANT=slim produces a second build with the embedded server left out.
Measured on Windows, both packaged from this branch:

build installer
yarn electron:build 126 MB
yarn electron:build:slim 92 MB

Electron's own runtime is about 90 MB of that 92, so the slim build is roughly
Gryt plus Chromium and not much else.

How it hangs together

The variant reaches three places that do not call each other, so it travels in
the environment:

  • beforeBuild skips packaging the runtime. That is also most of why a slim
    build is quicker — packaging is the step that needs the server, worker and SFU
    checkouts.
  • check-extra-resources stops demanding those two files, and still checks
    everything else. That script exists because electron-builder skips a missing
    extraResource silently, and this leans on exactly that behaviour.
  • electron-builder.config.cjs reads electron-builder.yml and applies the
    three things YAML cannot branch on. The YAML is still where everything is
    written down.

Two of those three are about the release rather than the build: without distinct
artifact names the variants overwrite each other in one release, and without its
own update channel a slim install downloads the full installer next time and
quietly puts the 34 MB back.

What to look at

The updater. main.ts deliberately does not set autoUpdater.channel.
electron-builder bakes channel: slim into app-update.yml, which is the
build's own statement of which variant it is; assigning the property would
override that with a value inferred from a file being absent. The inference is
used only by channelYmlName(), which reads the yml before electron-updater
loads anything — so if it is ever wrong the result is "no update available"
rather than the wrong installer. Worth a second opinion.

Verified

Both variants packaged and launched on Windows against an isolated profile.
Slim produces Gryt-Chat-1.9.14-win-x64-slim.exe, slim.yml, and resources
with no embedded-server.tar.gz or embedded-native/; the default build still
produces latest.yml and both embedded resources. Both start, show a window and
a tray, and discover LAN servers. check-builder-config validates both configs
against electron-builder's schema and asserts the filter, the channel and the
artifact name.

The smoke test found one thing, fixed here: the startup log said "Embedded
server runtime ready" in a slim build, because prepareEmbeddedServerRuntime()
returns early when there is no archive and the line after it ran regardless.

Not verified: macOS and Linux. Signing and notarization differ, and the mac
path stages the native overlay separately.

Still to do, not in this PR

  • The release workflow in the superproject needs a variant axis. Nothing
    publishes a slim artifact until then.
  • The site needs the download tick, defaulting to slim.

🤖 Generated with Claude Code

sivert-io and others added 2 commits September 4, 2026 21:11
A slim build leaves out embedded-server.tar.gz and the native overlay: 72MB
unpacked, 34MB off the Windows installer, so 126MB becomes 92MB. Measured, both
variants packaged on this machine.

GRYT_VARIANT=slim drives it, because the same answer has to reach three places
that do not call each other. The beforeBuild hook skips packaging the runtime,
which is also most of why a slim build is quicker — that step is what needs the
server, worker and SFU checkouts. check-extra-resources stops demanding the two
files, so the rest of that check stays in force rather than being switched off.
And electron-builder.config.cjs reads electron-builder.yml, which is still where
everything is written down, then applies the three edits YAML cannot express.

Two of those three are about the release rather than the build. The artifacts
need different names or the variants overwrite each other in one release, and
the update feed needs its own channel or a slim install downloads the full
installer next time and quietly puts the 34MB back. electron-builder writes
slim.yml and bakes `channel: slim` into app-update.yml, which is what
electron-updater reads.

main.ts does not set autoUpdater.channel. app-update.yml is the build's own
statement of which variant it is, and assigning the property would override that
with a value inferred from a missing file. The inference is only used for the
pre-check that reads the yml before the updater does, where being wrong means
reporting no update rather than fetching the wrong installer.

check-builder-config now validates both variants against electron-builder's
schema, and asserts the three things that otherwise fail silently: the filter,
the channel and the artifact name.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
prepareEmbeddedServerRuntime returns early when the archive is absent, which is
every slim build, and the line after it logged "Embedded server runtime ready"
regardless. Found while smoke-testing the slim build: the log said ready, so I
went looking for an extracted runtime that was never meant to be there.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@sivert-io
sivert-io merged commit 5d449ae into main Sep 4, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant