From a24878a1e23a08ccf9b68b88e8c8c82550862bc3 Mon Sep 17 00:00:00 2001
From: SUZUKI Sosuke
Date: Mon, 23 Jun 2025 11:04:03 +0900
Subject: [PATCH] 3.6 blog post (#17636)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: fisker
---
changelog_unreleased/blog-post-intro.md | 14 +
changelog_unreleased/javascript/17472.md | 4 +-
website/blog/2025-06-23-3.6.0.md | 1118 ++++++++++++++++++++++
3 files changed, 1133 insertions(+), 3 deletions(-)
create mode 100644 changelog_unreleased/blog-post-intro.md
create mode 100644 website/blog/2025-06-23-3.6.0.md
diff --git a/changelog_unreleased/blog-post-intro.md b/changelog_unreleased/blog-post-intro.md
new file mode 100644
index 000000000..a9a39ed08
--- /dev/null
+++ b/changelog_unreleased/blog-post-intro.md
@@ -0,0 +1,14 @@
+---
+authors: "sosukesuzuki"
+title: "Prettier 3.6: Experimental fast CLI and new OXC and Hermes plugins!"
+---
+
+This release includes several important feature additions that we're excited to share with you.
+
+First, we're shipping a new experimental high-performance CLI behind a feature flag (`--experimental-cli`). This CLI was previously only available in `prettier@next`, but now you can enable it simply by using a flag. We encourage you to try it out and share your feedback! If you are interested in the internal implementation, please read [Prettier's CLI: Performance Deep Dive by Fabio](https://prettier.io/blog/2023/11/30/cli-deep-dive).
+
+Additionally, we're releasing two new official plugins: [`@prettier/plugin-oxc`](https://github.com/prettier/prettier/tree/main/packages/plugin-oxc) and [`@prettier/plugin-hermes`](https://github.com/prettier/prettier/tree/main/packages/plugin-hermes). These plugins are provided separately from Prettier's core.
+
+We want to extend our heartfelt gratitude to everyone who made this amazing release possible: [@fabiospampinato](https://github.com/fabiospampinato), [@43081j](https://github.com/43081j), and [@pralkarz](https://github.com/pralkarz) along with the new CLI contributors, [@boshen](https://github.com/boshen) and [@overlookmotel](https://github.com/overlookmotel) along with other OXC contributors, the [Flow](https://flow.org/) and [Hermes](https://github.com/facebook/hermes/blob/main/README.md) teams at Meta. Thank you all for your incredible contributions!
+
+We're excited to see how these new features enhance your development experience. Happy formatting!
diff --git a/changelog_unreleased/javascript/17472.md b/changelog_unreleased/javascript/17472.md
index 3ed660964..94a228b7c 100644
--- a/changelog_unreleased/javascript/17472.md
+++ b/changelog_unreleased/javascript/17472.md
@@ -21,6 +21,4 @@ Due to package size limitations, this plugin is not included in the `prettier` p
For more information, check [the package homepage](https://github.com/prettier/prettier/tree/main/packages/plugin-oxc).
-
-
-Many thanks to the OXC team(@boshen, @overlookmotel, and other contributors).
+Many thanks to the OXC team([@boshen](https://github.com/boshen), [@overlookmotel](https://github.com/overlookmotel), and other contributors).
diff --git a/website/blog/2025-06-23-3.6.0.md b/website/blog/2025-06-23-3.6.0.md
new file mode 100644
index 000000000..62bfe4ded
--- /dev/null
+++ b/website/blog/2025-06-23-3.6.0.md
@@ -0,0 +1,1118 @@
+---
+authors: "sosukesuzuki"
+title: "Prettier 3.6: Experimental fast CLI and new OXC and Hermes plugins!"
+---
+
+This release includes several important feature additions that we're excited to share with you.
+
+First, we're shipping a new experimental high-performance CLI behind a feature flag (`--experimental-cli`). This CLI was previously only available in `prettier@next`, but now you can enable it simply by using a flag. We encourage you to try it out and share your feedback! If you are interested in the internal implementation, please read [Prettier's CLI: Performance Deep Dive by Fabio](https://prettier.io/blog/2023/11/30/cli-deep-dive).
+
+Additionally, we're releasing two new official plugins: [`@prettier/plugin-oxc`](https://github.com/prettier/prettier/tree/main/packages/plugin-oxc) and [`@prettier/plugin-hermes`](https://github.com/prettier/prettier/tree/main/packages/plugin-hermes). These plugins are provided separately from Prettier's core.
+
+We want to extend our heartfelt gratitude to everyone who made this amazing release possible: [@fabiospampinato](https://github.com/fabiospampinato), [@43081j](https://github.com/43081j), and [@pralkarz](https://github.com/pralkarz) along with the new CLI contributors, [@boshen](https://github.com/boshen) and [@overlookmotel](https://github.com/overlookmotel) along with other OXC contributors, the [Flow](https://flow.org/) and [Hermes](https://github.com/facebook/hermes/blob/main/README.md) teams at Meta. Thank you all for your incredible contributions!
+
+We're excited to see how these new features enhance your development experience. Happy formatting!
+
+
+
+## Highlights
+
+### JavaScript
+
+#### Added a new official plugin `@prettier/plugin-oxc` ([#17472](https://github.com/prettier/prettier/pull/17472), [#17483](https://github.com/prettier/prettier/pull/17483) by [@fisker](https://github.com/fisker)) {#change-17472}
+
+`@prettier/plugin-oxc` is based on [OXC](https://oxc.rs/)(A **fast** JavaScript and TypeScript parser in Rust).
+
+This plugin includes two new parsers `oxc` (JavaScript syntax) and `oxc-ts` (TypeScript syntax), to use this plugin:
+
+1. Install the plugin
+
+ ```sh
+ yarn add --dev prettier @prettier/plugin-oxc
+ ```
+
+2. Add the following to your `.prettierrc` file
+
+ ```yaml
+ plugins:
+ - "@prettier/plugin-oxc"
+ ```
+
+Due to package size limitations, this plugin is not included in the `prettier` package, it needs to be installed separately.
+
+For more information, check [the package homepage](https://github.com/prettier/prettier/tree/main/packages/plugin-oxc).
+
+Many thanks to the OXC team([@boshen](https://github.com/boshen), [@overlookmotel](https://github.com/overlookmotel), and other contributors).
+
+### Flow
+
+#### Added a new official plugin `@prettier/plugin-hermes` ([#17520](https://github.com/prettier/prettier/pull/17520) by [@fisker](https://github.com/fisker)) {#change-17520}
+
+`@prettier/plugin-hermes` is based on [Hermes JS Engine](https://github.com/facebook/hermes/blob/main/README.md).
+
+This plugin includes a new parser `hermes` (Flow syntax), to use this plugin:
+
+1. Install the plugin
+
+ ```sh
+ yarn add --dev prettier @prettier/plugin-hermes
+ ```
+
+2. Add the following to your `.prettierrc` file
+
+ ```yaml
+ plugins:
+ - "@prettier/plugin-hermes"
+ ```
+
+Due to package size limitations, this plugin is not included in the `prettier` package, it needs to be installed separately.
+
+**We plan to make this as the default parser for Flow syntax support in v4, we'll also remove `babel-flow` parser in v4, please give it a try.**
+
+For more information, check [the package homepage](https://github.com/prettier/prettier/tree/main/packages/plugin-hermes).
+
+Many thanks to the Hermes team.
+
+### CLI
+
+#### Support experimental CLI ([#17151](https://github.com/prettier/prettier/pull/17151), [#17396](https://github.com/prettier/prettier/pull/17396) by [@fisker](https://github.com/fisker)) {#change-17151}
+
+You may have already heard of or used our new [performance improved CLI](https://prettier.io/blog/2023/11/30/cli-deep-dive). From Prettier 3.6, you can now use it without installing unstable v4 version.
+
+```sh
+# Run CLI with `--experimental-cli`
+prettier . --check --experimental-cli
+
+# Or use environment variable `PRETTIER_EXPERIMENTAL_CLI=1`
+PRETTIER_EXPERIMENTAL_CLI=1 prettier . --check
+```
+
+## Other Changes
+
+### JavaScript
+
+#### Add parentheses to `SequenceExpression` in `ReturnStatement` and `ExpressionStatement` ([#17085](https://github.com/prettier/prettier/pull/17085) by [@TYKevin](https://github.com/TYKevin)) {#change-17085}
+
+
+```jsx
+// Input
+function a() {
+ return ( a, b)
+}
+
+(a(), b());
+
+// Prettier 3.5
+function a() {
+ return a, b;
+}
+
+a(), b();
+
+// Prettier 3.6
+function a() {
+ return (a, b);
+}
+
+(a(), b());
+```
+
+#### Add parentheses to `AssignmentExpression` in class property keys ([#17145](https://github.com/prettier/prettier/pull/17145) by [@fisker](https://github.com/fisker)) {#change-17145}
+
+Previously we only add parentheses to `AssignmentExpression` in object keys, but not in class property keys. Thanks to [Biome](https://biomejs.dev/formatter/differences-with-prettier/#prettier-has-an-inconsistent-behavior-for-assignment-in-computed-keys) for bringing our attention to this inconsistency.
+
+
+```jsx
+// Input
+a = {
+ [(x = "key")]: 1,
+}
+
+class A {
+ [(x = "property")] = 1;
+ [(x = "method")]() {}
+}
+
+// Prettier 3.5
+a = {
+ [(x = "key")]: 1,
+};
+
+class A {
+ [x = "property"] = 1;
+ [(x = "method")]() {}
+}
+
+// Prettier 3.6
+a = {
+ [(x = "key")]: 1,
+};
+
+class A {
+ [(x = "property")] = 1;
+ [(x = "method")]() {}
+}
+```
+
+#### Add parentheses to numbers in optional member expression ([#17190](https://github.com/prettier/prettier/pull/17190) by [@fisker](https://github.com/fisker)) {#change-17190}
+
+There is an inconsistency when formatting member expression where the object is a number before Prettier 3.6.
+
+When using `babel` parser(and other Babel based parsers), we print the number as unparenthesized, when using `typescript` parser(and other ESTree parsers), we print it as parenthesized.
+
+Technically parentheses are not needed, but if we print it as `1?.toString()` and later users realize it's unnecessary to use `?.`, users can't simply remove the question mark because `1.toString()` will raise a `SyntaxError`, for this reason, we decide to always put parentheses around it.
+
+
+```jsx
+// Input
+(1)?.toString();
+(1.5)?.toString();
+
+// Prettier 3.5 (--parser=babel)
+1?.toString();
+1.5?.toString();
+
+// Prettier 3.5 (--parser=typescript)
+(1)?.toString();
+(1.5)?.toString();
+
+// Prettier 3.6
+(1)?.toString();
+(1.5)?.toString();
+```
+
+#### Removed support for experimental `Records & Tuples` ([#17363](https://github.com/prettier/prettier/pull/17363) by [@fisker](https://github.com/fisker)) {#change-17363}
+
+The ES proposal [JavaScript Records & Tuples Proposal](https://github.com/tc39/proposal-record-tuple) has been withdrawn.
+
+- [Disclaimer about non-standard syntax](https://prettier.io/docs/en/rationale.html#disclaimer-about-non-standard-syntax)
+
+#### Preserve spaces between CSS words and embedded expression ([#17398](https://github.com/prettier/prettier/pull/17398) by [@sosukesuzuki](https://github.com/sosukesuzuki)) {#change-17398}
+
+
+```jsx
+// Input
+const Heading = styled.h1`
+ font-size: var(--font-size-h${level});
+`;
+
+// Prettier 3.5
+const Heading = styled.h1`
+ font-size: var(--font-size-h ${level});
+`;
+
+// Prettier 3.6
+const Heading = styled.h1`
+ font-size: var(--font-size-h${level});
+`;
+```
+
+#### Fix inconsistent assignment format ([#17469](https://github.com/prettier/prettier/pull/17469) by [@fisker](https://github.com/fisker)) {#change-17469}
+
+
+```jsx
+// Input
+didScheduleRenderPhaseUpdateDuringThisPassFoo = didScheduleRenderPhaseUpdate = true
+
+// Prettier 3.5 (--parser=babel)
+didScheduleRenderPhaseUpdateDuringThisPassFoo =
+ didScheduleRenderPhaseUpdate = true;
+
+// Prettier 3.5 (--parser=typescript)
+didScheduleRenderPhaseUpdateDuringThisPassFoo = didScheduleRenderPhaseUpdate =
+ true;
+
+// Prettier 3.6
+didScheduleRenderPhaseUpdateDuringThisPassFoo =
+ didScheduleRenderPhaseUpdate = true;
+```
+
+#### Fix inconsistent member chain format ([#17470](https://github.com/prettier/prettier/pull/17470) by [@fisker](https://github.com/fisker)) {#change-17470}
+
+
+```jsx
+// Input
+s.get(u)?.trigger({ triggerKind: y.SignatureHelpTriggerKind.InvokeFooBarBaz123 });
+
+// Prettier 3.5 (--parser=babel)
+s.get(u)?.trigger({
+ triggerKind: y.SignatureHelpTriggerKind.InvokeFooBarBaz123,
+});
+
+// Prettier 3.5 (--parser=typescript)
+s
+ .get(u)
+ ?.trigger({ triggerKind: y.SignatureHelpTriggerKind.InvokeFooBarBaz123 });
+
+// Prettier 3.6
+s.get(u)?.trigger({
+ triggerKind: y.SignatureHelpTriggerKind.InvokeFooBarBaz123,
+});
+```
+
+#### Fix optional chaining as computed key ([#17486](https://github.com/prettier/prettier/pull/17486) by [@fisker](https://github.com/fisker)) {#change-17486}
+
+
+```jsx
+// Input
+const a = { [y?.z]() {} };
+class A { [y?.z]() {} };
+
+// Prettier 3.5
+const a = { [y?.z]?() {} };
+class A {
+ [y?.z]?() {}
+}
+
+// Prettier 3.6
+const a = { [y?.z]() {} };
+class A {
+ [y?.z]() {}
+}
+```
+
+#### Support type cast comments for `acorn` and `meriyah` parser ([#17491](https://github.com/prettier/prettier/pull/17491), [#17566](https://github.com/prettier/prettier/pull/17566) by [@ArnaudBarre](https://github.com/ArnaudBarre), [#17600](https://github.com/prettier/prettier/pull/17600) by #fisker) {#change-17491}
+
+This was previously only supported by the Babel parser.
+
+
+```js
+// Input
+/** @type {MyType} */ (x).foo;
+
+// Prettier 3.5 (--parser=acorn|meriyah)
+/** @type {MyType} */ x.foo;
+
+// Prettier 3.6
+/** @type {MyType} */ (x).foo;
+```
+
+#### Fix unstable comment format in tagged template literal ([#17510](https://github.com/prettier/prettier/pull/17510) by [@fisker](https://github.com/fisker)) {#change-17510}
+
+
+```js
+// Input
+foo
+ // Comment
+ `x`
+
+// Prettier 3.5 (First format)
+foo// Comment
+`x`;
+
+// Prettier 3.5 (Second format)
+foo // Comment
+`x`;
+
+// Prettier 3.6
+foo // Comment
+`x`;
+```
+
+#### Improve consistency for JSX in optional method call ([#17616](https://github.com/prettier/prettier/pull/17616) by [@seiyab](https://github.com/seiyab)) {#change-17616}
+
+
+```jsx
+// Input
+
+
+ {Array(20)
+ .fill()
+ ?.map((_, i) => (
+
{i + 1}
+ ))}
+
+;
+
+// Prettier 3.5 (ESTree based parsers like espree and typescript)
+
+
+ {Array(20)
+ .fill()
+ ?.map((_, i) =>
{i + 1}
)}
+
+;
+
+// Prettier 3.5 (babel and babel-ts parser)
+
+
+ {Array(20)
+ .fill()
+ ?.map((_, i) => (
+
{i + 1}
+ ))}
+
+;
+
+// Prettier 3.6 (parsers of both types)
+
+
+ {Array(20)
+ .fill()
+ ?.map((_, i) => (
+
{i + 1}
+ ))}
+
+;
+```
+
+### TypeScript
+
+#### Support import type attribute in `TSImportType` ([#16881](https://github.com/prettier/prettier/pull/16881) by [@fisker](https://github.com/fisker)) {#change-16881}
+
+
+```jsx
+// Input
+type A = import("foo", {with: {type: "json"}})
+
+// Prettier 3.5
+type A = import("foo")
+
+// Prettier 3.6
+type A = import("foo", { with: { type: "json" } });
+```
+
+#### Fix comments in logical expression and intersection type ([#17193](https://github.com/prettier/prettier/pull/17193) by [@fisker](https://github.com/fisker)) {#change-17193}
+
+
+```jsx
+// Input
+export type ErrorLike =
+ SerializedProps &
+ // cause is a new addition to Error that is not yet available in all runtimes. We have added
+ // it to try and pinpoint additional reasoning for failures such as Node's fetch.
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/cause
+ { cause?: unknown };
+
+// Prettier 3.5
+export type ErrorLike =
+ SerializedProps & // cause is a new addition to Error that is not yet available in all runtimes. We have added
+ // it to try and pinpoint additional reasoning for failures such as Node's fetch.
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/cause
+ { cause?: unknown };
+
+// Prettier 3.5 (second format)
+export type ErrorLike =
+ SerializedProps & // it to try and pinpoint additional reasoning for failures such as Node's fetch. // cause is a new addition to Error that is not yet available in all runtimes. We have added
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/cause
+ { cause?: unknown };
+
+// Prettier 3.6
+export type ErrorLike = SerializedProps &
+ // cause is a new addition to Error that is not yet available in all runtimes. We have added
+ // it to try and pinpoint additional reasoning for failures such as Node's fetch.
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/cause
+ { cause?: unknown };
+```
+
+#### Improve new line detect in mapped type ([#17498](https://github.com/prettier/prettier/pull/17498) by [@fisker](https://github.com/fisker)) {#change-17498}
+
+
+```jsx
+// Input
+type A = { readonly
+ [A in B]: T}
+
+// Prettier 3.5
+type A = {
+ readonly [A in B]: T;
+};
+
+// Prettier 3.6
+type A = { readonly [A in B]: T };
+```
+
+#### Don't print extra semicolon after `prettier-ignore`d index-signature ([#17538](https://github.com/prettier/prettier/pull/17538) by [@sosukesuzuki](https://github.com/sosukesuzuki)) {#change-17538}
+
+
+```tsx
+// Input
+type foo = {
+ // prettier-ignore
+ [key: string]: bar;
+};
+
+// Prettier 3.5
+type foo = {
+ // prettier-ignore
+ [key: string]: bar;;
+};
+
+// Prettier 3.6
+type foo = {
+ // prettier-ignore
+ [key: string]: bar;
+};
+```
+
+### Flow
+
+#### Fix missing parentheses in `ConditionalTypeAnnotation` ([#17196](https://github.com/prettier/prettier/pull/17196) by [@fisker](https://github.com/fisker)) {#change-17196}
+
+
+```jsx
+// Input
+type T = 'a' | ('b' extends U ? 'c' : empty);
+type T = 'a' & ('b' extends U ? 'c' : empty);
+
+// Prettier 3.5
+type T = "a" | "b" extends U ? "c" : empty;
+type T = "a" & "b" extends U ? "c" : empty;
+
+// Prettier 3.6
+type T = "a" | ("b" extends U ? "c" : empty);
+type T = "a" & ("b" extends U ? "c" : empty);
+```
+
+### JSON
+
+#### Allow format comment-only JSONC files ([#17269](https://github.com/prettier/prettier/pull/17269) by [@fisker](https://github.com/fisker)) {#change-17269}
+
+
+```jsonc
+// Input
+// Comment
+
+// Prettier 3.5
+SyntaxError: Unexpected token (1:11)
+> 1 | // Comment
+ | ^
+
+// Prettier 3.6
+// Comment
+```
+
+#### Forbid parenthesized expressions ([#17598](https://github.com/prettier/prettier/pull/17598) by [@fisker](https://github.com/fisker)) {#change-17598}
+
+
+```json
+// Input
+[1, (2)]
+
+// Prettier 3.5
+[1, 2]
+
+// Prettier 3.6
+SyntaxError: 'ParenthesizedExpression' is not allowed in JSON. (1:5)
+> 1 | [1, (2)]
+ | ^^^
+```
+
+### CSS
+
+#### Support `@utility` directive for Tailwind ([#17362](https://github.com/prettier/prettier/pull/17362) by [@sosukesuzuki](https://github.com/sosukesuzuki)) {#change-17362}
+
+This change supports `@utility` directive for Tailwind CSS V4.
+
+
+```css
+/* Input */
+@utility tab-* {
+ tab-size: --value(--tab-size-*);
+}
+
+/* Prettier 3.5 */
+@utility tab-* {
+ tab-size: --value(--tab-size- *);
+}
+
+/* Prettier 3.6 */
+@utility tab-* {
+ tab-size: --value(--tab-size-*);
+}
+```
+
+#### Remove extra indentation for `:has` pseudo call ([#17541](https://github.com/prettier/prettier/pull/17541) by [@sosukesuzuki](https://github.com/sosukesuzuki)) {#change-17541}
+
+
+```css
+/* Input */
+li:has(
+ path[d="M544,272H480V150.627L523.314,107.314A16,16,0,0,0,500.686,84.687L457.373,128H415a127.00381,127.00381,0,1,0-254,0H118.627L75.314,84.687A16,16,0,1,0,52.686,107.314L96,150.627V272H32a16,16,0,0,0,0,32H96v24a174.98856,174.98856,0,0,0,30.484,98.889L68.687,484.686a15.99972,15.99972,0,1,0,22.627,22.627l55.616-55.616A175.45165,175.45165,0,0,0,272,504h32a175.45165,175.45165,0,0,0,125.07-52.303l55.616,55.616a15.99972,15.99972,0,0,0,22.627-22.627l-57.797-57.797A174.98856,174.98856,0,0,0,480,328V304h64a16,16,0,0,0,0-32ZM288,32.01263A95.99568,95.99568,0,0,1,383,128H193A95.99568,95.99568,0,0,1,288,32.01263ZM448,328c0,79.401-64.598,144-144,144V236a12.00052,12.00052,0,0,0-12-12h-8a12.00052,12.00052,0,0,0-12,12V472c-79.402,0-144-64.599-144-144V160H448Z"]
+) {
+ display: none;
+}
+
+/* Prettier 3.5 */
+li:has(
+ path[d="M544,272H480V150.627L523.314,107.314A16,16,0,0,0,500.686,84.687L457.373,128H415a127.00381,127.00381,0,1,0-254,0H118.627L75.314,84.687A16,16,0,1,0,52.686,107.314L96,150.627V272H32a16,16,0,0,0,0,32H96v24a174.98856,174.98856,0,0,0,30.484,98.889L68.687,484.686a15.99972,15.99972,0,1,0,22.627,22.627l55.616-55.616A175.45165,175.45165,0,0,0,272,504h32a175.45165,175.45165,0,0,0,125.07-52.303l55.616,55.616a15.99972,15.99972,0,0,0,22.627-22.627l-57.797-57.797A174.98856,174.98856,0,0,0,480,328V304h64a16,16,0,0,0,0-32ZM288,32.01263A95.99568,95.99568,0,0,1,383,128H193A95.99568,95.99568,0,0,1,288,32.01263ZM448,328c0,79.401-64.598,144-144,144V236a12.00052,12.00052,0,0,0-12-12h-8a12.00052,12.00052,0,0,0-12,12V472c-79.402,0-144-64.599-144-144V160H448Z"]
+ ) {
+ display: none;
+}
+
+/* Prettier 3.6 */
+li:has(
+ path[d="M544,272H480V150.627L523.314,107.314A16,16,0,0,0,500.686,84.687L457.373,128H415a127.00381,127.00381,0,1,0-254,0H118.627L75.314,84.687A16,16,0,1,0,52.686,107.314L96,150.627V272H32a16,16,0,0,0,0,32H96v24a174.98856,174.98856,0,0,0,30.484,98.889L68.687,484.686a15.99972,15.99972,0,1,0,22.627,22.627l55.616-55.616A175.45165,175.45165,0,0,0,272,504h32a175.45165,175.45165,0,0,0,125.07-52.303l55.616,55.616a15.99972,15.99972,0,0,0,22.627-22.627l-57.797-57.797A174.98856,174.98856,0,0,0,480,328V304h64a16,16,0,0,0,0-32ZM288,32.01263A95.99568,95.99568,0,0,1,383,128H193A95.99568,95.99568,0,0,1,288,32.01263ZM448,328c0,79.401-64.598,144-144,144V236a12.00052,12.00052,0,0,0-12-12h-8a12.00052,12.00052,0,0,0-12,12V472c-79.402,0-144-64.599-144-144V160H448Z"]
+) {
+ display: none;
+}
+```
+
+### Less
+
+#### Fix function argument incorrectly lowercased ([#17502](https://github.com/prettier/prettier/pull/17502) by [@fisker](https://github.com/fisker)) {#change-17502}
+
+
+```less
+// Input
+.what {
+ .make-modifier(1A, "1a.png");
+ .make-modifier(AA, "1a.png");
+}
+
+// Prettier 3.5
+.what {
+ .make-modifier(1a, "1a.png");
+ .make-modifier(AA, "1a.png");
+}
+
+// Prettier 3.6
+.what {
+ .make-modifier(1A, "1a.png");
+ .make-modifier(AA, "1a.png");
+}
+```
+
+### HTML
+
+#### Fix formatting when tag name is an object prototype property ([#17501](https://github.com/prettier/prettier/pull/17501) by [@fisker](https://github.com/fisker)) {#change-17501}
+
+
+```html
+
+
+ text
+
+
+
+TypeError: Vn(...).startsWith is not a function
+
+
+ text
+```
+
+### Angular
+
+#### Support `TemplateLiteral` introduced in Angular 19.2 ([#17238](https://github.com/prettier/prettier/pull/17238) by [@fisker](https://github.com/fisker)) {#change-17238}
+
+Angular 29.2 added [support for `TemplateLiteral`](https://blog.angular.dev/angular-19-2-is-now-available-673ec70aea12#ed7b).
+
+
+```html
+
+{{ `Hello, ${
+getName('world')}` }}
+
+
+
+ {{ `Hello, ${
+getName('world')}` }}
+
+
+
+{{ `Hello, ${getName("world")}` }}
+```
+
+#### Remove extra colon after `track` in angular `@for` control-flow ([#17280](https://github.com/prettier/prettier/pull/17280) by [@claudio-herger](https://github.com/claudio-herger)) {#change-17280}
+
+
+```angular
+// Input
+@for (item of items; let i = $index; let count = $count; track block) {}
+
+// Prettier 3.5
+@for (item of items; let i = $index; let count = $count; track: block) {}
+
+// Prettier 3.6
+@for (item of items; let i = $index; let count = $count; track block) {}
+```
+
+#### Support Angular 20 ([#17534](https://github.com/prettier/prettier/pull/17534) by [@fisker](https://github.com/fisker)) {#change-17534}
+
+
+```angular
+// Input
+{{
+ ( (a in (b)))
+}}
+{{
+ ( (tag ` a ${ b } \u0063 `))
+}}
+{{
+ ( (` a ${ b } \u0063 `))
+}}
+{{ void(1 + 2) }}
+
+// Prettier 3.5
+The new syntax is not correctly recognized.
+
+// Prettier 3.6
+{{ a in b }}
+{{ tag` a ${b} \u0063 ` }}
+{{ ` a ${b} \u0063 ` }}
+{{ void (1 + 2) }}
+```
+
+### MJML
+
+#### Enabling CSS formatting within `` tag ([#17338](https://github.com/prettier/prettier/pull/17338) by [@iryusa](https://github.com/iryusa)) {#change-17338}
+
+
+```mjml
+
+
+.hello {
+ color: blue;
+ border: 1px solid blue;
+font-size:12px;
+} p { font-size: 14px; }
+
+
+
+
+ .hello { color: blue; border: 1px solid blue; font-size:12px; } p { font-size:
+ 14px; }
+
+
+
+
+ .hello {
+ color: blue;
+ border: 1px solid blue;
+ font-size: 12px;
+ }
+ p {
+ font-size: 14px;
+ }
+
+```
+
+#### Correctly parse `` and `` ([#17400](https://github.com/prettier/prettier/pull/17400) by [@fisker](https://github.com/fisker)) {#change-17400}
+
+
+```html
+
+
+ a::before {
+ content: "";
+ }
+
+
+
+SyntaxError: Unexpected closing tag "p".
+
+
+Correctly parsed as CSS.
+```
+
+### Markdown
+
+#### Fix adjacent markdown syntax in blockquote ([#16596](https://github.com/prettier/prettier/pull/16596) by [@fiji-flo](https://github.com/fiji-flo)) {#change-16596}
+
+
+```md
+
+> `x`
+> `y`
+
+> _x_
+> _y_
+
+> [foo](http://foo)
+> [bar](http://bar)
+
+> `this` behaves
+> `correctly`
+
+
+> `x` > `y`
+
+> _x_ > _y_
+
+> [foo](http://foo) > [bar](http://bar)
+
+> `this` behaves `correctly`
+
+
+> `x` `y`
+
+> _x_ _y_
+
+> [foo](http://foo) [bar](http://bar)
+
+> `this` behaves `correctly`
+```
+
+#### Fix markdown inserts unexpected newline in lists ([#16637](https://github.com/prettier/prettier/pull/16637) by [@byplayer](https://github.com/byplayer)) {#change-16637}
+
+
+```md
+
+- Level 1
+ - Level 1-1
+
+- Level 2
+
+
+- Level 1
+
+ - Level 1-1
+
+- Level 2
+
+
+
+- Level 1
+ - Level 1-1
+
+- Level 2
+
+```
+
+#### Fix strong emphasis ([#17143](https://github.com/prettier/prettier/pull/17143) by [@fiji-flo](https://github.com/fiji-flo)) {#change-17143}
+
+Most markdown implementations don't support `1**_2_**3` so prefer `1***2**3`.
+
+
+```md
+
+1***2***3
+1**_2_**3
+
+
+1**_2_**3
+1**_2_**3
+
+
+1***2***3
+1***2***3
+```
+
+### YAML
+
+#### Do not add line break before empty map or sequence ([#16074](https://github.com/prettier/prettier/pull/16074) by [@BapRx](https://github.com/BapRx)) {#change-16074}
+
+
+```yaml
+# Input
+---
+myDict: {}
+ # comment
+myList: []
+ # comment
+
+# Prettier 3.5
+---
+myDict:
+ {}
+ # comment
+myList:
+ []
+ # comment
+
+# Prettier 3.6
+---
+myDict: {}
+ # comment
+myList: []
+ # comment
+```
+
+### API
+
+#### Accept `URL` in `plugins` option ([#17166](https://github.com/prettier/prettier/pull/17166) by [@fisker](https://github.com/fisker)) {#change-17166}
+
+`plugins` option now accepts [URL](https://developer.mozilla.org/en-US/docs/Web/API/URL) with `file:` protocol or a url string that starts with `file:` in all public APIs.
+
+```js
+// `URL`
+await prettier.check("foo", {
+ parser: "my-cool-parser",
+ plugins: [new URL("./path/to/plugin.js", import.meta.url)],
+});
+await prettier.format("foo", {
+ parser: "my-cool-parser",
+ plugins: [new URL("./path/to/plugin.js", import.meta.url)],
+});
+await prettier.formatWithCursor("foo", {
+ parser: "my-cool-parser",
+ cursorOffset: 2,
+ plugins: [new URL("./path/to/plugin.js", import.meta.url)],
+});
+await prettier.getFileInfo("/path/to/file", {
+ plugins: [new URL("./path/to/plugin.js", import.meta.url)],
+});
+await prettier.getSupportInfo({
+ plugins: [new URL("./path/to/plugin.js", import.meta.url)],
+});
+
+// URL string
+await prettier.check("foo", {
+ parser: "my-cool-parser",
+ plugins: ["file:///path/to/plugin.js"],
+});
+await prettier.format("foo", {
+ parser: "my-cool-parser",
+ plugins: ["file:///path/to/plugin.js"],
+});
+await prettier.formatWithCursor("foo", {
+ parser: "my-cool-parser",
+ cursorOffset: 2,
+ plugins: ["file:///path/to/plugin.js"],
+});
+await prettier.getFileInfo("/path/to/file", {
+ plugins: ["file:///path/to/plugin.js"],
+});
+await prettier.getSupportInfo({
+ plugins: ["file:///path/to/plugin.js"],
+});
+```
+
+#### Accept `URL` as custom config file in `resolveConfig` ([#17167](https://github.com/prettier/prettier/pull/17167) by [@fisker](https://github.com/fisker)) {#change-17167}
+
+[`prettier.resolveConfig()`](https://prettier.io/docs/api#prettierresolveconfigfileurlorpath--options) now accepts an [URL](https://developer.mozilla.org/en-US/docs/Web/API/URL) with `file:` protocol or a url string that starts with `file:` as custom config file location.
+
+```js
+// `URL`
+await prettier.resolveConfig("path/to/file", {
+ config: new URL("/path/to/prettier-config-file", import.meta.url),
+});
+
+// URL string
+await prettier.resolveConfig("path/to/file", {
+ config: "file:///path/to/prettier-config-file",
+});
+```
+
+#### Stop interpret `*.frag` files as JavaScript files ([#17178](https://github.com/prettier/prettier/pull/17178) by [@fisker](https://github.com/fisker)) {#change-17178}
+
+`*.frag` was interpreted as JavaScript files, but `.frag` is also used in GLSL([OpenGL Shading Language](https://en.wikipedia.org/wiki/OpenGL_Shading_Language)). It causes error when Prettier try to format them as JavaScript files.
+
+Since Prettier 3.6, `*.frag` files except `*.start.frag`, `*.end.frag`, `start.frag`, and `end.frag` are no longer treated as JavaScript files.
+
+If you have JavaScript files with `.frag` that do not match the patterns mentioned above, you can config with `overrides`.
+
+```js
+export default {
+ overrides: {
+ files: "**/*.frag",
+ options: {
+ parser: "babel",
+ },
+ },
+};
+```
+
+#### Add `isSupported` function support for `languages` API ([#17331](https://github.com/prettier/prettier/pull/17331) by [@JounQin](https://github.com/JounQin), [#17490](https://github.com/prettier/prettier/pull/17490) by [@fisker](https://github.com/fisker)) {#change-17331}
+
+Previously, `languages` API for custom plugins only supported inferring parser based on the file basename or extension.
+
+Prettier 3.6 added `isSupported: (options: { filepath: string }) => boolean` function to allow plugin check if file is supported based on the full path (eg: files in a specific directory).
+
+:::note
+
+Prettier can not ensure that `filepath` exists on disk.\
+When using from APIs(eg: `prettier.format()`), Prettier can not ensure it's a valid path either.
+
+:::
+
+If no `isSupported` provided, it just behaves the same way as before.
+
+```js
+export const languages = [
+ {
+ name: "foo",
+ parsers: ["foo"],
+ isSupported: ({ filepath }) => filepath.includes(".foo"),
+ },
+];
+```
+
+#### Add `mjml` parser ([#17339](https://github.com/prettier/prettier/pull/17339) by [@fisker](https://github.com/fisker)) {#change-17339}
+
+We already support [MJML](https://mjml.io/) in previous version with `html` parser, in order to distinguish MJML-specific a new `mjml` parser added.
+
+#### Ignore files with `--check-ignore-pragma` ([#17344](https://github.com/prettier/prettier/pull/17344) by [@wnayes](https://github.com/wnayes)) {#change-17344}
+
+Individual files can now opt out of formatting via `@noformat` or `@noprettier` "pragma" comments at the top of the file.
+
+To enable this feature, use the new option [`--check-ignore-pragma`](https://prettier.io/docs/options#check-ignore-pragma) (`checkIgnorePragma` via configuration or API).
+
+Language plugins can [implement support](https://prettier.io/docs/plugins#parsers) for this feature. Most built-in parsers, including JavaScript (TypeScript), CSS, HTML, JSON, Markdown (MDX), YAML, and GraphQL, were updated to support this feature.
+
+
+```jsx
+/**
+ * @noformat
+ */
+
+export default matrix(
+ 1, 0, 0,
+ 0, 1, 0,
+ 0, 0, 1
+);
+```
+
+#### Fix plugin loading in `prettier.getFileInfo()` ([#17548](https://github.com/prettier/prettier/pull/17548) by [@fisker](https://github.com/fisker)) {#change-17548}
+
+In previous version, `prettier.getFileInfo()` only read `parser` config from `.prettierrc`, but doesn't load plugins to infer parser from plugin `languages`, Prettier 3.6 fixed it.
+
+```js
+// prettier-plugin-foo
+export const languages = [
+ {
+ parsers: ["foo"],
+ extensions: [".foo"],
+ },
+];
+```
+
+```yaml
+# .prettierrc
+plugins:
+ - prettier-plugin-foo
+```
+
+```console
+prettier --file-info file.foo
+
+# Prettier 3.5
+{ "ignored": false, "inferredParser": null }
+
+# Prettier 3.6
+{ "ignored": false, "inferredParser": "foo" }
+```
+
+#### Allow plugin to override builtin parsers when inferring parser ([#17549](https://github.com/prettier/prettier/pull/17549) by [@fisker](https://github.com/fisker)) {#change-17549}
+
+Previously when inferring parser for file, builtin plugins are checked first, so plugins are not able to override parsers for files like `.js`.
+
+```js
+// prettier-plugin-foo
+export const languages = [
+ {
+ parsers: ["foo"],
+ extensions: [".js"],
+ },
+];
+```
+
+```js
+// prettier.config.js
+import * as prettierPluginFoo from "prettier-plugin-foo";
+
+export default {
+ plugins: [prettierPluginFoo],
+};
+```
+
+```console
+prettier --file-info file.js
+
+# Prettier 3.5
+{ "ignored": false, "inferredParser": "babel" }
+
+# Prettier 3.6
+{ "ignored": false, "inferredParser": "foo" }
+```
+
+### CLI
+
+#### Forbid use `--config` and `--no-config` together ([#12221](https://github.com/prettier/prettier/pull/12221) by [@Balastrong](https://github.com/Balastrong)) {#change-12221}
+
+```console
+$ prettier --config=.prettierrc --no-config .
+[error] Cannot use --no-config and --config together.
+```
+
+#### Ignore file modified time when `--cache-strategy=content` ([#17438](https://github.com/prettier/prettier/pull/17438) by [@fisker](https://github.com/fisker)) {#change-17438}
+
+In previous version, when using `--cache-strategy=content`, if the file modified time changed, it still gets re-formatted even the file content didn't change, Prettier 3.6 fixed it.
+
+#### Fix result message for files can not be formatted ([#17505](https://github.com/prettier/prettier/pull/17505) by [@fisker](https://github.com/fisker)) {#change-17505-2}
+
+```console
+touch unknown
+prettier --check unknown
+
+# Prettier 3.5
+Checking formatting...
+unknown
+[error] No parser could be inferred for file "".
+All matched files use Prettier code style!
+
+# Prettier 3.6
+Checking formatting...
+unknown
+[error] No parser could be inferred for file "".
+Error occurred when checking code style in the above file.
+```
+
+#### Fix exitCode when parser cannot infer ([#17505](https://github.com/prettier/prettier/pull/17505) by [@fisker](https://github.com/fisker)) {#change-17505}
+
+```console
+touch unknown
+prettier --check unknown > /dev/null;echo $?
+
+# Prettier 3.5
+[error] No parser could be inferred for file "".
+0
+
+# Prettier 3.6
+[error] No parser could be inferred for file "".
+2
+```
+
+### Miscellaneous
+
+#### Fix embedded format with `cursorOffset` ([#17254](https://github.com/prettier/prettier/pull/17254) by [@fisker](https://github.com/fisker)) {#change-17254}
+
+
+````md
+
+# Angular note
+
+```typescript
+ import {Component} from '@angular/core';
+
+ @Component({
+ selector: 'app-root',
+ standalone: true,
+ imports: [],
+ template: `
+
+
+ {{ title }}
+ `,
+ styleUrls: ['./app.component.css'],
+ })
+ export class AppComponent {
+ title = 'default';
+ }
+```
+
+
+Error: There are too many 'cursor' in doc.
+
+
+# Angular note
+
+```typescript
+import { Component } from "@angular/core";
+
+@Component({
+ selector: "app-root",
+ standalone: true,
+ imports: [],
+ template: `
+
+ {{ title }}
+
+ `,
+ styleUrls: ["./app.component.css"],
+})
+export class AppComponent {
+ title = "default";
+}
+```
+````