Replies: 12 comments 15 replies
-
|
Original file Options: Default Input: With a leading line comment before the export interface DirectiveArgumentNode extends ArrayExpression {
elements: // dir, exp, arg, modifiers
| [string]
| [string, ExpressionNode]
| [string, ExpressionNode, ExpressionNode]
| [string, ExpressionNode, ExpressionNode, ObjectExpression]
}Oxfmt output: export interface DirectiveArgumentNode extends ArrayExpression {
elements: // dir, exp, arg, modifiers
| [string]
| [string, ExpressionNode]
| [string, ExpressionNode, ExpressionNode]
| [string, ExpressionNode, ExpressionNode, ObjectExpression]
}Prettier output: export interface DirectiveArgumentNode extends ArrayExpression {
elements: // dir, exp, arg, modifiers
| [string]
| [string, ExpressionNode]
| [string, ExpressionNode, ExpressionNode]
| [string, ExpressionNode, ExpressionNode, ObjectExpression];
}Prettier output without export interface DirectiveArgumentNode extends ArrayExpression {
elements:
| [string]
| [string, ExpressionNode]
| [string, ExpressionNode, ExpressionNode]
| [string, ExpressionNode, ExpressionNode, ObjectExpression];
}The Oxfmt is exactly the same as Biome for this case, and we think the current Oxfmt output is better than Prettier's from a readability and consistency perspective. |
Beta Was this translation helpful? Give feedback.
-
|
Original file Options: Default Input: props[handlerName = toHandlerKey(event)]Oxfmt output: props[handlerName = toHandlerKey(event)]Prettier output: props[(handlerName = toHandlerKey(event))]The assignment inside the brackets of ComputedMemberExpression does not need to be wrapped in parentheses. There are no semantic changes regarding whether to wrap a parenthesis or not, and I have not found a reason why Prettier did it. |
Beta Was this translation helpful? Give feedback.
-
|
Input export default {
head: [
[
'meta', { name: 'robots', content: 'index, follow' },
],
[
'meta', { name: 'viewport', content: 'width=device-width, initial-scale=1.0' },
],
],
};oxfmt output: export default {
head: [
['meta', { name: 'robots', content: 'index, follow' }],
['meta', { name: 'viewport', content: 'width=device-width, initial-scale=1.0' }],
],
};Prettier output: export default {
head: [
['meta', { name: 'robots', content: 'index, follow' }],
[
'meta',
{ name: 'viewport', content: 'width=device-width, initial-scale=1.0' },
],
],
};
|
Beta Was this translation helpful? Give feedback.
-
I think this is great, because while Prettier is a great idea, sometimes it's just annoying and will produce some really weird-looking code. Another general problem with it is that sometimes small changes will 'cascade', i.e. you're changing a small thing and it'll rewrite 20 lines of code. I know this is vague, but hopefully still a decent description of this tendency. I realize it's not always possible to avoid, but still something where it would be neat if oxc handled it better. |
Beta Was this translation helpful? Give feedback.
-
|
Options: Default Input: const defaultColorDecoratorsEnablement = accessor
.get(IConfigurationService)
.getValue<"auto" | "always" | "never">(
"longlonglonglonglonglonglonglonglong",
);Oxfmt and Biome's output: const defaultColorDecoratorsEnablement = accessor
.get(IConfigurationService)
.getValue<"auto" | "always" | "never">(
"longlonglonglonglonglonglonglonglong",
);Prettier output: const defaultColorDecoratorsEnablement = accessor
.get(IConfigurationService)
.getValue<
"auto" | "always" | "never"
>("longlonglonglonglonglonglonglonglong");I found this case in the VSCode repo. From my first look, I think Oxfmt's output is prettier than Prettier's, but considering compatibility, I already fixed the issue in #14983. However, I suspect this is actually a bug in Prettier and wrote my thoughts in its description, so track the problem here. Learn more at #14983. |
Beta Was this translation helpful? Give feedback.
This comment has been hidden.
This comment has been hidden.
-
|
Couple of examples I'm seeing after trying oxfmt on large codebase.
|
Beta Was this translation helpful? Give feedback.
This comment has been hidden.
This comment has been hidden.
-
|
The array formatting case from @fengmk2 is a good example of where oxfmt does better. Prettier's inconsistent breaking (one array fits on one line, the other doesn't despite similar length) is confusing. I think the philosophy of "99.99% Prettier compatible but fix obvious issues" is the right approach. The key is documenting these intentional differences clearly so users aren't surprised when migrating. One suggestion: maybe create a dedicated docs page listing all intentional divergences with before/after examples? Would help users understand what to expect and make informed decisions about adopting oxfmt. |
Beta Was this translation helpful? Give feedback.
-
|
Reporting some minor prettier-ofmt differences I discovered. Overall the compatibly seems impressive (ran it over 40k+ files, had less than 50 differently formatted) :) Using prettier Prettier formatted reproduction: type SomeType<T> = any;
type OtherType = any;
const x = [].reduce(() => {
return "y";
}, {} as SomeType<OtherType>);Oxfmt formatted reproduction: type SomeType<T> = any;
type OtherType = any;
const x = [].reduce(
() => {
return "y";
},
{} as SomeType<OtherType>,
);I can only speculate it has something to do with the generic bracket notation |
Beta Was this translation helpful? Give feedback.
-
Beta Was this translation helpful? Give feedback.
-
Formatting differences found during real-world migration (NestJS monorepo, ~600 files)We migrated a large NestJS backend (~600 TS files, oxfmt version: 0.35.x Pattern 1:
|
| Pattern | Occurrences | Lines affected |
|---|---|---|
await import() wrapping |
~96 | ~288 |
| Import merging | ~6 | ~12 |
| Method chain wrapping | ~9 | ~27 |
| Total | ~111 | ~327 |
Out of ~600 TS files, 68 files (11%) had any formatting difference. The remaining 532 files were formatted identically to Prettier.
These are non-blocking for our migration — we accepted the oxfmt output. Just reporting for tracking purposes.
Beta Was this translation helpful? Give feedback.





Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
This issue tracks formatting differences between
OxfmtandPrettier, and documents decisions on whether to align or accept the differences.Background
Oxfmtis ported fromBiome, but we aim to makeOxfmt99.99% compatible withPrettierto ease migration pain. However, after testingOxfmton popular repositories, we've found cases wherePrettier's output looks weird or isn't "pretty" enough, and we believeOxfmtshould not align with those behaviors.Philosophy
Oxfmtis not trying to be another opinionated formatter. We are open to discussing different approaches and potentially producing output different from both currentOxfmtandPrettier. However, changes are impactful to thePrettierecosystem, so we'll carefully consider each difference.How We Decide
When evaluating differences, we consider:
Prettierrationale - Is there a documented reason forPrettier's behavior?Decisions are made through community discussion and core team review. We err on the side of
Prettiercompatibility unless there's a compelling reason to diverge.Bugs in Prettier
As of now, we've found a lot of prettier bugs that produced incorrect outputs, which caused the output to be different. Know more at Prettier
Important
Always assume that differences between prettier's output and
oxfmt's output are a bug, except when you find differences in the Prettier issues which we reported, or the cases already listed here. Please create a GitHub issue for those differences! If we decide that it is an expected output and better than prettier's output, then we will post here.Beta Was this translation helpful? Give feedback.
All reactions