Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use the "engines" field to automatically replace node with bun in the shebang #9346

Open
Jarred-Sumner opened this issue Mar 10, 2024 · 6 comments
Labels
bun install Something that relates to the npm-compatible client tracking An umbrella issue for tracking big features

Comments

@Jarred-Sumner
Copy link
Collaborator

Jarred-Sumner commented Mar 10, 2024

Currently, it is difficult to publish CLIs to npm which can transparently run in either node or bun.

Thus far, Bun has attempted to address that in two ways:

  1. When node is not in path,bun <any-executable> and bun run <any-executable> automatically adds a temporary node to path symlinked to Bun, which makes #!/usr/bin/env node still work when Node is not installed
  2. The --bun flag forces the behavior of ^ even when node is in path - bun --bun <any-executable>

This doesn't fix the case where <any-executable> is installed globally, you don't have node installed and you want to run it without prefixing bun.

While some packages are happy to be bun-only, for many packages it doesn't make sense today to limit their potential users to only bun.

tsc and turbo both seem to work in bun, there's no reason it doesn't run them using bun when bun is installed

This proposal suggests the following:

When using bun install and "bun" exists in the "engines" field in package.json in an installed dependency, we automatically inject and replace the #!/usr/bin/env node shebang with #!/usr/bin/env bun in all bins with a javascript-like file extension.

{
  "name": "my-cli-tool",
  "version": "1.0.0",
  "engines": {
    "node": "*",
    "bun": "*"
  },
  "bin": {
    "my-cli": "./bin/my-cli.js"
  }
}

This would let package authors publish packages for both node and bun that lets the user choose which runtime to use (implicitly by choosing bun with bun install, or node with other package managers). This has the downside that yarn v1 will report a warning about an unknown engine (only yarn v1 as far as I can tell), but that's probably okay (the "vscode" engine used by vscode extensions has the same issue)

Another approach involves the "exports" field, but the npm registry api does not expose that information in the abbreviated version object (nor should it, imo)

Fixes #9334
Blocked on #5846

@Jarred-Sumner Jarred-Sumner added the tracking An umbrella issue for tracking big features label Mar 10, 2024
@Electroid Electroid added the bun install Something that relates to the npm-compatible client label Mar 11, 2024
@paperdave
Copy link
Member

I like this proposal, but I don't like that it will force every CLI that is compatible to bun to add this field. It should not be required for packages to alter any of their code for bun to properly run them. This should be used by projects intending to support multiple runtimes.

I think this shebang replacement #!/usr/bin/env node -> #!/usr/bin/env bun should just always be done if node is not installed. Later on, this should be the default along with --bun (i think we should soon make this a feature flag or bunfig option to set this default enabled)

Also, it should be noted that this specific case is not an issue on Windows, as the shim does what I describe when node is not available (see #8795). Though, typing this up, replacing to bun is incorrect; it should be hitting our .RunAsNodeCommand for edge cases. We dont have a great way to expose this outside of setting the binary name to node.

As a first step, we should document this and make bun init add this engine definition there.

@kunokareal
Copy link
Contributor

an alternative solution would maybe to allow running scripts without a shebang at all?
and make the default behaviour "run with bun" if there is no shebang in the script

currently it fails with Failed to run "scriptname" due to error InvalidExe if there's no shebang, while npx happily just runs it with node

@paperdave
Copy link
Member

while npx happily just runs it with node

i didn't realize that is even allowed. this feels more like a separate bug to me, and it should be implemented in addition to the other ideas.

@arlyon
Copy link

arlyon commented Mar 26, 2024

This would be handy for turbo. repro (should also work w/ docker):

$ podman run -it oven/bun:alpine sh
$ bun i -g turbo
$ /root/.bun/bin/turbo
env: can't execute 'node': No such file or directory

Linking this issue also vercel/turborepo#7688

@frytg
Copy link

frytg commented Apr 9, 2024

@Jarred-Sumner should we expect for engines: { bun: >x.x } in package.json to be working already or is this part of the considered change?

@kravetsone
Copy link

Great idea! I will wait it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bun install Something that relates to the npm-compatible client tracking An umbrella issue for tracking big features
Projects
None yet
Development

No branches or pull requests

7 participants