You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
oxc-vscode tries to discover oxlint|oxfmt binaries by looking in node_modules/.bin/.
In Vite+ projects, these binaries are internal dependencies of the vp CLI, so they don't appear in the user's node_modules/.bin/.
As a result, oxc-vscode cannot find them and LSP features (--lsp) don't work.
TODO
Create wrapper scripts in node_modules/.bin/oxlint|oxfmt after vp install.
The wrappers only allow --lsp mode
Other usage should show an error directing users to vp lint|fmt
Shim generation (sh/cmd/ps1) is handled in Rust, reusing the existing shim.rs
Binary paths are resolved via the existing JS lint/fmt resolver() callbacks
Concerns
Need to ensure shims are created across all install code paths?
explicit vp install, auto-install during vp run, global CLI install, etc
First, the Vite+ configuration file is a single file named vite.config.ts located at the root. Within this file, the keys test, lint, and fmt are nested.
vp lint and vp fmt generate temporary config files at runtime to integrate with oxlint/oxfmt. This is because oxapps doesn't know about vite.config.ts, so even if you specify it with --config, it cannot be interpreted.
However, this approach does not work for editor integrations (e.g., VSCode) where the LSP server needs persistent config files.
⚠️ And we need to release this by this Thursday.
Option A: JSON Config Files (Project Root)
Serialize the vite.config content into .oxlintrc.json / .oxfmtrc.json and place them at the project root. No changes needed on the oxc side, but keeping them in sync with vite.config is a challenge.
oxlint/oxfmt natively read vite.config.ts and extract the .lint / .fmt fields as their config source. This requires Vite+ knowledge to oxc side.
👉🏻 This was rejected, oxapps should not know Vite+ specific usage.
Option C: Generic Config Field Extraction
Instead of being vite.config-aware, oxlint/oxfmt support extracting a specific field from any TS config file. e.g., oxlint -c vite.config.ts --config-field lint. Not Vite+-specific, so more likely to be accepted by oxc. This also works with package.json (e.g., oxlint -c package.json --config-field oxlint), which is a well-established pattern used by tools like prettier and jest.
Option D: Bridge Files (Project Root)
Place oxlint.config.ts / oxfmt.config.ts at the project root that simply import vite.config and re-export the relevant field.
Place bridge files in a hidden location (e.g., node_modules/.vite-plus/) and add a basePath option to oxlint/oxfmt so that relative paths are resolved from the project root instead of the file's actual location.
Config Files
oxlint
oxfmt
oxc-vscode
vite+
VSCode UX
Others UX
Concerns
A
.oxlintrc.json, .oxfmtrc.json
None
None
None
File generation + sync
OK
OK
1, 2
B
vite.config.ts
vite.config support
vite.config support, TS config support
None
None
OK
OK
3
C
vite.config.ts
configField support
configField support, TS config support
None
None
OK
OK
-
D
oxlint.config.ts, oxfmt.config.ts
None
TS config support
Additional watch patterns
File generation
OK
OK
2, 4
E
Under node_modules/.vite-plus/
basePath support
TS config + basePath support
Additional watch patterns
File generation + editor config
OK
Not easy
4, 5
Sync between vite.config and JSON files is an ongoing challenge (vp config sync command? file watcher? pre-commit hook?)
Additional files appear in the project root (gitignore?)
Vite+-specific logic would be introduced into oxc side
Watch patterns must be manually configured by the user. There is no mechanism to automatically detect and track import dependencies of config files
Editor-side configuration for configPath + watch is required. Editors which are using CLI directly also requires finding config, extracting field, etc
Currently, Oxlint has 2 concepts to configuration files:
root config
nested configs
Nested configs are not used if -c or oxc.configPath is specified.
And there are 2 types of uses for them:
CLI
LSP
First, when the CLI is executed:
root config: Searches only the current working directory (cwd)
nested configs: Searches upwards from each file
Regarding vite.config.ts, it used only as a root config and acts as a fallback if other .oxlintrc.json(c) or oxlint.config.ts are not found. (It is ignored when searching for nested configs).
Next, in the case of LSP, the cwd is based on the workspace folder opened by the user.
Root config: Searches upwards from the workspace.
Nested configs: Searches downwards from the workspace.
The key point is that it differs slightly from the CLI, but the handling of vite.config.ts is the same as the CLI; it is only considered as a root config.
Oxfmt always uses a single configuration file and does not have the concept of nested configs.
Both the CLI and LSP search upwards from the current working directory.
vite.config.ts also acts as a fallback if no other .oxfmtrc.json(c) or oxfmt.config.ts is found.
The current issue is that, for both Oxlint and Oxfmt, the LSP sometimes finds a nested vite.config.ts during the process of searching for the root config.
monorepo/
├── vite.config.ts # .lint is here
├── packages/
│ └── child/ ← workspace root
│ ├── vite.config.ts # .lint not found!
│ └── src/
This is not an issue when .lint|fmt is intentionally written, but in most other cases, it results in a ".lint|fmt does not exist" error.
It should work with valid .lint|fmt config one.
But how...? Load js config and check key, then ignore if not exists...?
Or, if we only need to support root configs, then perhaps we could allow specifying the root config somehow when calling the wrapper with --lsp...?
👉🏻 This is fixed by just ignoring vite.config.ts w/o .lint|fmt, and defineConfig(fn) exports.
To summarize, the remaining concerns we likely have at this point are:
The plan for Vite+ has always been for vite.config.ts to be nested, but it's unclear if we want users to nest .lint|fmt configurations
I heard that vp lint|fmt will always specify the root vite.config.ts using the -c flag
When running vp run fmt in a subdirectory, oxfmt searches for a higher-level configuration file, while oxlint does not
There might also be a difference in how oxlint searches for nested configurations (since vp lint uses -c, it doesn't search for nested configurations)
For LSP, both will search for a higher-level configuration file
However, if an oxfmtrc or similar file is found along that path, it will be used
In the first place, placing such files in a Vite+ project is probably not recommended
If vite.config.ts uses function style defineConfig(fn), oxapps cannot consume it
It seems limitation to interpret vite.config.ts
These are issues that users may encounter for a while:
I did install vite+ as my node manager. But now on older project that does not use vite+ the lsp for oxc doesn't work.
this is the output of the oxc plugin. 2026-03-13 15:22:45.151 [info] Searching for oxlint binary. 2026-03-13 15:22:45.151 [info] Using server binary at: /Users/jordanboyer/Documents/home/project-medusa/node_modules/.pnpm/oxlint@1.55.0_oxlint-tsgolint@0.16.0/node_modules/oxlint/bin/oxlint 2026-03-13 15:22:45.151 [info] [Error - 3:22:45 PM] oxc client: couldn't create connection to server. 2026-03-13 15:22:45.151 [info] Launching server using command node failed. Error: spawn node ENOENT
I don't understand how to fix this from this PR if someone have a answer ^^'
Unfortunately the issue is not resolved. I resorted to adding the following lines to .vscode/settings.json to make the extension recognize vite.config.ts
Activity
linear commentedon Feb 25, 2026
VP-197
[-]Oxc LSP support[/-][+]Make oxc-vscode work with Vite+ environments[/+]leaysgur commentedon Feb 25, 2026
fengmk2 commentedon Feb 25, 2026
leaysgur commentedon Feb 25, 2026
leaysgur commentedon Feb 26, 2026
feat(cli): Install wrapper `bin/ox(lint|fmt)` for oxc-vscode (#633)
leaysgur commentedon Mar 6, 2026
Background
First, the Vite+ configuration file is a single file named
vite.config.tslocated at the root. Within this file, the keystest,lint, andfmtare nested.vp lintandvp fmtgenerate temporary config files at runtime to integrate with oxlint/oxfmt. This is because oxapps doesn't know aboutvite.config.ts, so even if you specify it with--config, it cannot be interpreted.However, this approach does not work for editor integrations (e.g., VSCode) where the LSP server needs persistent config files.
Option A: JSON Config Files (Project Root)
Serialize the vite.config content into
.oxlintrc.json/.oxfmtrc.jsonand place them at the project root. No changes needed on the oxc side, but keeping them in sync with vite.config is a challenge.Option B: oxlint/oxfmt Recognize vite.config Directly
oxlint/oxfmt natively read
vite.config.tsand extract the.lint/.fmtfields as their config source. This requires Vite+ knowledge to oxc side.👉🏻 This was rejected, oxapps should not know Vite+ specific usage.
Option C: Generic Config Field Extraction
Instead of being vite.config-aware, oxlint/oxfmt support extracting a specific field from any TS config file. e.g.,
oxlint -c vite.config.ts --config-field lint. Not Vite+-specific, so more likely to be accepted by oxc. This also works withpackage.json(e.g.,oxlint -c package.json --config-field oxlint), which is a well-established pattern used by tools like prettier and jest.Option D: Bridge Files (Project Root)
Place
oxlint.config.ts/oxfmt.config.tsat the project root that simply import vite.config and re-export the relevant field.Option E: Bridge Files (Hidden Location) + basePath
Place bridge files in a hidden location (e.g.,
node_modules/.vite-plus/) and add abasePathoption to oxlint/oxfmt so that relative paths are resolved from the project root instead of the file's actual location..oxlintrc.json,.oxfmtrc.jsonvite.config.tsvite.config.tsconfigFieldsupportconfigFieldsupport, TS config supportoxlint.config.ts,oxfmt.config.tsnode_modules/.vite-plus/basePathsupportbasePathsupportvp config synccommand? file watcher? pre-commit hook?)configPath+ watch is required. Editors which are using CLI directly also requires finding config, extracting field, etcfengmk2 commentedon Mar 6, 2026
leaysgur commentedon Mar 6, 2026
leaysgur commentedon Mar 9, 2026
Finally,
Option COption B: approved, TODOs are:.tsconfigvite.config.ts.lintvite.config.ts.lintfield oxc-project/oxc#20214vite.config.ts.fmtvite.config.*.fmtfield oxc-project/oxc#20197oxfmt.config."ts"only oxc-project/oxc#20216vp lint|fmt, just use--config vite.config.tsinstead--config?)leaysgur commentedon Mar 11, 2026
NOTE for the record:
Currently, Oxlint has 2 concepts to configuration files:
Nested configs are not used if
-coroxc.configPathis specified.And there are 2 types of uses for them:
First, when the CLI is executed:
Regarding
vite.config.ts, it used only as a root config and acts as a fallback if other.oxlintrc.json(c)oroxlint.config.tsare not found. (It is ignored when searching for nested configs).Next, in the case of LSP, the
cwdis based on the workspace folder opened by the user.The key point is that it differs slightly from the CLI, but the handling of
vite.config.tsis the same as the CLI; it is only considered as a root config.Oxfmt always uses a single configuration file and does not have the concept of nested configs.
Both the CLI and LSP search upwards from the current working directory.
vite.config.tsalso acts as a fallback if no other.oxfmtrc.json(c)oroxfmt.config.tsis found.The current issue is that, for both Oxlint and Oxfmt, the LSP sometimes finds a nested
vite.config.tsduring the process of searching for the root config.This is not an issue when
.lint|fmtis intentionally written, but in most other cases, it results in a ".lint|fmtdoes not exist" error.It should work with valid
.lint|fmtconfig one.But how...? Load js config and check key, then ignore if not exists...?
Or, if we only need to support root configs, then perhaps we could allow specifying the root config somehow when calling the wrapper with
--lsp...?👉🏻 This is fixed by just ignoring
vite.config.tsw/o.lint|fmt, anddefineConfig(fn)exports.To summarize, the remaining concerns we likely have at this point are:
vite.config.tsto be nested, but it's unclear if we want users to nest.lint|fmtconfigurationsvp lint|fmtwill always specify the rootvite.config.tsusing the-cflagvp run fmtin a subdirectory,oxfmtsearches for a higher-level configuration file, whileoxlintdoes notoxlintsearches for nested configurations (sincevp lintuses-c, it doesn't search for nested configurations)oxfmtrcor similar file is found along that path, it will be usedvite.config.tsuses function styledefineConfig(fn), oxapps cannot consume itvite.config.tsThese are issues that users may encounter for a while:
jordan-boyer commentedon Mar 13, 2026
I did install vite+ as my node manager. But now on older project that does not use vite+ the lsp for oxc doesn't work.
this is the output of the oxc plugin.
2026-03-13 15:22:45.151 [info] Searching for oxlint binary. 2026-03-13 15:22:45.151 [info] Using server binary at: /Users/jordanboyer/Documents/home/project-medusa/node_modules/.pnpm/oxlint@1.55.0_oxlint-tsgolint@0.16.0/node_modules/oxlint/bin/oxlint 2026-03-13 15:22:45.151 [info] [Error - 3:22:45 PM] oxc client: couldn't create connection to server. 2026-03-13 15:22:45.151 [info] Launching server using command node failed. Error: spawn node ENOENTI don't understand how to fix this from this PR if someone have a answer ^^'
feat: update oxfmt, oxlint to detect vite plus #4395
nickbutsky commentedon Jun 8, 2026
Unfortunately the issue is not resolved. I resorted to adding the following lines to
.vscode/settings.jsonto make the extension recognizevite.config.tsshannonmoeller commentedon Sep 8, 2026
This should be part of the default recommended vscode config for vite-plus. https://viteplus.dev/guide/ide-integration#vs-code