Consumer: Native Executable Install
GOAL
Make sure we can ship cli as a native package without requiring NPM. We need a solution for 🐧 🍏 and 🪟. They don't have to be the same solution, but that would be nice.
First step is figure how to package. 2nd step how/where to distribute. Github packages and attached to the release on github seems like a logical first step.
Related:
- https://github.com/oven-sh/bun/issues/21189
Love the idea, this would make for a really nice UX. Deno & Bun are probably the only two contenders in this space.
I just quickly tested this withbun build --compile packages/cli/index.ts --outfile gemini-cli and it works like a charm.
A few notes:
- Executable file size is ~70MB on my Mac
- Since this removes the need for esbuild, need to define
process.env.CLI_VERSIONusing some other way. For example,CLI_VERSIONcould be a file that is then simply embedded. - For
sandbox-exec, need to pass configs as a string (-p '...') instead of as a file path (-f). That should be a quick thing though according to the documentation. - There will be a need for things like code signing and custom upgrade procedures
I'd love to help research options here!
Wonderful! I added a few notes to make the description more useful. I thought i had cleaned all those up before posting ;)
I made a pull request which builds the project for macos,windows and linux using bun! https://github.com/google-gemini/gemini-cli/pull/4488. Check out the branch https://github.com/Shubin123/gemini-cli/tree/build-script. I'm surprised there is no native executable yet
Edit: sorry if my comment came off as rude or disengenious. I should have looked at the existing issues better since I didnt find this discussion before making a pull request. But with many items on the roadmap its hard to find this task being discussed.
my pr just puts @swissspidy bun build command with --target=. set to build for a macos and windows in a shell script. I tried with pkg and deno but those options didnt work. maybe the existing makefile would be a better place to create commands to create target binaries?
If there is no errors with the bun build maybe it could be attached as release since that would help distribution efforts? Although code signing might also be part of the continous intergation that either I'm unaware of or needs to be setup.
Once again sorry if I overstepped I didnt know this discussion was already taking place and @taeold was already assigned and working on it @swissspidy had the same idea then I would not have made a pr.
Thanks for sharing your work @Shubin123 - like you, I'm just trying to help push this work through the door, and I appreciate your work.
I think bun executable is not ready to be released yet.
I noticed that Gemini CLI executed with bun runtime sometimes freezes. The bun exectuable repeatedly froze for me when the Auth dialog pops up. It also breaks "esc to cancel" the agent's progress.
I think there may be an issue w/ how bun handles stdin when there are multiple streams listening to it. I've reported the issue on bun (linked in the issue description now) - I think we should wait for that issue to be resolved before we start distributing the native binaries with bun.
We should be unblocked to think through how we'll create and distribute binaries for MacOS/Linux/Windows w/ proper code signing. I'm going to research some common setup used to achieve this kind of distribution. Feel free to share your findings.
I tried bun build --compile packages/cli/index.ts --outfile gemini-cli
but it errors with
[630ms] bundle 2367 modules
[19ms] compile gemini-cli
39 | "*.scss"
^
warn: wildcard sideEffects are not supported yet, which means this package will be deoptimized
at /home/mrcool/dev/lab/lab2/gemini-cli/node_modules/highlight.js/package.json:39:5
deno compile on the other hand works
DENO_COMPAT=1 deno compile -A --no-check packages/cli/index.ts
though it gives a big executable (> 200mb)
if I bundle with npm run bundle then compile , bun and deno both work (deno compiled size becomes normal)
I tested in linux and Deno have smaller compiled artifact size:
- Deno 93.3 MiB
- Bun 107.8 MiB
Deno is also blocked on a similar issue to bun (doest work with current latest version, but it works correctly with Deno version 2.3.3) https://github.com/denoland/deno/issues/30145
/assign
@Ayushmanonlycode Thanks for taking interest but this issue is already assigned. We'd still love to have you contribute. Check out our Help Wanted list for issues where we need some extra attention.
@taeold @swissspidy I'm on the Bun team - we'd love to resolve issues you are experiencing. We can get a Slack setup / or you can email us ([email protected]). CC @jarred-sumner
Just to chime in - I've done a workshop on saturday 4oct at Devfest Modena and most Windows users had trouble installing Gemini CLI (basically only Mac/Linux folks finished my workshop!).
Sending 💛💛💛 lots ot love to this Issue and PR coders
Gemini seem to have done some changes recently that makes Deno work with no workarounds
So I made this repo https://github.com/sigmaSd/gemini-deno-native-build/ which will automatically build gemini-cli with Deno each 6 hours from latest commit
You can find the binaries here https://github.com/sigmaSd/gemini-deno-native-build/releases (the order is a bit messed up, but the latest release is here https://github.com/sigmaSd/gemini-deno-native-build/releases/latest )
/assign
👋 @aswinashok44, you've been assigned to this issue! Thank you for taking the time to contribute. Make sure to check out our contributing guidelines.
https://www.npmjs.com/package/@yao-pkg/pkg might be another way to package things into native executables. I haven't used it but I've worked in a project that did and it seemed to work well enough.
@gundermanc Thanks for the input, I did look into pkg. The original pkg maintained by vercel was deprecated and archived, the one you shared is a fork, my main concern with using pkg is the future support and maintenance since vercel is no longer maintaining the original repo. I feel Bun is more future-proof!
Node.js natively supports this via Single Executable Application (SEA).
-
Performance (useCodeCache): We can utilize the
useCodeCacheoption in the SEA configuration. This pre-compiles the Javascript into a V8 code cache during the build process, significantly reducing startup time by skipping the parsing/compilation phase.
Since we already generate a bundled gemini.js, the workflow would essentially be:
- Create a
sea-config.jsonenablinguseCodeCache. - Generate the blob:
node --experimental-sea-config sea-config.json. - Inject the blob into the node binary using
postject.
@myaaaaaaaaa Thanks for the inputs.
I did a POC with Node SEA and Bun.
Couple of issues:
- Node SEA doesn't support ESM, the bundled gemini.js is an ES module, so I have to use a common js launcher.
- The interactive shell requires node-pty which needs to be shipped as sidecar.
Bun supports ESM, Bun is planning to have a native PTY implementation in it's runtime which help us avoid shipping the sidecar.