Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
1aefcb1
feat(js-api): add spanInBytesToSpanInCodeUnits in subpath exports (#9…
regseb Jun 13, 2026
1077238
feat(useSortedAttributes): add sortFirst option (#10631)
thibaut-pro Jul 10, 2026
7c39b09
Merge branch 'main' into next
ematipico Jul 10, 2026
0efefb9
Merge branch 'refs/heads/main' into next
siketyan Jul 14, 2026
8057ea4
Merge branch 'main' into chore/merge-main-into-next
ematipico Jul 23, 2026
2c6ad76
Merge pull request #11044 from biomejs/chore/merge-main-into-next
ematipico Jul 23, 2026
40de5a0
feat(plugins): add resolutionKind for object-syntax plugin entries (#…
soconnor-seeq Jul 23, 2026
dc7f199
chore: fix failures
ematipico Jul 23, 2026
3479d15
feat(cli): output files information via biome rage by default (#6886)
christymcgrory Jul 23, 2026
189b7ba
feat: add partitionByNewLine option to useSortedInterfaceMembers (#10…
LinusU Jul 23, 2026
78c992f
chore: `main` into `next` (#11093)
dyc3 Jul 27, 2026
fa63050
feat(html): support .htm files (#11126)
Punisheroot Jul 30, 2026
70551d6
Merge remote-tracking branch 'origin/main' into chore/merge-main-into…
ematipico Aug 5, 2026
4cb7214
fix merge
ematipico Aug 5, 2026
2f9ce68
[autofix.ci] apply automated fixes
autofix-ci[bot] Aug 5, 2026
fd2039d
fix
ematipico Aug 5, 2026
dbb63f1
fix another snap
ematipico Aug 5, 2026
419ff8b
Merge pull request #11241 from biomejs/chore/merge-main-into-next
ematipico Aug 5, 2026
0628b53
feat(cli): add profiler for type inference (#11244)
ematipico Aug 5, 2026
0874b7f
feat(useSortedClasses): add support for html files (#11102)
gameroman Aug 7, 2026
bf298bd
Merge branch 'main' into chore/merge-main-into-next
ematipico Aug 17, 2026
22ceffa
chore: update snapshots
ematipico Aug 17, 2026
7bbf2c3
[autofix.ci] apply automated fixes
autofix-ci[bot] Aug 17, 2026
d43d0e4
Merge pull request #11380 from biomejs/chore/merge-main-into-next
ematipico Aug 17, 2026
ebbc788
feat(tailwind): add top-level detection configuration
dyc3 Aug 15, 2026
0943cb6
refactor(noTailwindArbitraryValue): use TailwindSyntax query
dyc3 Aug 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions .changeset/add-span-conversion-helper-in-subpath.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
"@biomejs/js-api": minor
---

Added `spanInBytesToSpanInCodeUnits` helper function in subpath exports of `@biomejs/js-api`.

```js
import { spanInBytesToSpanInCodeUnits } from "@biomejs/js-api/nodejs";
// Or:
// import { spanInBytesToSpanInCodeUnits } from "@biomejs/js-api/bundler";
// import { spanInBytesToSpanInCodeUnits } from "@biomejs/js-api/web";

const [start, end] = spanInBytesToSpanInCodeUnits(
diagnostic.location.span,
content
);
const text = content.slice(start, end); // Correctly extracts the text
```
5 changes: 5 additions & 0 deletions .changeset/chatty-meals-train.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@biomejs/biome": minor
---

`biome rage` now shows the resolved `files.includes` and `files.ignoreUnknown` configuration.
5 changes: 5 additions & 0 deletions .changeset/cold-snakes-smile.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@biomejs/biome": minor
---

Added support for [`useSortedClasses`](https://biomejs.dev/linter/rules/use-sorted-classes/) rule in HTML-ish files.
19 changes: 19 additions & 0 deletions .changeset/eight-lamps-follow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
"@biomejs/biome": minor
---

Adds a new `resolutionKind` option for object-syntax plugin entries.

This allows shared Biome configs in monorepos to load local Grit plugins from the package that declares them instead of resolving plugin paths from the consuming project.

```json
{
"plugins": [
{ "path": "./grit/no-debugger.grit", "resolutionKind": "config" },
{ "path": "local-plugin.grit", "resolutionKind": "project" },
{ "path": "local-plugin.grit" }
]
}
```

Use `resolutionKind: "config"` to resolve the plugin from the configuration file that declares it. Use `resolutionKind: "project"` to resolve the plugin from the consuming project. When omitted, `resolutionKind` defaults to `project`. This only affects plugin resolution; `includes` still apply to end-user project files as usual.
21 changes: 21 additions & 0 deletions .changeset/fix-css-commented-function-arguments.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
"@biomejs/biome": patch
---

Fixed CSS formatting for multiline function arguments preceded by comments:

```diff
.example {
value: outer(
1,
/* comment */
nested(
- first,
- second
- )
+ first,
+ second
+ )
);
}
```
5 changes: 5 additions & 0 deletions .changeset/fix-nested-destructured-arrow-ternary.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@biomejs/biome": patch
---

Fixed [#10131](https://github.com/biomejs/biome/issues/10131): Biome now correctly parses curried arrow functions in ternary consequents when the inner arrow's parameters use a destructuring pattern, e.g. `cond ? (x) => ({ a, b }) => body : alt`.
5 changes: 5 additions & 0 deletions .changeset/fix-reindent-verbatim-regions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@biomejs/biome": patch
---

Fixed [#10515](https://github.com/biomejs/biome/issues/10515): `biome check --write` was not idempotent on Svelte files — multi-line template literals in `<script>` blocks and block comments in `<style>` blocks gained an extra indent level on every run.
39 changes: 39 additions & 0 deletions .changeset/gentle-rocks-teach.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
---
"@biomejs/biome": minor
---

Added the new CLI option `--profile-type-inference` to the commands `lint` and `check`.

The profiler is designed to track the execution time of internal queries and operations, group them by file, and sort them from the most expensive to the least expensive.

```shell
biome lint --profile-type-inference
```

```text
profiler ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

i Type inference profile (Biome <version>)

src/index.ts

Requests (top 5 of 12 groups; 28 source records; 46 executions)
1. Promise classification <- nursery/noFloatingPromises
...

Queries (top 8 of 25 groups; 61 source records; 94 executions)
1. Promises / infer_expression_is_promise
...

Whole-module inference (top 1 of 1 group; 1 source record; 1 execution)
1. Import depth limit
...

68 files omitted.

ℹ To show all the information, use the --verbose option. The output might be very verbose, so it's advised to analyze a single file.

$ biome lint --profile-type-inference --verbose ./path/to/file.ts
```

Use `--verbose` to include detailed timings, attribution, breadth, and implementation references for the top source records in each file.
15 changes: 15 additions & 0 deletions .changeset/light-carrots-throw.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
"@biomejs/biome": patch
---

Improved the accuracy of type-aware lint rules by resolving more inferred types. For example, [`noFloatingPromises`](https://biomejs.dev/linter/rules/no-floating-promises/) now detects floating Promises returned by aliased callbacks and arrays of Promises created by async mapping callbacks.

The following statements are now reported:

```ts
type AsyncCallback = () => Promise<void>;
declare const callback: AsyncCallback;
callback();

[1, 2, 3].map(async value => value);
```
5 changes: 5 additions & 0 deletions .changeset/parse-mixed-case-html-doctype.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@biomejs/biome": patch
---

The HTML parser now accepts mixed-case `doctype` declarations.
5 changes: 5 additions & 0 deletions .changeset/rotten-bars-shout.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@biomejs/biome": patch
---

Fixed a performance regression in type-aware JavaScript lint rules by inferring only requested types and memoizing export resolution.
5 changes: 5 additions & 0 deletions .changeset/sharp-emus-raise.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@biomejs/biome": patch
---

Added support for Svelte declaration tags using `let` and `const`. Biome can now parse, format, and lint bindings declared in these tags.
5 changes: 5 additions & 0 deletions .changeset/support-htm-files.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@biomejs/biome": minor
---

Biome now recognizes files with the `.htm` extension as HTML.
5 changes: 5 additions & 0 deletions .changeset/swift-suns-smell.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@biomejs/biome": patch
---

Improved the performance of Biome formatter up to ~7% across the board.
5 changes: 5 additions & 0 deletions .changeset/thick-coins-hide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@biomejs/biome": patch
---

Added the nursery rule [`noJsRestrictedProperties`](https://biomejs.dev/linter/rules/no-js-restricted-properties/), which ports ESLint's `no-restricted-properties` rule. Biome now flags restricted member access and object destructuring, and `biome migrate eslint` preserves the rule's options.
32 changes: 32 additions & 0 deletions .changeset/use-sorted-attributes-sort-first.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
---
"@biomejs/biome": minor
---

Added the `sortFirst` option to the [useSortedAttributes](https://biomejs.dev/assist/actions/use-sorted-attributes/) action (JSX and HTML). It takes a list of attribute names that are sorted before all other attributes, in the order given, while the remaining attributes keep their usual sort. This is useful to keep attributes such as `key` first.

With the following configuration:

```json
{
"assist": {
"actions": {
"source": {
"useSortedAttributes": {
"level": "on",
"options": { "sortFirst": ["key"] }
}
}
}
}
}
```

The attributes are reordered so that `key` comes first:

```jsx
// Before
<div className={styles.investment} key={investment.id} />;

// After
<div key={investment.id} className={styles.investment} />;
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@biomejs/biome": minor
---

Added the `partitionByNewLine` option to the `useSortedInterfaceMembers` assist. When enabled, members separated by a blank line are kept in their own section and sorted only within that section, preserving the logical groupings the author intentionally introduced with empty lines.
16 changes: 8 additions & 8 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/biome_analyze/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ biome_rowan = { workspace = true }
biome_string_case = { workspace = true }
biome_suppression = { workspace = true }
biome_text_edit = { workspace = true }
bitvec = "1.0.1"
camino = { workspace = true }
either = { workspace = true }
enumflags2 = { workspace = true }
Expand Down
45 changes: 45 additions & 0 deletions crates/biome_analyze/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@ pub struct AnalyzerConfiguration {
/// The JSX fragment factory function identifier (e.g., "Fragment")
/// Only applies when jsx_runtime is ReactClassic.
jsx_fragment_factory: Option<Box<str>>,

/// Configures which attributes and functions contain Tailwind classes.
tailwind: TailwindOptions,
}

impl AnalyzerConfiguration {
Expand Down Expand Up @@ -130,6 +133,11 @@ impl AnalyzerConfiguration {
self.preferred_indentation = preferred_indentation;
self
}

pub fn with_tailwind(mut self, tailwind: TailwindOptions) -> Self {
self.tailwind = tailwind;
self
}
}

/// A set of information useful to the analyzer infrastructure
Expand Down Expand Up @@ -231,6 +239,43 @@ impl AnalyzerOptions {
pub fn preferred_indentation(&self) -> PreferredIndentation {
self.configuration.preferred_indentation
}

pub fn tailwind(&self) -> &TailwindOptions {
&self.configuration.tailwind
}
}

/// User-provided names that Tailwind-aware analyzer queries use to identify class strings.
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct TailwindOptions {
attributes: Option<Arc<[Box<str>]>>,
functions: Option<Arc<[Box<str>]>>,
}

impl TailwindOptions {
/// Creates analyzer options from optional replacement lists.
pub fn new(attributes: Option<Box<[Box<str>]>>, functions: Option<Box<[Box<str>]>>) -> Self {
Self {
attributes: attributes.map(Arc::from),
functions: functions.map(Arc::from),
}
}

/// Returns the configured attribute replacement list, or `None` when language defaults apply.
pub fn attributes(&self) -> Option<&[Box<str>]> {
self.attributes.as_deref()
}

/// Returns the configured function replacement list, or `None` when defaults apply.
pub fn functions(&self) -> Option<&[Box<str>]> {
self.functions.as_deref()
}
}

impl Default for TailwindOptions {
fn default() -> Self {
Self::new(None, None)
}
}

#[derive(Clone, Copy, Debug, Default)]
Expand Down
1 change: 1 addition & 0 deletions crates/biome_analyze/src/shared/mod.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
pub mod class_dedup;
pub mod sort_attributes;
pub mod sorted_classes;
25 changes: 25 additions & 0 deletions crates/biome_analyze/src/shared/sort_attributes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,31 @@ pub trait SortableAttribute {
(None, None) => Ordering::Equal,
}
}

fn sort_first_index(&self, sort_first: &[Box<str>]) -> usize {
self.name()
.and_then(|name| {
sort_first
.iter()
.position(|listed| listed.as_ref() == name.text_trimmed())
})
.unwrap_or(sort_first.len())
}

fn cmp_sort_first(
&self,
other: &Self,
sort_first: &[Box<str>],
base: impl Fn(&Self, &Self) -> Ordering,
) -> Ordering {
if sort_first.is_empty() {
return base(self, other);
}

self.sort_first_index(sort_first)
.cmp(&other.sort_first_index(sort_first))
.then_with(|| base(self, other))
}
}

#[derive(Clone)]
Expand Down
Loading
Loading