---
authors: "sosukesuzuki"
title: "Prettier 3.5: New objectWrap option, experimentalOperatorPosition option and TS config file support!"
---

This release includes a lot of bug fixes and the following new features:

- Support for the new `objectWrap` option
- Support for the new experimental `experimentalOperatorPosition` option
- Support for TypeScript configuration file

See each section for details.

<!-- truncate -->

If you appreciate Prettier and would like to support our work, please consider sponsoring us directly via [our OpenCollective](https://opencollective.com/prettier) or by sponsoring the projects we depend on, such as [typescript-eslint](https://opencollective.com/typescript-eslint), [remark](https://opencollective.com/unified), and [Babel](https://opencollective.com/babel). Thank you for your continued support!

## Why We Added Two New Options

This release introduces two new options. If you’re familiar with Prettier’s [Option Philosophy](https://prettier.io/docs/option-philosophy/), you might be wondering: “Why add new options?” Rest assured, these aren’t your typical options, nor do they violate our option philosophy.

As the name suggests, `experimentalOperatorPosition` is experimental. We have a [policy for experimental options](https://github.com/prettier/prettier/issues/14527), which means it will eventually be removed. In the future, the new behavior could become the default, or this option might be dropped entirely. If you’ve been following Prettier for a while, you may recall we once added an `experimentalTernaries` option, and this follows the same approach.

`objectWrap` is a bit special. For a long time, we’ve struggled with how to print multi-line objects. We haven’t yet found the perfect solution, so we’ve resorted to a semi-manual approach. For more details, see our [Rationale](https://prettier.io/docs/rationale/#multi-line-objects). The current behavior isn’t ideal because the final output can vary based on how the user writes their code. To provide a more consistent format, we’ve decided to introduce the `objectWrap` option.

Although this release includes two new options, **we want to emphasize that we haven’t forgotten Prettier’s option philosophy**. These options address specific, long-standing formatting challenges without compromising our option philosophy.

## Highlights

### JavaScript

#### Add experimental option for breaking lines before binary operators ([#7111](https://github.com/prettier/prettier/pull/7111) by [@btmills](https://github.com/btmills))

This is implemented behind the `--experimental-operator-position <start|end>` flag.

When binary expressions wrap lines, `start` prints the operators at the start of new lines. Placing binary operators at the beginning of wrapped lines can make the operators more prominent and easier to scan.

<!-- prettier-ignore -->
```jsx
// Input
var a = Math.random() * (yRange * (1 - minVerticalFraction)) + minVerticalFraction * yRange - offset;

// `experimentalOperatorPosition: end` (default behavior)
var a =
  Math.random() * (yRange * (1 - minVerticalFraction)) +
  minVerticalFraction * yRange -
  offset;

// `experimentalOperatorPosition: start`
var a =
  Math.random() * (yRange * (1 - minVerticalFraction))
  + minVerticalFraction * yRange
  - offset;
```

#### Implement `objectWrap` config option ([#16163](https://github.com/prettier/prettier/pull/16163) by [@pauldraper](https://github.com/pauldraper), [@sosukesuzuki](https://github.com/sosukesuzuki))

Prettier has historically done semi-manual formatting of multi-line JavaScript object literals.

Namely, an object is kept on multiple lines if there is a newline prior to the first property, even if it could fit on a single line. See [Multi-line objects](https://prettier.io/docs/rationale#multi-line-objects) for more details.

While this behavior continues to be the default, `--object-wrap=collapse` instead ignores whitespace when formatting object literals.

<!-- prettier-ignore -->
```js
// Input
const obj1 = {
  name1: "value1", name2: "value2",
};

const obj2 = { name1: "value1",
  name2: "value2",
};

// Prettier 3.4
const obj1 = {
  name1: "value1",
  name2: "value2",
};

const obj2 = { name1: "value1", name2: "value2" };

// Prettier 3.5 (with `--object-wrapping=collapse`)
const obj1 = { name1: "value1", name2: "value2" };

const obj2 = { name1: "value1", name2: "value2" };
```

### API

#### Add support for TypeScript config files ([#16828](https://github.com/prettier/prettier/pull/16828) by [@itsyoboieltr](https://github.com/itsyoboieltr) & [@fisker](https://github.com/fisker))

Added new format of configuration files:

- `.prettierrc.ts`
- `.prettierrc.mts`
- `.prettierrc.cts`
- `prettier.config.ts`
- `prettier.config.mts`
- `prettier.config.cts`

Note:

Currently TypeScript support in Node.js is experimental.

To make TypeScript config files work, Node.js>=22.6.0 is required and Node.js v22 requires `--experimental-strip-types`.

You can run prettier with

```sh
node --experimental-strip-types node_modules/prettier/bin/prettier.cjs . --write
```

or

```sh
NODE_OPTIONS="--experimental-strip-types" prettier . --write
```

Other TS loaders should also work, but not tested, use at your own risk.

For example, with [`tsx`](https://tsx.is/), you can

```sh
node --import tsx node_modules/prettier/bin/prettier.cjs . --write
```

or

```sh
tsx node_modules/prettier/bin/prettier.cjs . --write
```

## Other Changes

### JavaScript

#### Improve word wrapping edge cases in JSX ([#16700](https://github.com/prettier/prettier/pull/16700) by [@seiyab](https://github.com/seiyab))

<!-- prettier-ignore -->
```jsx
// Input
br_triggers_expression_break =
  <div><br />
  text text text text text text text text text text text {this.props.type} </div>

// Prettier 3.4
br_triggers_expression_break = (
  <div>
    <br />
    text text text text text text text text text text text {
      this.props.type
    }{" "}
  </div>
);

// Prettier 3.5
br_triggers_expression_break = (
  <div>
    <br />
    text text text text text text text text text text text{" "}
    {this.props.type}{" "}
  </div>
);
```

### Flow

#### Support `const` type parameters in Flow ([#16947](https://github.com/prettier/prettier/pull/16947) by [@gkz](https://github.com/gkz))

<!-- prettier-ignore -->
```flow
function f<const T>(): void {}

// Prettier 3.4
// Parse error

// Prettier 3.5
function f<const T>(): void {}
```

### CSS

#### Break before breaking comma separated values ([#16907](https://github.com/prettier/prettier/pull/16907) by [@seiyab](https://github.com/seiyab))

<!-- prettier-ignore -->
```css
/* Input */
a {
  background-image:
    linear-gradient(to bottom, rgb(255 255 0 / 50%), rgb(0 0 255 / 50%)),
    url("catfront.png");
}

/* Prettier 3.4 */
a {
  background-image: linear-gradient(
      to bottom,
      rgb(255 255 0 / 50%),
      rgb(0 0 255 / 50%)
    ),
    url("catfront.png");
}

/* Prettier 3.5 */
a {
  background-image:
    linear-gradient(to bottom, rgb(255 255 0 / 50%), rgb(0 0 255 / 50%)),
    url("catfront.png");
}
```

### Vue

#### Support `.prop` shorthand ([#16920](https://github.com/prettier/prettier/pull/16920) by [@fisker](https://github.com/fisker))

`.foo` is shorthand for `v-bind:foo.prop`. See [`v-bind` builtin directive](https://vuejs.org/api/built-in-directives.html#v-bind) for details.

<!-- prettier-ignore -->
```vue
<!-- Input -->
<template>
  <button .disabled="   a &&b ">Click!</button>
</template>

<!-- Prettier 3.4 -->
<template>
  <button .disabled="   a &&b ">Click!</button>
</template>

<!-- Prettier 3.5 -->
<template>
  <button .disabled="a && b">Click!</button>
</template>
```

### Angular

#### Improve line breaks inside ICU blocks ([#16922](https://github.com/prettier/prettier/pull/16922) by [@fisker](https://github.com/fisker))

<!-- prettier-ignore -->
```html
<!-- Input -->
<span>The author is {gender, select, male {male} female {female} other {other}}</span>
<span>The author is <span>male consectetur adipiscing elit, sed do eiusmod</span></span>

<!-- Prettier 3.4 -->
<span
  >The author is {gender, select, male {male} female {female} other {other}
}</span>
<span
  >The author is
  <span>male consectetur adipiscing elit, sed do eiusmod</span></span
>

<!-- Prettier 3.5 -->
<span
  >The author is
  {gender, select, male {male} female {female} other {other}}</span
>
<span
  >The author is
  <span>male consectetur adipiscing elit, sed do eiusmod</span></span
>
```

#### Fix extra new line inside ICU blocks ([#16922](https://github.com/prettier/prettier/pull/16922) by [@fisker](https://github.com/fisker))

<!-- prettier-ignore -->
```html
<!-- Input -->
{active, select,
  true {
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod temp
  }
  false {
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod temp
  }
}

<!-- Prettier 3.4 -->
{active, select,
  true {
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod temp

  }
  false {
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod temp

  }
}

<!-- Prettier 3.5 -->
{active, select,
  true {
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod temp
  }
  false {
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod temp
  }
}
```

### Ember / Handlebars

#### Handle `<style>` and `<pre>` tags in Handlebars/Glimmer ([#15087](https://github.com/prettier/prettier/pull/15087) by [@jurgenwerk](https://github.com/jurgenwerk))

<!-- prettier-ignore -->
```handlebars
{{!-- Input --}}
<pre>
  cd ~
  ls
  echo "hey"
</pre>
<style>
  .red { color: red }
  .blue {
    color: red
  }
</style>

{{!-- Prettier 3.4 --}}
<pre>
  cd ~ ls echo "hey"
</pre>
<style>
  .red { color: red } .blue { color: blue }
</style>

{{!-- Prettier 3.5 --}}
<pre>
  cd ~
  ls
  echo "hey"
</pre>
<style>
  .red {
    color: red;
  }
  .blue {
    color: red;
  }
</style>
```

### Markdown

#### U+FF5E as CJK punctuation ([#16832](https://github.com/prettier/prettier/pull/16832) by [@tats-u](https://github.com/tats-u))

U+FF5E FULLWIDTH TILDE (～) is commonly used as a substitute for U+301C WAVE DASH (〜) in Windows for Japanese. Full width alphabets are less used in Markdown documents comparing to other types of documents (e.g. Microsoft Office documents), and the full width tilde is much less used as this purpose compared to full width alphabets and digits. Therefore, we can assume that the full width tilde in Markdown documents in the wild are a alternative form of the wave dash and a part of CJK punctuation.

<!-- prettier-ignore -->
```markdown
<!-- Input (--prose-wrap=never) -->
a 字 a 字 a 字
60～
100点
60〜
100点

<!-- Prettier 3.4 -->
a 字 a 字 a 字 60～ 100点 60〜10点


<!-- Prettier 3.5 -->
a 字 a 字 a 字 60～10点 60〜100点
```

The first symbol between 60 and 100 in the above example is U+FF5E FULLWIDTH TILDE (～) and the second one is U+301C WAVE DASH (〜).

### API

#### Support read config from `package.json` with JSONC syntax on Bun ([#17041](https://github.com/prettier/prettier/pull/17041) by [@fisker](https://github.com/fisker))

[Bun 1.2 added JSONC support in `package.json`](https://bun.sh/blog/bun-v1.2#jsonc-support-in-package-json), in previous version of Prettier, it will ignore `prettier` config in it. Since Prettier 3.5, we can read `prettier` config from it without error.

However, since it's just a Bun feature and not supported by Node.js, it can only work when running Prettier with Bun.

Important note: Prettier uses [`json-stringify` parser](https://prettier.io/docs/options#parser) to format `package.json` file by default, to support formatting `package.json` file with JSONC syntax, you need override the parser option

```js
export default {
  overrides: [
    {
      files: ["package.json"],
      options: {
        parser: "jsonc",
      },
    },
  ],
};
```

If you can't upgrade Prettier for some reason, you can still use JSONC syntax in `package.json`, but don't put your `prettier` config in it, you'll have to use another [configuration file](https://prettier.io/docs/configuration).

### Miscellaneous

#### Use ESM entrypoint for `require(ESM)` ([#16958](https://github.com/prettier/prettier/pull/16958) by [@tats-u](https://github.com/tats-u))

:::info

This change has been reverted in v3.5.2, check [#17139](https://github.com/prettier/prettier/pull/17139) for details.

:::

Node.js 22.12 or later [can (experimentally) load ESM modules with `require` function](https://nodejs.org/api/modules.html#loading-ecmascript-modules-using-require) without runtime flags. This change enables `require` to load Prettier without the CommonJS entrypoint with almost only the ability to import the ESM entrypoint.

The feature to load ES modules with `require` is not completely stable but can be used without ExperimentalWarning as of Node 22.13.
