## What
Ports the Relay `graphql` tagged template transform (babel-plugin-relay / swc_relay) as an individual napi transform, per #24914:
- **`crates/oxc_relay`** — the core transform as its own crate (modeled on `oxc_react_compiler`): replaces `graphql` tagged templates with references to relay-compiler artifacts. Definition names are extracted textually like `swc_relay` (equivalent to `\b(fragment|mutation|query|subscription)\s+(\w+)` with `#` comments stripped; hand-rolled scanner, no regex dependency).
- **`napi/transform-relay`** (`oxc-transform-relay`) — standalone napi package copied from the `napi/transform-react` template: parse → semantic → relay traverse → codegen. Only `graphql` tags are rewritten; TypeScript/JSX syntax is preserved untouched, so the output composes with any downstream toolchain.
## Options
| option | default | behavior |
|---|---|---|
| `artifactDirectory` | unset | when set, the import path is computed lexically relative to the transformed file (babel-plugin-relay `getRelativeImportPath` semantics — swc emits absolute paths instead); unset → `./__generated__/` next to the file |
| `language` | `javascript` | `typescript` imports `Name.graphql.ts`, otherwise `Name.graphql.js` |
| `eagerEsModules` | `true` | hoisted default imports (babel-plugin-relay ≥ v17 parity); `false` emits inline `require()` (`@swc/plugin-relay` / Next.js behavior) |
A `graphql` tag with no extractable definition name produces an error diagnostic (babel throws; swc silently skips).
Not supported, documented in both READMEs: dev-mode artifact hash validation, `jsModuleFormat: "haste"`, `isDevVariableName`, swc's Next.js-specific `projects`/`pagesDir`, and GraphQL document validation.
closes#24914
---
Implemented with Claude Code.
Prevents the internal `oxc_react_compiler` and
`oxc_transform_react_napi` Rust crates from being published while
including the `oxc-transform-react` npm package in workspace releases.
Validated with `taplo lint`, Cargo metadata, and `just ready`.
AI assistance was used for this change.
- Implement `oxc_formatter_css` crate
- Use `raffia` crate
- https://github.com/g-plane/raffia
- Supports CSS, LESS and SCSS
- Prettier uses `postcss` for parser
- https://github.com/prettier/prettier/blob/1c6ba5539141552e0e8e22d401ea620d8fdff468/package.json#L100-L105
Since design of `postcss`, this parser is very lenient with syntax.
Because of this, the AST is also less detailed, so formatting processes often rely on text-based.
On the other hand, `raffia` is relatively strict, so it cannot parse some postcss plugin syntax.
While this part clearly creates a difference from Prettier, we have judged that it is not an issue since it still supports major plugins syntax and aligns with current trends.
- Implement `oxc_formatter_graphql` crate
- Use `apollo-parser` crate from `apollo-rs`
- https://github.com/apollographql/apollo-rs
- Which follows Oct2021 spec
- Prettier uses `graphql-js` and implements more and more syntax
- v16 for `latest = 3.8.4` and v17 for `main = 3.9.x`
NOTE: So at the point of this PR, diffs can be seen as skipped in prettier_conformance.
Will be addressed in later PR by forking `apollo-parser`.
Part of #19704
In Prettier, there are 4 variants for JSON formatting.
- json 👈🏻 this
- jsonc
- json5
- json-stringify
Although Prettier calls "JSON", it doesn't strictly adhere to the JSON specification; in practice, it behaves more like JS...
To begin with, it uses `babel.parseExpression()`, which makes the input parsing very lenient. The output also doesn't necessarily conform to the specification—for instance, it allows comments and sometimes omits double quotes on keys.
Because of this, we are re-implementing it using `oxc_parser`. Since `parse_expression()` cannot capture comments, I've achieved this by wrapping the input in `()`.
Also considered adding JSON support to `oxc_formatter`, but I have decided NOT to for now. We may reconsider this once we have bothered on various edge cases.
Split `oxc_formatter` into:
- `oxc_formatter(_js)`: JS/TS specific formatter, comment handling, sortImports, jsdoc, etc
- `oxc_formatter_core`: Language agnostic IR, printer, etc
The naming convention is different from Biome or Ruff (they do not have `_core`, and `_formatter` is equivalent to the core), but this is because in Oxc, items without `_js` are the default.
As a basic task, I have added `Context` as a generic to all relevant parts to ensure support for multiple languages.
There might still be other components that could be refactored into the core, but I would like to finish them as I implement support for other languages.
Also moved some shared utilities to the core in advance.
Closes#19746.
Add `oxlint-plugin-eslint` plugin which exports all ESLint's built-in rules as a JS plugin which can be used with Oxlint.
The code for rules is lazy-loaded on first use, so just using the plugin doesn't load the code for all the rules, only the ones which the user actually uses. However, the `meta` property of each rule is provided eagerly, so that `registerPlugin` in Oxlint can load the plugin without triggering the getters which lazy-load rule code.
All ESLint's rule code is bundled into this plugin package, so the package has no dependencies. This has a few advantages:
1. We control the version of ESLint which the rules are taken from.
2. Avoids "works on my machine" unreproducible bug reports due to differing ESLint versions.
3. Avoids relying on ESLint's `eslint/use-at-your-own-risk` export, which could change without warning.
At present, the plugin contains *all* ESLint's rules, including ones which are natively implemented in Oxlint.
We might choose to scale it back to include only the rules which Oxlint doesn't natively implement. But then we need to consider what happens when we implement more rules in future: Do they disappear from this package without warning? Would that be considered a breaking change? If it would, how long do we keep them in this package?
I propose that in the interests of getting this useful feature released without having to decide all these issues, we just go with it as is for now. JS plugins are not yet stable, so at present we can still make changes later on if we need to, without breaking any promises.
#18824 added a `@oxlint/plugins` NPM package, and #18903 altered the
release workflow. It seems neither worked correctly - the package hasn't
been getting published during the release process.
It's still on version 1.43.0 on NPM:
https://www.npmjs.com/package/@oxlint/plugins
This PR alters the pre-release and release workflows to (hopefully) bump
version of this package and release it alongside `oxlint` package.
There have been no changes to content of `@oxlint/plugins` package since
the last published version, and it has no dependencies, so it doesn't
really matter that we've skipped these releases. But this PR should get
it publishing correctly from next release onwards.
## Summary
- Removes `editors/vscode` directory - code has been moved to
https://github.com/nicholasrice/oxc-vscode
- Removes `tasks/vscode_docs` crate (no longer needed)
- Removes CI and release workflows for VS Code extension
- Updates `editors/README.md` to point to the new repository
- Cleans up references in `.gitignore`, `justfile`, `oxc_release.toml`,
`oxfmtrc.jsonc`, `oxlintrc.json`, and `pnpm-workspace.yaml`
closes#17484🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Package version is used by NAPI-RS in the bindings file it generates.
Adapt the pre-release workflow to run NAPI-RS build when creating a release PR, so that the version number in bindings files matches the new version number.
This change covers all NAPI packages in `crates` pre-release workflow, and also `oxlint` in its pre-release workflow.