zed
zed copied to clipboard
`Biome` support
Check for existing issues
- [X] Completed
Describe the feature
Add support for Biome formatter/linter
If applicable, add mockups / screenshots to help present your vision of the feature
No response
Ideally, zed should just detect that a biome.json
file is present in the directory and call the local instance defined in package.json
for formatting and linting.
Unlike vscode, there is probably no need to propose to download a local copy of biome as we rely on the package version for CI anyway. What do you/others think?
Ideally, zed should just detect that a
biome.json
file is present in the directory and call the local instance defined inpackage.json
for formatting and linting.Unlike vscode, there is probably no need to propose to download a local copy of biome as we rely on the package version for CI anyway. What do you/others think?
You can argue the same for Prettier which is supported by Zed
Before it's integrated and you need Biome so badly, this is what you can add into your ./.zed/settings.json
.
{
"formatter": {
"external": {
"command": "node",
"arguments": [
"./node_modules/.bin/biome",
"check",
"--apply-unsafe",
"--stdin-file-path=dummy.js",
"-"
]
}
}
}
Until Zed supports Biome through native extension, external command invocation seems like a great alternative!
However, calling node
or npx
is too slow for me. It takes almost 1 second every time I save my file.
I found out that bun
is a great alternative in this use case! It's almost instant and as fast as native VSCode extension.
"formatter": {
"external": {
"command": "bunx",
"arguments": ["@biomejs/biome", "format", "--stdin-file-path", "{buffer_path}", "--write"]
}
}
Here's the config I use:
{
"formatter": {
"external": {
"command": "./node_modules/.bin/biome",
"arguments": ["check", "--stdin-file-path", "{buffer_path}", "--apply"]
}
}
}
~~With this, it'll use the local CLI that's in Rust, so it's faster than npm or bun and since it uses check
, it'll also run organize imports. To make it even faster, you could use --use-server
, but that requires starting the server somehow~~
This is not true, see below.
That makes sense, "./node_modules/.bin/biome",
is going to be a Rust binary that doesn't depend on JS runtime at all?
"./node_modules/.bin/biome"
it is not binary file, it is just javascript
Benchmark 1: cat index.js | bun ./node_modules/.bin/biome check --apply-unsafe --stdin-file-path=index.js
Time (mean ± σ): 31.2 ms ± 0.5 ms [User: 23.8 ms, System: 10.6 ms]
Range (min … max): 30.3 ms … 33.6 ms 83 runs
Benchmark 2: cat index.js | node ./node_modules/.bin/biome check --apply-unsafe --stdin-file-path=index.js
Time (mean ± σ): 65.5 ms ± 1.1 ms [User: 56.6 ms, System: 9.2 ms]
Range (min … max): 64.2 ms … 71.5 ms 44 runs
Warning: Statistical outliers were detected. Consider re-running this benchmark on a quiet system without any interferences from other programs. It might help to use the '--warmup' or '--prepare' options.
Benchmark 3: cat index.js | ./node_modules/.bin/biome check --apply-unsafe --stdin-file-path=index.js
Time (mean ± σ): 67.0 ms ± 2.2 ms [User: 57.3 ms, System: 9.7 ms]
Range (min … max): 64.6 ms … 75.2 ms 42 runs
Warning: Statistical outliers were detected. Consider re-running this benchmark on a quiet system without any interferences from other programs. It might help to use the '--warmup' or '--prepare' options.
Summary
cat index.js | bun ./node_modules/.bin/biome check --apply-unsafe --stdin-file-path=index.js ran
2.10 ± 0.05 times faster than cat index.js | node ./node_modules/.bin/biome check --apply-unsafe --stdin-file-path=index.js
2.15 ± 0.08 times faster than cat index.js | ./node_modules/.bin/biome check --apply-unsafe --stdin-file-path=index.js
so using bun
still makes sense
Arf, I was trying with the native install and replaced my script without thinking, thank you for actually fact checking me, ha! You can actually find the Rust CLI in the node_modules
, but you need to adjust your script per platform (for instance, macOS's one would be at@biomejs/cli-darwin-arm64
)
Formatting seems straightforward enough here, but will this give you inline linting as well like the VS code extension?
Formatting seems straightforward enough here, but will this give you inline linting as well like the VS code extension?
No, not yet. The snippet proposed applies safe fixes, important sorting and formatting when the formatting event is triggered.
Here's the config I use:
{ "formatter": { "external": { "command": "./node_modules/.bin/biome", "arguments": ["check", "--stdin-file-path", "{buffer_path}", "--apply"] } } }
With this, it'll use the local CLI that's in Rust, so it's faster than npm or bun and since it uses
check
, it'll also run organize imports. To make it even faster, you could use--use-server
, but that requires starting the server somehow
Thanks, that's a temporary alternative, albeit slower than native integrations that presumably keep a running process.
Also, is there a way to use that formatter only for certain file types? We still need to fallback to prettier for svelte files, or gofmt for go, etc.
While being able to format is great, not having lints show up in the editor kinda blows-would we need native support for this, or can the new extensions provide this functionality for us?
Does this issue depend on #7096? It seems like being able to add a small WASM plugin to spin up the Biome LSP is the most straightforward way to do this integration.
The official Biome extension just got released https://github.com/zed-industries/extensions/pull/444.
Is it possible to use this extension with Astro files? I know biome already has partial support for Astro
Is it possible to use this extension with Astro files? I know biome already has partial support for Astro
Yes, try it with the latest zed preview.