Skip to content

refactor: replace kuchikiki with dom_query - #14959

Merged
Legend-Master merged 37 commits into
tauri-apps:devfrom
thomaseizinger:chore/replace-kuchikiki-dom_query
Mar 25, 2026
Merged

refactor: replace kuchikiki with dom_query#14959
Legend-Master merged 37 commits into
tauri-apps:devfrom
thomaseizinger:chore/replace-kuchikiki-dom_query

Conversation

@thomaseizinger

Copy link
Copy Markdown
Contributor

This PR removes the dependency on kuchikiki from the tauri-cli and tauri-utils crates. It is still being pulled in by wry but that is not part of this repository and needs to be dealt with separately.

Resolves: #14958

@thomaseizinger
thomaseizinger requested a review from a team as a code owner February 17, 2026 05:16
@github-actions

github-actions Bot commented Feb 17, 2026

Copy link
Copy Markdown
Contributor

Package Changes Through 91888fb

There are 9 changes which include tauri-macos-sign with patch, tauri-build with patch, tauri with minor, tauri-bundler with patch, tauri-cli with patch, @tauri-apps/cli with patch, tauri-runtime-wry with minor, tauri-runtime with minor, tauri-utils with minor

Planned Package Versions

The following package releases are the planned based on the context of changes in this pull request.

package current next
tauri-utils 2.8.3 2.9.0
tauri-macos-sign 2.3.3 2.3.4
tauri-bundler 2.8.1 2.8.2
tauri-runtime 2.10.1 2.11.0
tauri-runtime-wry 2.10.1 2.11.0
tauri-codegen 2.5.5 2.5.6
tauri-macros 2.5.5 2.5.6
tauri-plugin 2.5.4 2.5.5
tauri-build 2.5.6 2.5.7
tauri 2.10.3 2.11.0
@tauri-apps/cli 2.10.1 2.10.2
tauri-cli 2.10.1 2.10.2

Add another change file through the GitHub UI by following this link.


Read about change files or the docs at github.com/jbolda/covector

@Legend-Master Legend-Master left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for working on this

Could we preserve the non mut version of those functions? Asking because it is technically going to break people updating tauri-utils without bumping tauri (we don't fully follow semver on tauri-utils but unfortunately we didn't mark tauri and other dependencies to only take a smaller version range yet)

Also we'll need a change file here and the wry one, and this one will need to wait for the wry one to go through first

Comment thread crates/tauri-utils/src/html.rs Outdated
Comment thread crates/tauri-utils/src/html.rs Outdated
@thomaseizinger

Copy link
Copy Markdown
Contributor Author

Could we preserve the non mut version of those functions?

That is a bit tricky to do. We'd have to make a wrapper for the document that uses interior mutability. Is that something you want?

@Legend-Master

Copy link
Copy Markdown
Contributor

We'd have to make a wrapper for the document that uses interior mutability.

Doesn't NodeRef from dom_query already do that with its nodes?

@thomaseizinger

Copy link
Copy Markdown
Contributor Author

We'd have to make a wrapper for the document that uses interior mutability.

Doesn't NodeRef from dom_query already do that with its nodes?

Yep, I just discovered that as well! Sorry for the bad first iteration.

I've revised this to not be mutable but it is still a breaking change because we used to have kuchikiki's types in the API.

@thomaseizinger

Copy link
Copy Markdown
Contributor Author

Not sure what to do about the CI failures regarding serde? Seems unrelated to this PR.

@Legend-Master

Legend-Master commented Feb 18, 2026

Copy link
Copy Markdown
Contributor

I've revised this to not be mutable but it is still a breaking change because we used to have kuchikiki's types in the API.

Yes, I'm happy as long as old tauri still work with the new tauri-utils though 😂 cc @FabianLars any thoughts on this?

To me I think we should probably mark the entire tauri-utils crate as if it's pre-1.0, meaning 2.5 -> 2.6 will contain breaking changes and adjust our crates to rely on minor versions. Not sure if we should do this before 3.0 though

Not sure what to do about the CI failures regarding serde? Seems unrelated to this PR.

No worries, that's a cache problem for quite some time now

@FabianLars

Copy link
Copy Markdown
Member

To me I think we should probably mark the entire tauri-utils crate as if it's pre-1.0, meaning 2.5 -> 2.6 will contain breaking changes and adjust our crates to rely on minor versions. Not sure if we should do this before 3.0 though

problem is that we re-export tauri-utils in tauri as tauri::utils

No worries, that's a cache problem for quite some time now

i removed the cache, next run should work.

@Legend-Master

Copy link
Copy Markdown
Contributor

problem is that we re-export tauri-utils in tauri as tauri::utils

If we decide to do that, we would also need something like we did for cookie and platform webview crates

Or we should re-think about if we should have an internal util crate or something in v3

@Legend-Master Legend-Master added the type: breaking change This issue or pull request will introduce a breaking change and requires major version bump label Feb 18, 2026
@Legend-Master Legend-Master added this to the 3.0 milestone Feb 18, 2026
@FabianLars

Copy link
Copy Markdown
Member

yeah, something like this i guess. or we make a different design choice for the utils crate. eg no breaking changes (builder pattern or non_exhaustive?) and no third party types in the api and whatever else we can think of.

but yes, we talked about splitting the utils crate up a few times as well

@thomaseizinger

Copy link
Copy Markdown
Contributor Author

To me I think we should probably mark the entire tauri-utils crate as if it's pre-1.0, meaning 2.5 -> 2.6 will contain breaking changes and adjust our crates to rely on minor versions. Not sure if we should do this before 3.0 though

problem is that we re-export tauri-utils in tauri as tauri::utils

Yeah that means any breaking change to tauri-utils is a breaking change to tauri.

If you want to be strict about semver, my suggestion would be:

  • Re-export as little as possible from tauri, also not tauri-utils
  • Do not re-export types from other crates
  • Version crates like tauri-utils independently so you can make breaking changes to it without having to break tauri itself. Yes this means that users have to depend on them separately.
  • Use a tool like cargo-semver-checks to automate this process. Not breaking semver is a very hard thing to do without any tool support.

What is the current policy here? Will this have to wait until Tauri v3?

@FabianLars

Copy link
Copy Markdown
Member

What is the current policy here? Will this have to wait until Tauri v3?

breaking changes in struct fields are fairly common but this here is a bit much for 2.x i think

@thomaseizinger

Copy link
Copy Markdown
Contributor Author

What is the current policy here? Will this have to wait until Tauri v3?

breaking changes in struct fields are fairly common but this here is a bit much for 2.x i think

Because we are exposing a type with a different API? What if we create a wrapper around dom_query::Document that mimics the previous API?

@FabianLars

FabianLars commented Feb 20, 2026

Copy link
Copy Markdown
Member

if we could mimic the api in a way that would not break "old" tauri-codegen and tauri versions that somehow use newer tauri-utils versions that would be ideal. I assume virtually nobody uses the html-manipulation feature directly so i don't really care about anything else (including the use in tauri-cli)

not sure how reasonable/realistic that wish is

@thomaseizinger

Copy link
Copy Markdown
Contributor Author

We can mimic it such that zero code changes are required when you upgrade both. But you still need to upgrade both because they are just not the same type. If you only upgrade tauri-utils, it is not going to work.

I was under the impression that all tauri crates need to be bumped together anyway always.

There is one approach that we can take if you want to be fully backwards-compatible:

  • Leave all the previous code in place
  • Add an entirely new module that uses dom_query
  • Add a new feature-flag
  • Require a more recent version of tauri-utils in all other crates and stop using the old API. That way, the public API here only receives additions and it is thus backwards-compatible.

Let me know what you prefer.

@Legend-Master

Copy link
Copy Markdown
Contributor

Looking at the usage, mimicking the methods can be quite hard to maintain since we'll need to wrap them with our own structs

Feature flags can work, but it's also quite hard, we'll need a new default feature set and enable the old feature for tauri-utils, then use default-features = false + enable the new feature in dependent crates

If the dependency issue of kuchikiki isn't critical, I am leaning towards delaying this to v3

And in v3, I would really like to bump all tauri crate minor versions together, and make the dependency rely on minors (e.g. ~3.3), also marking internal dependencies non-stable between minor bumps

(or alternatively, change up the way we release things by bumping major versions and use a 'forth' digit to indicate major feature/change releases (like 301.5.2 to indicate major version 3, breaking change 1, minor 5, patch 2) 😂 https://antfu.me/posts/epoch-semver)

@thomaseizinger

Copy link
Copy Markdown
Contributor Author

Feature flags can work, but it's also quite hard, we'll need a new default feature set and enable the old feature for tauri-utils, then use default-features = false + enable the new feature in dependent crates

I don't think we need to? tauri-utils currently doesn't have any default features and the build feature can stay as is. We just need to introduce a new html-manipulation-2 feature that uses dom_query and internally, between Tauri crates, we just stop using the build feature and list the other ones out explicitly, replacing html-manipulation with html-manipulation-2.

That is entirely backwards-compatible and allows anyone to remove kuchikiki from their dependency tree.

@thomaseizinger
thomaseizinger force-pushed the chore/replace-kuchikiki-dom_query branch 2 times, most recently from 9bbd2d4 to 50fb8a9 Compare February 23, 2026 06:24
@thomaseizinger

thomaseizinger commented Feb 23, 2026

Copy link
Copy Markdown
Contributor Author

Let me know what you think of the latest version. If I am not mistaken, this is fully backwards-compatible. Feature-naming subject to bike-shedding of course, I just wanted to demonstrate the concept.

@FabianLars

Copy link
Copy Markdown
Member

i for one could totally live with this approach :)

@thomaseizinger

Copy link
Copy Markdown
Contributor Author

i for one could totally live with this approach :)

Cool! I'll fix the clippy warnings and then test in our repo to ensure the dependencies do go away.

@thomaseizinger

Copy link
Copy Markdown
Contributor Author

Okay, CI should be passing now. I've patched in this branch into my repo and it seems to work. The thing though is, all plugins will need to be updated to no longer use the build feature.

For now, I've unrolled the build feature in this PR. Should we introduce a build-2 (name subject to bike-shedding) that can be used in place of the old one? With Tauri v3, that can then be removed again in favor of build.

@thomaseizinger

Copy link
Copy Markdown
Contributor Author

The thing though is, all plugins will need to be updated to no longer use the build feature.

Actually, it is only the fs plugin so maybe we don't need to introduce build-2.

@thomaseizinger

Copy link
Copy Markdown
Contributor Author

The thing though is, all plugins will need to be updated to no longer use the build feature.

Actually, it is only the fs plugin so maybe we don't need to introduce build-2.

I ended up introducing it because there is also a dependency on the build feature to enable the build module which I've now enabled in both cases (build and build-2).

@Legend-Master

Legend-Master commented Feb 24, 2026

Copy link
Copy Markdown
Contributor

Juggling feature flags is not exactly easy, it feels to me that this is too much effort for upgrading a non-critical dependency here. And because of the way features work, it is possible for projects to end up with both branches pulled in and compiled.

That being said, I'm not opposed to this if that's not me working on it 😂 Thanks for the effort!

@Legend-Master

Legend-Master commented Mar 15, 2026

Copy link
Copy Markdown
Contributor

Will wait for new wry and dom query versions and then we can merge this (done as of
6f1f9ca)

And with the chance we got, we might want to also clean up as many pub in the new module as possible, for example #14959 (comment) and mark the module unstable, and lock tauri-utils versions in tauri to minors if possible

@FabianLars

Copy link
Copy Markdown
Member

And with the chance we got, we might want to also clean up as many pub in the new module as possible, for example #14959 (comment) and mark the module unstable

Splitting it up into tauri-utils and tauri-internals or something is stupid right?

@thomaseizinger

Copy link
Copy Markdown
Contributor Author

And with the chance we got, we might want to also clean up as many pub in the new module as possible, for example #14959 (comment) and mark the module unstable

Splitting it up into tauri-utils and tauri-internals or something is stupid right?

In my humble opinion, anything "utils" is always a code-smell because it always end up being a catch-all bucket for all kinds of functionality and causes an entangled mess. Of course, it comes with its own bit of complexity to create a tauri-html or other things but I do think that esp. when it comes to semver, it is worth to split code into cohesive buckets. That way, version bumps are a lot less common and have less of a ripple effect through the ecosystem. With more cohesive crates, the reason why one package depends on another is solely for the functionality it wants from it and not thus is not impacted if something else in its API changes that it is not even using.

So no, I don't think it is a stupid idea. I think it is actually a great idea IF the boundaries of the crates are designed around their functionality, i.e. tauri-html etc.

@FabianLars

Copy link
Copy Markdown
Member

yeah i think we can all agree that tauri-utils contains way too much 😅 but perhaps it's not the time to split it up and simply wait for v3 (iirc getting the config part out of utils was also very tricky?)

@Legend-Master

Copy link
Copy Markdown
Contributor

An internal crate sounds good to me, but in the other hand, I never even realized that the tauri-utils crate is actually a public crate (and tauri even re-exports it) until recently say half a year ago 😂

I don't know how common is a non-semver following internal crate practice in the rust world, but it seems to be something quite common for the npm packages, like docusaurus having @docusaurus/utils, parcel having @parcel/utils

In the other hand, some other packages/crates choose to 0.x for internal packages/crates that does follow semver

Both approaches have their own trade offs though

iirc getting the config part out of utils was also very tricky?

Can't remember the details anymore, I think it was mainly about the ACL and other things being shared by both the config and tauri APIs like TitleBarStyle

@FabianLars

Copy link
Copy Markdown
Member

i'd still follow semver for external crates just to not make cargo's life harder than necessary but imo we don't need to follow tauri's version e.g. we can keep it in 0.x or like chrome on v145+ 🤷

That would also make some de-duplication possible assuming that not every single change we have there is breaking

@thomaseizinger

Copy link
Copy Markdown
Contributor Author

An internal crate sounds good to me, but in the other hand, I never even realized that the tauri-utils crate is actually a public crate (and tauri even re-exports it) until recently say half a year ago 😂

I think that is the root of the issue here. utils crates are fine as long as you are not making them part of your public API. They are "public" in the sense of everyone can depend on it but the versioning doesn't matter then, right? It wouldn't matter if tauri-utils is version 37 as long as it is only used internally. That is what tokio and tokio-util are doing for example and I think that is a very sensible approach.

lucasfernog
lucasfernog previously approved these changes Mar 25, 2026

@lucasfernog lucasfernog left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice one!

FabianLars
FabianLars previously approved these changes Mar 25, 2026
@Legend-Master
Legend-Master dismissed stale reviews from FabianLars and lucasfernog via 91888fb March 25, 2026 12:39

@Legend-Master Legend-Master left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks again for the patience @thomaseizinger !

@Legend-Master
Legend-Master merged commit e032c3b into tauri-apps:dev Mar 25, 2026
27 of 28 checks passed
razein97 pushed a commit to razein97/tauri that referenced this pull request Apr 30, 2026
* test: add more unit-tests for `html` module

* refactor: remove html dependencies from `tauri-cli`

* feat: introduce `html-manipulation-2` feature

* Remove deprecation

* Use new feature flag

* Unroll `build` feature

* Introduce `build-2` feature

* Reduce diff

* Use `build-2` in more places

* Add docs

* Refactor `inject_script_hashes`

* Refactor `with_head`

* Rename serialize and parse functions

* Add changes file

* Remove unused function

* Update changelog

* Remove test

* Update wry

* Add todo comments
we don't have the git blame data in html2, better do it now or never
find it again

* refactor `with_head` to `ensure_head`

* Remove unused casts

* Avoid using format to construct html elements
which has the potential to get injected

* Feature gate `inline_isolation`

* Keep old prepends appends

* Fix `inline_isolation_replaces_src_with_content` test

* End meta tag

* Mirror test to old html module

* Use back to `append_html` for csp and link issue

* Try out dom query main branch

* Use nodes instead to avoid an extra clone

* Use wry 0.54.4 and dom_query 0.27

* Mark stability

* Remove `PatternObject`

---------

Co-authored-by: Tony <legendmastertony@gmail.com>
Co-authored-by: Tony <68118705+Legend-Master@users.noreply.github.com>
razein97 pushed a commit to razein97/tauri that referenced this pull request Apr 30, 2026
* test: add more unit-tests for `html` module

* refactor: remove html dependencies from `tauri-cli`

* feat: introduce `html-manipulation-2` feature

* Remove deprecation

* Use new feature flag

* Unroll `build` feature

* Introduce `build-2` feature

* Reduce diff

* Use `build-2` in more places

* Add docs

* Refactor `inject_script_hashes`

* Refactor `with_head`

* Rename serialize and parse functions

* Add changes file

* Remove unused function

* Update changelog

* Remove test

* Update wry

* Add todo comments
we don't have the git blame data in html2, better do it now or never
find it again

* refactor `with_head` to `ensure_head`

* Remove unused casts

* Avoid using format to construct html elements
which has the potential to get injected

* Feature gate `inline_isolation`

* Keep old prepends appends

* Fix `inline_isolation_replaces_src_with_content` test

* End meta tag

* Mirror test to old html module

* Use back to `append_html` for csp and link issue

* Try out dom query main branch

* Use nodes instead to avoid an extra clone

* Use wry 0.54.4 and dom_query 0.27

* Mark stability

* Remove `PatternObject`

---------

Co-authored-by: Tony <legendmastertony@gmail.com>
Co-authored-by: Tony <68118705+Legend-Master@users.noreply.github.com>
thomaseizinger added a commit to firezone/firezone that referenced this pull request May 7, 2026
This PR harvests the changes we have landed upstream in
tauri-apps/tauri#14959 and allows us to remove a
lot of outdated dependencies from our dependency tree that got pulled in
by the `kuchikiki` dependency which is more or less unmaintained.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

kuchikiki dependency is dragging in very old crates

4 participants