Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(perf): skip first mergeClassList reverse() call #445

Closed

Conversation

rortan134
Copy link

@rortan134 rortan134 commented Jul 15, 2024

This PR introduces performance optimizations to the mergeClassList function

We can eliminate the need for the first array.prototype.reverse() call in the function by concatenating the classnames with unshift instead which pushes elements at the start of the array instead of at the end.

It leads to some performance gains particularly for smaller array lengths (< 5000) which shouldn't be common here, with diminishing returns after that

I also replaced some loops with marginally faster alternatives

my (primitive) benchmark results are optimistic

before 23.744 ops/sec 0.042 ms ± 15.14 % (43 runs sampled)
after 56.035 ops/sec 0.018 ms ± 42.14 % (59 runs sampled)

@github-actions github-actions bot added the context-v2 Related to tailwind-merge v2 label Jul 15, 2024
@XantreDev
Copy link
Contributor

Nice work. Btw, I think it's possible to boost performance further if remove all other unnecessary array allocations. When I've seen code of mergeClassList I was really appalled with amount of overhead

@dcastil dcastil added the feature Is new feature label Jul 24, 2024
@dcastil dcastil mentioned this pull request Jul 24, 2024
@dcastil
Copy link
Owner

dcastil commented Jul 24, 2024

Hey @rortan134! 👋

Thanks for your patience, just came back from a vacation. Cool that you took the time to make tailwind-merge faster! I'm definitely up to adding this change if it makes things that much faster.

I tried to do a similar perf optimization in the past but it turned out not to make a difference, probably due to the usually small arrays that are handled there (<100 elements). But I also didn't use a benchmark suite but measured the performance in a real app that used tailwind-merge a lot.

A backwards running for loop with simple string concatenation like I did back then should theoretically be the fastest way to do the work in mergeClassList since there are no array allocations anymore other than splitting the original string. That also eliminates the result.unshift() call which can also become quite slow. I'm not 100% sure how up to date this info is with JS engines doing all sorts of tricks nowadays, but in a simple implementation of unshift() all existing array elements need to be moved in order to add one at the start, wasting a lot of CPU cyles. More on that in https://stackoverflow.com/questions/44031591/performance-of-array-push-vs-array-unshift.

Could you test how the code performs when you switch to the backwards running for loop with string concatenation as described in #20 (comment)? Is that faster or slower than your approach?

@XantreDev
Copy link
Contributor

XantreDev commented Jul 25, 2024

Hey @rortan134! 👋

Thanks for your patience, just came back from a vacation. Cool that you took the time to make tailwind-merge faster! I'm definitely up to adding this change if it makes things that much faster.

I tried to do a similar perf optimization in the past but it turned out not to make a difference, probably due to the usually small arrays that are handled there (<100 elements). But I also didn't use a benchmark suite but measured the performance in a real app that used tailwind-merge a lot.

A backwards running for loop with simple string concatenation like I did back then should theoretically be the fastest way to do the work in mergeClassList since there are no array allocations anymore other than splitting the original string. That also eliminates the result.unshift() call which can also become quite slow. I'm not 100% sure how up to date this info is with JS engines doing all sorts of tricks nowadays, but in a simple implementation of unshift() all existing array elements need to be moved in order to add one at the start, wasting a lot of CPU cyles. More on that in https://stackoverflow.com/questions/44031591/performance-of-array-push-vs-array-unshift.

Could you test how the code performs when you switch to the backwards running for loop with string concatenation as described in #20 (comment)? Is that faster or slower than your approach?

Yep, seems to be unshift is O(n)

mergeClassList will also be poorly JIT-ed, because it's not possible to inline parseClassName, getClassGroupId, getConflictingClassGroupIds, since it's passed as parameter

@XantreDev
Copy link
Contributor

XantreDev commented Jul 26, 2024

There is no much performance difference. I think most of the difference on side of memory usage, don't know how to bench it yet
image
Bench is here

Most of the time funciton calls other functions
image
CPU-20240726T020621.cpuprofile

@dcastil
Copy link
Owner

dcastil commented Jul 28, 2024

mergeClassList will also be poorly JIT-ed, because it's not possible to inline parseClassName, getClassGroupId, getConflictingClassGroupIds, since it's passed as parameter

@XantreDev What do you mean with "poorly JIT-ed"? I know what JIT is but don't know much about about how JS engines compile down JS code.

There is no much performance difference. […]

Thanks for your benchmarks! Your relative results seem to align with my own results in #20 (comment). That means the string concatenation approach is the best one, although the difference is not too big.

Is there a reason why you used an array instead of a set for classGroupsInConflict? I think a set should perform better in both time and space there because of the O(1) lookup and duplicates removal.

@dcastil
Copy link
Owner

dcastil commented Jul 28, 2024

@rortan134 would you be willing to adopt the string concatenation approach from https://github.com/XantreDev/tailwind-merge/blob/ef59466ad6053aaa2803d4aafb4844676d161b71/src/lib/merge-classlist.ts#L100-L179 in your PR? Looks like that is the best approach going forward.

@XantreDev
Copy link
Contributor

XantreDev commented Jul 28, 2024

Is there a reason why you used an array instead of a set for classGroupsInConflict? I think a set should perform better in both time and space there because of the O(1) lookup and duplicates removal.

It depends from amount of data we store in set. Array will perform better with relatively small number up elements (up to hundreds of elements). Probably you're right if we are talking about strings, but there was no difference in benchmarks of this code

5 unique elements - Array is better
5 unique 10 symbols length - Array is better
8 unique elements - Array is better
20 unique elements - Set is better

@XantreDev
Copy link
Contributor

mergeClassList will also be poorly JIT-ed, because it's not possible to inline parseClassName, getClassGroupId, getConflictingClassGroupIds, since it's passed as parameter

@XantreDev What do you mean with "poorly JIT-ed"? I know what JIT is but don't know much about about how JS engines compile down JS code.

JIT optimizer can optimize some levels of abstraction if it will infer types correctly, but here is kind of hard to infer types, because a lot of code in polymorphic, there are also a lot of memory allocations is going on. JIT also cannot inline some functions, because it's passed as a parameter (I've experemented with that a bit and didn't found any performance benefit from using additional closure)

I will think about how to make this library much faster, because 32k ops/s is not really great. It can use a lot of performance budget when we rendering on mobile with 120 hz display

@dcastil
Copy link
Owner

dcastil commented Jul 29, 2024

Thanks for your explanations @XantreDev! 🙏

@dcastil
Copy link
Owner

dcastil commented Jul 29, 2024

Hey @rortan134, I just merged #450 with the improvements discussed in this PR, so I'm closing this one.

I'll include you in the release notes to acknowledge your contribution as well. Thanks you for your PR!

@dcastil dcastil closed this Jul 29, 2024
@rortan134
Copy link
Author

rortan134 commented Jul 29, 2024

Hey @rortan134, I just merged #450 with the improvements discussed in this PR, so I'm closing this one.

I'll include you in the release notes to acknowledge your contribution as well. Thanks you for your PR!

That is great, glad I could move the needle a bit, sorry for not seeing this thread before didn't have much time this week ❤️

@rortan134 rortan134 deleted the refactor-perf-merge-classlist branch July 29, 2024 21:00
renovate bot referenced this pull request in inabagumi/shinju-date Aug 11, 2024
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [tailwind-merge](https://github.com/dcastil/tailwind-merge) |
[`^2.4.0` ->
`^2.5.0`](https://renovatebot.com/diffs/npm/tailwind-merge/2.4.0/2.5.0)
|
[![age](https://developer.mend.io/api/mc/badges/age/npm/tailwind-merge/2.5.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/tailwind-merge/2.5.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/tailwind-merge/2.4.0/2.5.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/tailwind-merge/2.4.0/2.5.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|

---

### Release Notes

<details>
<summary>dcastil/tailwind-merge (tailwind-merge)</summary>

###
[`v2.5.0`](https://github.com/dcastil/tailwind-merge/releases/tag/v2.5.0)

[Compare
Source](https://github.com/dcastil/tailwind-merge/compare/v2.4.0...v2.5.0)

##### New Features

- Performance improvements in mergeClassList by
[@&#8203;XantreDev](https://github.com/XantreDev) in
[https://github.com/dcastil/tailwind-merge/pull/450](https://github.com/dcastil/tailwind-merge/pull/450)
and [@&#8203;rortan134](https://github.com/rortan134) in
[https://github.com/dcastil/tailwind-merge/pull/445](https://github.com/dcastil/tailwind-merge/pull/445)
- Use arrow functions where possible to help with minification by
[@&#8203;VIKTORVAV99](https://github.com/VIKTORVAV99) in
[https://github.com/dcastil/tailwind-merge/pull/449](https://github.com/dcastil/tailwind-merge/pull/449)

##### Bug Fixes

- Fix bg-opacity arbitrary percentages not being recognized properly by
[@&#8203;dcastil](https://github.com/dcastil) in
[https://github.com/dcastil/tailwind-merge/pull/451](https://github.com/dcastil/tailwind-merge/pull/451)

**Full Changelog**:
dcastil/tailwind-merge@v2.4.0...v2.5.0

Thanks to
[@&#8203;brandonmcconnell](https://github.com/brandonmcconnell),
[@&#8203;manavm1990](https://github.com/manavm1990),
[@&#8203;langy](https://github.com/langy) and
[@&#8203;jamesreaco](https://github.com/jamesreaco) for sponsoring
tailwind-merge! ❤️

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend
Renovate](https://www.mend.io/free-developer-tools/renovate/). View the
[repository job
log](https://developer.mend.io/github/inabagumi/shinju-date).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOC4yMC4xIiwidXBkYXRlZEluVmVyIjoiMzguMjAuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIl19-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
kodiakhq bot referenced this pull request in technifit/tasker Aug 11, 2024
[![Mend Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [tailwind-merge](https://github.com/dcastil/tailwind-merge) | [`2.4.0` -> `2.5.0`](https://renovatebot.com/diffs/npm/tailwind-merge/2.4.0/2.5.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/tailwind-merge/2.5.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/tailwind-merge/2.5.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/tailwind-merge/2.4.0/2.5.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/tailwind-merge/2.4.0/2.5.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) |

---

### Release Notes

<details>
<summary>dcastil/tailwind-merge (tailwind-merge)</summary>

### [`v2.5.0`](https://github.com/dcastil/tailwind-merge/releases/tag/v2.5.0)

[Compare Source](https://github.com/dcastil/tailwind-merge/compare/v2.4.0...v2.5.0)

##### New Features

-   Performance improvements in mergeClassList by [@&#8203;XantreDev](https://github.com/XantreDev) in [https://github.com/dcastil/tailwind-merge/pull/450](https://github.com/dcastil/tailwind-merge/pull/450) and [@&#8203;rortan134](https://github.com/rortan134) in [https://github.com/dcastil/tailwind-merge/pull/445](https://github.com/dcastil/tailwind-merge/pull/445)
-   Use arrow functions where possible to help with minification by [@&#8203;VIKTORVAV99](https://github.com/VIKTORVAV99) in [https://github.com/dcastil/tailwind-merge/pull/449](https://github.com/dcastil/tailwind-merge/pull/449)

##### Bug Fixes

-   Fix bg-opacity arbitrary percentages not being recognized properly by [@&#8203;dcastil](https://github.com/dcastil) in [https://github.com/dcastil/tailwind-merge/pull/451](https://github.com/dcastil/tailwind-merge/pull/451)

**Full Changelog**: dcastil/tailwind-merge@v2.4.0...v2.5.0

Thanks to [@&#8203;brandonmcconnell](https://github.com/brandonmcconnell), [@&#8203;manavm1990](https://github.com/manavm1990), [@&#8203;langy](https://github.com/langy) and [@&#8203;jamesreaco](https://github.com/jamesreaco) for sponsoring tailwind-merge! ❤️

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] If you want to rebase/retry this PR, check this box

---

This PR was generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View the [repository job log](https://developer.mend.io/github/technifit/tasker).
diegohaz referenced this pull request in ariakit/ariakit Aug 11, 2024
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [tailwind-merge](https://github.com/dcastil/tailwind-merge) |
[`2.4.0` ->
`2.5.0`](https://renovatebot.com/diffs/npm/tailwind-merge/2.4.0/2.5.0) |
[![age](https://developer.mend.io/api/mc/badges/age/npm/tailwind-merge/2.5.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/tailwind-merge/2.5.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/tailwind-merge/2.4.0/2.5.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/tailwind-merge/2.4.0/2.5.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|

---

### Release Notes

<details>
<summary>dcastil/tailwind-merge (tailwind-merge)</summary>

###
[`v2.5.0`](https://github.com/dcastil/tailwind-merge/releases/tag/v2.5.0)

[Compare
Source](https://github.com/dcastil/tailwind-merge/compare/v2.4.0...v2.5.0)

##### New Features

- Performance improvements in mergeClassList by
[@&#8203;XantreDev](https://github.com/XantreDev) in
[https://github.com/dcastil/tailwind-merge/pull/450](https://github.com/dcastil/tailwind-merge/pull/450)
and [@&#8203;rortan134](https://github.com/rortan134) in
[https://github.com/dcastil/tailwind-merge/pull/445](https://github.com/dcastil/tailwind-merge/pull/445)
- Use arrow functions where possible to help with minification by
[@&#8203;VIKTORVAV99](https://github.com/VIKTORVAV99) in
[https://github.com/dcastil/tailwind-merge/pull/449](https://github.com/dcastil/tailwind-merge/pull/449)

##### Bug Fixes

- Fix bg-opacity arbitrary percentages not being recognized properly by
[@&#8203;dcastil](https://github.com/dcastil) in
[https://github.com/dcastil/tailwind-merge/pull/451](https://github.com/dcastil/tailwind-merge/pull/451)

**Full Changelog**:
dcastil/tailwind-merge@v2.4.0...v2.5.0

Thanks to
[@&#8203;brandonmcconnell](https://github.com/brandonmcconnell),
[@&#8203;manavm1990](https://github.com/manavm1990),
[@&#8203;langy](https://github.com/langy) and
[@&#8203;jamesreaco](https://github.com/jamesreaco) for sponsoring
tailwind-merge! ❤️

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend
Renovate](https://www.mend.io/free-developer-tools/renovate/). View the
[repository job log](https://developer.mend.io/github/ariakit/ariakit).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOC4yMC4xIiwidXBkYXRlZEluVmVyIjoiMzguMjAuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
kkrishguptaa referenced this pull request in kkrishguptaa/study-web3 Aug 11, 2024
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [tailwind-merge](https://github.com/dcastil/tailwind-merge) |
[`2.4.0` ->
`2.5.0`](https://renovatebot.com/diffs/npm/tailwind-merge/2.4.0/2.5.0) |
[![age](https://developer.mend.io/api/mc/badges/age/npm/tailwind-merge/2.5.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/tailwind-merge/2.5.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/tailwind-merge/2.4.0/2.5.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/tailwind-merge/2.4.0/2.5.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|

---

### Release Notes

<details>
<summary>dcastil/tailwind-merge (tailwind-merge)</summary>

###
[`v2.5.0`](https://github.com/dcastil/tailwind-merge/releases/tag/v2.5.0)

[Compare
Source](https://github.com/dcastil/tailwind-merge/compare/v2.4.0...v2.5.0)

##### New Features

- Performance improvements in mergeClassList by
[@&#8203;XantreDev](https://github.com/XantreDev) in
[https://github.com/dcastil/tailwind-merge/pull/450](https://github.com/dcastil/tailwind-merge/pull/450)
and [@&#8203;rortan134](https://github.com/rortan134) in
[https://github.com/dcastil/tailwind-merge/pull/445](https://github.com/dcastil/tailwind-merge/pull/445)
- Use arrow functions where possible to help with minification by
[@&#8203;VIKTORVAV99](https://github.com/VIKTORVAV99) in
[https://github.com/dcastil/tailwind-merge/pull/449](https://github.com/dcastil/tailwind-merge/pull/449)

##### Bug Fixes

- Fix bg-opacity arbitrary percentages not being recognized properly by
[@&#8203;dcastil](https://github.com/dcastil) in
[https://github.com/dcastil/tailwind-merge/pull/451](https://github.com/dcastil/tailwind-merge/pull/451)

**Full Changelog**:
dcastil/tailwind-merge@v2.4.0...v2.5.0

Thanks to
[@&#8203;brandonmcconnell](https://github.com/brandonmcconnell),
[@&#8203;manavm1990](https://github.com/manavm1990),
[@&#8203;langy](https://github.com/langy) and
[@&#8203;jamesreaco](https://github.com/jamesreaco) for sponsoring
tailwind-merge! ❤️

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend
Renovate](https://www.mend.io/free-developer-tools/renovate/). View the
[repository job
log](https://developer.mend.io/github/kkrishguptaa/study-web3).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOC4yMC4xIiwidXBkYXRlZEluVmVyIjoiMzguMjAuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIl19-->

Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
renovate bot referenced this pull request in remcolakens/next-boilerplate Aug 11, 2024
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [@commitlint/cli](https://commitlint.js.org/)
([source](https://github.com/conventional-changelog/commitlint/tree/HEAD/@commitlint/cli))
| [`^19.3.0` ->
`^19.4.0`](https://renovatebot.com/diffs/npm/@commitlint%2fcli/19.3.0/19.4.0)
|
[![age](https://developer.mend.io/api/mc/badges/age/npm/@commitlint%2fcli/19.4.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@commitlint%2fcli/19.4.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@commitlint%2fcli/19.3.0/19.4.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@commitlint%2fcli/19.3.0/19.4.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
| [@commitlint/cz-commitlint](https://commitlint.js.org/)
([source](https://github.com/conventional-changelog/commitlint/tree/HEAD/@commitlint/cz-commitlint))
| [`^19.2.0` ->
`^19.4.0`](https://renovatebot.com/diffs/npm/@commitlint%2fcz-commitlint/19.2.0/19.4.0)
|
[![age](https://developer.mend.io/api/mc/badges/age/npm/@commitlint%2fcz-commitlint/19.4.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@commitlint%2fcz-commitlint/19.4.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@commitlint%2fcz-commitlint/19.2.0/19.4.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@commitlint%2fcz-commitlint/19.2.0/19.4.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
| [@playwright/test](https://playwright.dev)
([source](https://github.com/microsoft/playwright)) | [`^1.45.3` ->
`^1.46.0`](https://renovatebot.com/diffs/npm/@playwright%2ftest/1.45.3/1.46.0)
|
[![age](https://developer.mend.io/api/mc/badges/age/npm/@playwright%2ftest/1.46.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@playwright%2ftest/1.46.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@playwright%2ftest/1.45.3/1.46.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@playwright%2ftest/1.45.3/1.46.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
|
[@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/node)
([source](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node))
| [`^20.14.14` ->
`^20.14.15`](https://renovatebot.com/diffs/npm/@types%2fnode/20.14.14/20.14.15)
|
[![age](https://developer.mend.io/api/mc/badges/age/npm/@types%2fnode/20.14.15?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@types%2fnode/20.14.15?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@types%2fnode/20.14.14/20.14.15?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@types%2fnode/20.14.14/20.14.15?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
|
[@typescript-eslint/eslint-plugin](https://typescript-eslint.io/packages/eslint-plugin)
([source](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin))
| [`^8.0.0` ->
`^8.0.1`](https://renovatebot.com/diffs/npm/@typescript-eslint%2feslint-plugin/8.0.0/8.0.1)
|
[![age](https://developer.mend.io/api/mc/badges/age/npm/@typescript-eslint%2feslint-plugin/8.0.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@typescript-eslint%2feslint-plugin/8.0.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@typescript-eslint%2feslint-plugin/8.0.0/8.0.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@typescript-eslint%2feslint-plugin/8.0.0/8.0.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
|
[@typescript-eslint/parser](https://typescript-eslint.io/packages/parser)
([source](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser))
| [`^8.0.0` ->
`^8.0.1`](https://renovatebot.com/diffs/npm/@typescript-eslint%2fparser/8.0.0/8.0.1)
|
[![age](https://developer.mend.io/api/mc/badges/age/npm/@typescript-eslint%2fparser/8.0.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@typescript-eslint%2fparser/8.0.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@typescript-eslint%2fparser/8.0.0/8.0.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@typescript-eslint%2fparser/8.0.0/8.0.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
|
[eslint-plugin-testing-library](https://github.com/testing-library/eslint-plugin-testing-library)
| [`^6.2.2` ->
`^6.3.0`](https://renovatebot.com/diffs/npm/eslint-plugin-testing-library/6.2.2/6.3.0)
|
[![age](https://developer.mend.io/api/mc/badges/age/npm/eslint-plugin-testing-library/6.3.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/eslint-plugin-testing-library/6.3.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/eslint-plugin-testing-library/6.2.2/6.3.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/eslint-plugin-testing-library/6.2.2/6.3.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
|
[inquirer](https://github.com/SBoudrias/Inquirer.js/blob/main/packages/inquirer/README.md)
([source](https://github.com/SBoudrias/Inquirer.js)) | [`10.1.7` ->
`10.1.8`](https://renovatebot.com/diffs/npm/inquirer/10.1.7/10.1.8) |
[![age](https://developer.mend.io/api/mc/badges/age/npm/inquirer/10.1.8?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/inquirer/10.1.8?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/inquirer/10.1.7/10.1.8?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/inquirer/10.1.7/10.1.8?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
| [lucide-react](https://lucide.dev)
([source](https://github.com/lucide-icons/lucide/tree/HEAD/packages/lucide-react))
| [`^0.424.0` ->
`^0.427.0`](https://renovatebot.com/diffs/npm/lucide-react/0.424.0/0.427.0)
|
[![age](https://developer.mend.io/api/mc/badges/age/npm/lucide-react/0.427.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/lucide-react/0.427.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/lucide-react/0.424.0/0.427.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/lucide-react/0.424.0/0.427.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
| [pnpm](https://pnpm.io) ([source](https://github.com/pnpm/pnpm)) |
[`9.6.0` -> `9.7.0`](https://renovatebot.com/diffs/npm/pnpm/9.6.0/9.7.0)
|
[![age](https://developer.mend.io/api/mc/badges/age/npm/pnpm/9.7.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/pnpm/9.7.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/pnpm/9.6.0/9.7.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/pnpm/9.6.0/9.7.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
| [postcss](https://postcss.org/)
([source](https://github.com/postcss/postcss)) | [`^8.4.40` ->
`^8.4.41`](https://renovatebot.com/diffs/npm/postcss/8.4.40/8.4.41) |
[![age](https://developer.mend.io/api/mc/badges/age/npm/postcss/8.4.41?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/postcss/8.4.41?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/postcss/8.4.40/8.4.41?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/postcss/8.4.40/8.4.41?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
|
[prettier-plugin-tailwindcss](https://github.com/tailwindlabs/prettier-plugin-tailwindcss)
| [`^0.6.5` ->
`^0.6.6`](https://renovatebot.com/diffs/npm/prettier-plugin-tailwindcss/0.6.5/0.6.6)
|
[![age](https://developer.mend.io/api/mc/badges/age/npm/prettier-plugin-tailwindcss/0.6.6?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/prettier-plugin-tailwindcss/0.6.6?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/prettier-plugin-tailwindcss/0.6.5/0.6.6?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/prettier-plugin-tailwindcss/0.6.5/0.6.6?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
| [tailwind-merge](https://github.com/dcastil/tailwind-merge) |
[`^2.4.0` ->
`^2.5.0`](https://renovatebot.com/diffs/npm/tailwind-merge/2.4.0/2.5.0)
|
[![age](https://developer.mend.io/api/mc/badges/age/npm/tailwind-merge/2.5.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/tailwind-merge/2.5.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/tailwind-merge/2.4.0/2.5.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/tailwind-merge/2.4.0/2.5.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
| [tailwindcss](https://tailwindcss.com)
([source](https://github.com/tailwindlabs/tailwindcss)) | [`^3.4.7` ->
`^3.4.9`](https://renovatebot.com/diffs/npm/tailwindcss/3.4.7/3.4.9) |
[![age](https://developer.mend.io/api/mc/badges/age/npm/tailwindcss/3.4.9?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/tailwindcss/3.4.9?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/tailwindcss/3.4.7/3.4.9?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/tailwindcss/3.4.7/3.4.9?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|

---

### Release Notes

<details>
<summary>conventional-changelog/commitlint
(@&#8203;commitlint/cli)</summary>

###
[`v19.4.0`](https://github.com/conventional-changelog/commitlint/blob/HEAD/@&#8203;commitlint/cli/CHANGELOG.md#1940-2024-08-07)

[Compare
Source](https://github.com/conventional-changelog/commitlint/compare/v19.3.0...v19.4.0)

##### Features

- support command line options from a file
([#&#8203;4109](https://github.com/conventional-changelog/commitlint/issues/4109))
([a20e890](https://github.com/conventional-changelog/commitlint/commit/a20e890f6b6c8bacdc511d40cb41f29415bdd044))
- support linting from the last tag
([#&#8203;4110](https://github.com/conventional-changelog/commitlint/issues/4110))
([4b204ec](https://github.com/conventional-changelog/commitlint/commit/4b204ecfb43dd6a00e24b51111aadbd78f9d58e1))

</details>

<details>
<summary>conventional-changelog/commitlint
(@&#8203;commitlint/cz-commitlint)</summary>

###
[`v19.4.0`](https://github.com/conventional-changelog/commitlint/blob/HEAD/@&#8203;commitlint/cz-commitlint/CHANGELOG.md#1940-2024-08-07)

[Compare
Source](https://github.com/conventional-changelog/commitlint/compare/v19.2.0...v19.4.0)

**Note:** Version bump only for package
[@&#8203;commitlint/cz-commitlint](https://github.com/commitlint/cz-commitlint)

</details>

<details>
<summary>microsoft/playwright (@&#8203;playwright/test)</summary>

###
[`v1.46.0`](https://github.com/microsoft/playwright/compare/v1.45.3...99a36310570617222290c09b96a2026beb8b00f9)

[Compare
Source](https://github.com/microsoft/playwright/compare/v1.45.3...v1.46.0)

</details>

<details>
<summary>typescript-eslint/typescript-eslint
(@&#8203;typescript-eslint/eslint-plugin)</summary>

###
[`v8.0.1`](https://github.com/typescript-eslint/typescript-eslint/blob/HEAD/packages/eslint-plugin/CHANGELOG.md#801-2024-08-05)

[Compare
Source](https://github.com/typescript-eslint/typescript-eslint/compare/v8.0.0...v8.0.1)

##### 🩹 Fixes

- **eslint-plugin:** \[no-unused-vars] ignore imports used only as types

##### ❤️  Thank You

-   Jake Bailey

You can read about our [versioning
strategy](https://main--typescript-eslint.netlify.app/users/versioning)
and
[releases](https://main--typescript-eslint.netlify.app/users/releases)
on our website.

</details>

<details>
<summary>typescript-eslint/typescript-eslint
(@&#8203;typescript-eslint/parser)</summary>

###
[`v8.0.1`](https://github.com/typescript-eslint/typescript-eslint/blob/HEAD/packages/parser/CHANGELOG.md#801-2024-08-05)

[Compare
Source](https://github.com/typescript-eslint/typescript-eslint/compare/v8.0.0...v8.0.1)

This was a version bump only for parser to align it with other projects,
there were no code changes.

You can read about our [versioning
strategy](https://main--typescript-eslint.netlify.app/users/versioning)
and
[releases](https://main--typescript-eslint.netlify.app/users/releases)
on our website.

</details>

<details>
<summary>testing-library/eslint-plugin-testing-library
(eslint-plugin-testing-library)</summary>

###
[`v6.3.0`](https://github.com/testing-library/eslint-plugin-testing-library/compare/v6.2.2...4dc7caa86b880d7b762a5df23f4ec736a548b502)

[Compare
Source](https://github.com/testing-library/eslint-plugin-testing-library/compare/v6.2.2...v6.3.0)

</details>

<details>
<summary>SBoudrias/Inquirer.js (inquirer)</summary>

###
[`v10.1.8`](https://github.com/SBoudrias/Inquirer.js/compare/inquirer@10.1.7...inquirer@10.1.8)

[Compare
Source](https://github.com/SBoudrias/Inquirer.js/compare/inquirer@10.1.7...inquirer@10.1.8)

</details>

<details>
<summary>lucide-icons/lucide (lucide-react)</summary>

###
[`v0.427.0`](https://github.com/lucide-icons/lucide/releases/tag/0.427.0):
New icons 0.427.0

[Compare
Source](https://github.com/lucide-icons/lucide/compare/0.426.0...0.427.0)

#### New icons 🎨

- `binoculars`
([#&#8203;2207](https://github.com/lucide-icons/lucide/issues/2207))
by [@&#8203;karsa-mistmere](https://github.com/karsa-mistmere)
- `tickets`
([#&#8203;2335](https://github.com/lucide-icons/lucide/issues/2335))
by [@&#8203;jguddas](https://github.com/jguddas)

###
[`v0.426.0`](https://github.com/lucide-icons/lucide/releases/tag/0.426.0):
New icons 0.426.0

[Compare
Source](https://github.com/lucide-icons/lucide/compare/0.425.0...0.426.0)

#### New icons 🎨

- `chevrons-left-right-ellipsis`
([#&#8203;2120](https://github.com/lucide-icons/lucide/issues/2120))
by [@&#8203;ericfennis](https://github.com/ericfennis)
- `ethernet-port`
([#&#8203;2120](https://github.com/lucide-icons/lucide/issues/2120))
by [@&#8203;ericfennis](https://github.com/ericfennis)

#### Modified Icons 🔨

- `cigarette-off`
([#&#8203;2282](https://github.com/lucide-icons/lucide/issues/2282))
by [@&#8203;jguddas](https://github.com/jguddas)
- `cigarette`
([#&#8203;2282](https://github.com/lucide-icons/lucide/issues/2282))
by [@&#8203;jguddas](https://github.com/jguddas)

###
[`v0.425.0`](https://github.com/lucide-icons/lucide/releases/tag/0.425.0):
New icons 0.425.0

[Compare
Source](https://github.com/lucide-icons/lucide/compare/0.424.0...0.425.0)

#### New icons 🎨

- `bandage`
([#&#8203;2341](https://github.com/lucide-icons/lucide/issues/2341))
by [@&#8203;karsa-mistmere](https://github.com/karsa-mistmere)
- `table-of-contents`
([#&#8203;2348](https://github.com/lucide-icons/lucide/issues/2348))
by [@&#8203;karsa-mistmere](https://github.com/karsa-mistmere)

#### Modified Icons 🔨

- `mouse-pointer-2`
([#&#8203;2350](https://github.com/lucide-icons/lucide/issues/2350))
by [@&#8203;karsa-mistmere](https://github.com/karsa-mistmere)
- `mouse-pointer-ban`
([#&#8203;2350](https://github.com/lucide-icons/lucide/issues/2350))
by [@&#8203;karsa-mistmere](https://github.com/karsa-mistmere)
- `mouse-pointer-click`
([#&#8203;2350](https://github.com/lucide-icons/lucide/issues/2350))
by [@&#8203;karsa-mistmere](https://github.com/karsa-mistmere)
- `mouse-pointer`
([#&#8203;2350](https://github.com/lucide-icons/lucide/issues/2350))
by [@&#8203;karsa-mistmere](https://github.com/karsa-mistmere)
- `square-dashed-mouse-pointer`
([#&#8203;2350](https://github.com/lucide-icons/lucide/issues/2350))
by [@&#8203;karsa-mistmere](https://github.com/karsa-mistmere)
- `square-mouse-pointer`
([#&#8203;2350](https://github.com/lucide-icons/lucide/issues/2350))
by [@&#8203;karsa-mistmere](https://github.com/karsa-mistmere)

</details>

<details>
<summary>pnpm/pnpm (pnpm)</summary>

### [`v9.7.0`](https://github.com/pnpm/pnpm/releases/tag/v9.7.0): pnpm
9.7

[Compare Source](https://github.com/pnpm/pnpm/compare/v9.6.0...v9.7.0)

#### Minor Changes

- Added pnpm version management. If the
`manage-package-manager-versions` setting is set to `true`, pnpm will
switch to the version specified in the `packageManager` field of
`package.json` [#&#8203;8363](https://github.com/pnpm/pnpm/pull/8363).
This is the same field used by Corepack. Example:

    ```json
    {
      "packageManager": "pnpm@9.3.0"
    }
    ```

- Added the ability to apply patch to all versions
[#&#8203;8337](https://github.com/pnpm/pnpm/pull/8337).

If the key of `pnpm.patchedDependencies` is a package name without a
version (e.g. `pkg`), pnpm will attempt to apply the patch to all
versions of the package. Failures will be skipped. If there's only one
version of `pkg` installed, `pnpm patch pkg` and subsequent `pnpm
patch-commit $edit_dir` will create an entry named `pkg` in
`pnpm.patchedDependencies`. And pnpm will attempt to apply this patch to
other versions of `pkg` in the future.

- Change the default edit dir location when running `pnpm patch` from a
temporary directory to `node_modules/.pnpm_patches/pkg[@&#8203;version]`
to allow the code editor to open the edit dir in the same file tree as
the main project
[#&#8203;8379](https://github.com/pnpm/pnpm/issues/8379).

- Substitute environment variables in config keys
[#&#8203;6679](https://github.com/pnpm/pnpm/issues/6679).

#### Patch Changes

- `pnpm install` should run `node-gyp rebuild` if the project has a
`binding.gyp` file even if the project doesn't have an install script
[#&#8203;8293](https://github.com/pnpm/pnpm/issues/8293).
- Print warnings to stderr
[#&#8203;8342](https://github.com/pnpm/pnpm/pull/8342).
- Peer dependencies of optional peer dependencies should be
automatically installed
[#&#8203;8323](https://github.com/pnpm/pnpm/issues/8323).

#### Platinum Sponsors

<table>
  <tbody>
    <tr>
      <td align="center" valign="middle">
<a href="https://bit.dev/?utm_source=pnpm&utm_medium=release_notes"
target="_blank"><img src="https://pnpm.io/img/users/bit.svg"
width="80"></a>
      </td>
      <td align="center" valign="middle">
<a href="https://figma.com/?utm_source=pnpm&utm_medium=release_notes"
target="_blank"><img src="https://pnpm.io/img/users/figma.svg"
width="80"></a>
      </td>
    </tr>
  </tbody>
</table>

#### Gold Sponsors

<table>
  <tbody>
    <tr>
      <td align="center" valign="middle">
<a href="https://discord.com/?utm_source=pnpm&utm_medium=release_notes"
target="_blank">
          <picture>
<source media="(prefers-color-scheme: light)"
srcset="https://pnpm.io/img/users/discord.svg" />
<source media="(prefers-color-scheme: dark)"
srcset="https://pnpm.io/img/users/discord_light.svg" />
<img src="https://pnpm.io/img/users/discord.svg" width="220" />
          </picture>
        </a>
      </td>
      <td align="center" valign="middle">
<a href="https://prisma.io/?utm_source=pnpm&utm_medium=release_notes"
target="_blank">
          <picture>
<source media="(prefers-color-scheme: light)"
srcset="https://pnpm.io/img/users/prisma.svg" />
<source media="(prefers-color-scheme: dark)"
srcset="https://pnpm.io/img/users/prisma_light.svg" />
<img src="https://pnpm.io/img/users/prisma.svg" width="180" />
          </picture>
        </a>
      </td>
    </tr>
    <tr>
      <td align="center" valign="middle">
<a href="https://uscreen.de/?utm_source=pnpm&utm_medium=release_notes"
target="_blank">
          <picture>
<source media="(prefers-color-scheme: light)"
srcset="https://pnpm.io/img/users/uscreen.svg" />
<source media="(prefers-color-scheme: dark)"
srcset="https://pnpm.io/img/users/uscreen_light.svg" />
<img src="https://pnpm.io/img/users/uscreen.svg" width="180" />
          </picture>
        </a>
      </td>
      <td align="center" valign="middle">
<a
href="https://www.jetbrains.com/?utm_source=pnpm&utm_medium=release_notes"
target="_blank">
          <picture>
<source media="(prefers-color-scheme: light)"
srcset="https://pnpm.io/img/users/jetbrains.svg" />
<source media="(prefers-color-scheme: dark)"
srcset="https://pnpm.io/img/users/jetbrains.svg" />
<img src="https://pnpm.io/img/users/jetbrains.svg" width="180" />
          </picture>
        </a>
      </td>
    </tr>
    <tr>
      <td align="center" valign="middle">
<a href="https://nx.dev/?utm_source=pnpm&utm_medium=release_notes"
target="_blank">
          <picture>
<source media="(prefers-color-scheme: light)"
srcset="https://pnpm.io/img/users/nx.svg" />
<source media="(prefers-color-scheme: dark)"
srcset="https://pnpm.io/img/users/nx_light.svg" />
            <img src="https://pnpm.io/img/users/nx.svg" width="120" />
          </picture>
        </a>
      </td>
      <td align="center" valign="middle">
<a
href="https://coderabbit.ai/?utm_source=pnpm&utm_medium=release_notes"
target="_blank">
          <picture>
<source media="(prefers-color-scheme: light)"
srcset="https://pnpm.io/img/users/coderabbit.svg" />
<source media="(prefers-color-scheme: dark)"
srcset="https://pnpm.io/img/users/coderabbit_light.svg" />
<img src="https://pnpm.io/img/users/coderabbit.svg" width="220" />
          </picture>
        </a>
      </td>
    </tr>
  </tbody>
</table>

#### Our Silver Sponsors

<table>
  <tbody>
    <tr>
      <td align="center" valign="middle">
<a
href="https://leniolabs.com/?utm_source=pnpm&utm_medium=release_notes"
target="_blank">
          <img src="https://pnpm.io/img/users/leniolabs.jpg" width="80">
        </a>
      </td>
      <td align="center" valign="middle">
<a href="https://vercel.com/?utm_source=pnpm&utm_medium=release_notes"
target="_blank">
          <picture>
<source media="(prefers-color-scheme: light)"
srcset="https://pnpm.io/img/users/vercel.svg" />
<source media="(prefers-color-scheme: dark)"
srcset="https://pnpm.io/img/users/vercel_light.svg" />
<img src="https://pnpm.io/img/users/vercel.svg" width="180" />
          </picture>
        </a>
      </td>
    </tr>
    <tr>
      <td align="center" valign="middle">
<a href="https://depot.dev/?utm_source=pnpm&utm_medium=release_notes"
target="_blank">
          <picture>
<source media="(prefers-color-scheme: light)"
srcset="https://pnpm.io/img/users/depot.svg" />
<source media="(prefers-color-scheme: dark)"
srcset="https://pnpm.io/img/users/depot_light.svg" />
<img src="https://pnpm.io/img/users/depot.svg" width="200" />
          </picture>
        </a>
      </td>
      <td align="center" valign="middle">
<a href="https://moonrepo.dev/?utm_source=pnpm&utm_medium=release_notes"
target="_blank">
          <picture>
<source media="(prefers-color-scheme: light)"
srcset="https://pnpm.io/img/users/moonrepo.svg" />
<source media="(prefers-color-scheme: dark)"
srcset="https://pnpm.io/img/users/moonrepo_light.svg" />
<img src="https://pnpm.io/img/users/moonrepo.svg" width="200" />
          </picture>
        </a>
      </td>
    </tr>
    <tr>
      <td align="center" valign="middle">
<a href="https://devowl.io/?utm_source=pnpm&utm_medium=release_notes"
target="_blank">
          <picture>
<source media="(prefers-color-scheme: light)"
srcset="https://pnpm.io/img/users/devowlio.svg" />
<source media="(prefers-color-scheme: dark)"
srcset="https://pnpm.io/img/users/devowlio.svg" />
<img src="https://pnpm.io/img/users/devowlio.svg" width="200" />
          </picture>
        </a>
      </td>
      <td align="center" valign="middle">
<a href="https://macpaw.com/?utm_source=pnpm&utm_medium=release_notes"
target="_blank">
          <picture>
<source media="(prefers-color-scheme: light)"
srcset="https://pnpm.io/img/users/macpaw.svg" />
<source media="(prefers-color-scheme: dark)"
srcset="https://pnpm.io/img/users/macpaw_light.svg" />
<img src="https://pnpm.io/img/users/macpaw.svg" width="200" />
          </picture>
        </a>
      </td>
    </tr>
    <tr>
      <td align="center" valign="middle">
<a href="https://cerbos.dev/?utm_source=pnpm&utm_medium=release_notes"
target="_blank">
          <picture>
<source media="(prefers-color-scheme: light)"
srcset="https://pnpm.io/img/users/cerbos.svg" />
<source media="(prefers-color-scheme: dark)"
srcset="https://pnpm.io/img/users/cerbos_light.svg" />
<img src="https://pnpm.io/img/users/cerbos.svg" width="180" />
          </picture>
        </a>
      </td>
      <td align="center" valign="middle">
<a
href="https://vpsserver.com/en-us/?utm_source=pnpm&utm_medium=release_notes"
target="_blank">
<img src="https://pnpm.io/img/users/vpsserver.svg" width="180" />
        </a>
      </td>
    </tr>
  </tbody>
</table>

</details>

<details>
<summary>postcss/postcss (postcss)</summary>

###
[`v8.4.41`](https://github.com/postcss/postcss/blob/HEAD/CHANGELOG.md#8441)

[Compare
Source](https://github.com/postcss/postcss/compare/8.4.40...8.4.41)

- Fixed types (by [@&#8203;nex3](https://github.com/nex3) and
[@&#8203;querkmachine](https://github.com/querkmachine)).
-   Cleaned up RegExps (by [@&#8203;bluwy](https://github.com/bluwy)).

</details>

<details>
<summary>tailwindlabs/prettier-plugin-tailwindcss
(prettier-plugin-tailwindcss)</summary>

###
[`v0.6.6`](https://github.com/tailwindlabs/prettier-plugin-tailwindcss/blob/HEAD/CHANGELOG.md#066---2024-08-09)

[Compare
Source](https://github.com/tailwindlabs/prettier-plugin-tailwindcss/compare/v0.6.5...v0.6.6)

- Add support for `prettier-plugin-multiline-arrays`
([#&#8203;299](https://github.com/tailwindlabs/prettier-plugin-tailwindcss/pull/299))
- Add resolution cache for known plugins
([#&#8203;301](https://github.com/tailwindlabs/prettier-plugin-tailwindcss/pull/301))
- Support Tailwind CSS `v4.0.0-alpha.19`
([#&#8203;310](https://github.com/tailwindlabs/prettier-plugin-tailwindcss/pull/310))

</details>

<details>
<summary>dcastil/tailwind-merge (tailwind-merge)</summary>

###
[`v2.5.0`](https://github.com/dcastil/tailwind-merge/releases/tag/v2.5.0)

[Compare
Source](https://github.com/dcastil/tailwind-merge/compare/v2.4.0...v2.5.0)

##### New Features

- Performance improvements in mergeClassList by
[@&#8203;XantreDev](https://github.com/XantreDev) in
[https://github.com/dcastil/tailwind-merge/pull/450](https://github.com/dcastil/tailwind-merge/pull/450)
and [@&#8203;rortan134](https://github.com/rortan134) in
[https://github.com/dcastil/tailwind-merge/pull/445](https://github.com/dcastil/tailwind-merge/pull/445)
- Use arrow functions where possible to help with minification by
[@&#8203;VIKTORVAV99](https://github.com/VIKTORVAV99) in
[https://github.com/dcastil/tailwind-merge/pull/449](https://github.com/dcastil/tailwind-merge/pull/449)

##### Bug Fixes

- Fix bg-opacity arbitrary percentages not being recognized properly by
[@&#8203;dcastil](https://github.com/dcastil) in
[https://github.com/dcastil/tailwind-merge/pull/451](https://github.com/dcastil/tailwind-merge/pull/451)

**Full Changelog**:
dcastil/tailwind-merge@v2.4.0...v2.5.0

Thanks to
[@&#8203;brandonmcconnell](https://github.com/brandonmcconnell),
[@&#8203;manavm1990](https://github.com/manavm1990),
[@&#8203;langy](https://github.com/langy) and
[@&#8203;jamesreaco](https://github.com/jamesreaco) for sponsoring
tailwind-merge! ❤️

</details>

<details>
<summary>tailwindlabs/tailwindcss (tailwindcss)</summary>

###
[`v3.4.9`](https://github.com/tailwindlabs/tailwindcss/releases/tag/v3.4.9)

[Compare
Source](https://github.com/tailwindlabs/tailwindcss/compare/v3.4.8...v3.4.9)

##### Fixed

- No longer warns when broad glob patterns are detecting `vendor`
folders

###
[`v3.4.8`](https://github.com/tailwindlabs/tailwindcss/compare/v3.4.7...1676118af9dd1ca2b59f3f9b91afef4d0b453ea5)

[Compare
Source](https://github.com/tailwindlabs/tailwindcss/compare/v3.4.7...v3.4.8)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - "before 4am on Monday" in timezone
Europe/Amsterdam, Automerge - At any time (no schedule defined).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

👻 **Immortal**: This PR will be recreated if closed unmerged. Get
[config help](https://github.com/renovatebot/renovate/discussions) if
that's undesired.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend
Renovate](https://www.mend.io/free-developer-tools/renovate/). View the
[repository job
log](https://developer.mend.io/github/remcolakens/next-boilerplate).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOC4yMC4xIiwidXBkYXRlZEluVmVyIjoiMzguMjAuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIl19-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
context-v2 Related to tailwind-merge v2 feature Is new feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants