diff --git a/Cargo.lock b/Cargo.lock
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2124,15 +2124,15 @@ dependencies = [
 
 [[package]]
 name = "harfrust"
-version = "0.13.3"
+version = "0.15.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "948d0741125ba89cd3e1c23e5642415b6ade7e1d29d67ba25fb925b533e989d6"
+checksum = "865dcc4105d51c323d8fedbb2d75b5e9c8ecddf5613f74c82f851d0afbc97114"
 dependencies = [
  "bitflags 2.13.2",
  "bytemuck",
- "once_cell",
- "read-fonts 0.43.3",
+ "read-fonts 0.46.0",
  "smallvec",
+ "yoke",
 ]
 
 [[package]]
@@ -4271,9 +4271,9 @@ dependencies = [
 
 [[package]]
 name = "read-fonts"
-version = "0.43.3"
+version = "0.44.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "005c8acf251756c478b0bf402885bfd88a1476020c4c7e6060edc1aa68da38ea"
+checksum = "d5a0cf4bb6cbce4c29756270d189a5e400ac05e91192161d83a0bcb6e68492e8"
 dependencies = [
  "bytemuck",
  "font-types 0.12.7",
@@ -4282,13 +4282,16 @@ dependencies = [
 
 [[package]]
 name = "read-fonts"
-version = "0.44.0"
+version = "0.46.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d5a0cf4bb6cbce4c29756270d189a5e400ac05e91192161d83a0bcb6e68492e8"
+checksum = "bdaa4fffe9ff3ca2c353fa9729792805b9b3e324695ff5a081f860612e81b330"
 dependencies = [
  "bytemuck",
+ "foldhash 0.2.0",
  "font-types 0.12.7",
  "once_cell",
+ "smallvec",
+ "yoke",
 ]
 
 [[package]]
@@ -5079,6 +5082,19 @@ dependencies = [
  "read-fonts 0.44.0",
 ]
 
+[[package]]
+name = "skrifa"
+version = "0.49.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a7459fb60888ad9a5f367dd293fa2fb9df142cb451aa6bfd6cd66a7d6a9b739d"
+dependencies = [
+ "bytemuck",
+ "once_cell",
+ "read-fonts 0.46.0",
+ "smallvec",
+ "yoke",
+]
+
 [[package]]
 name = "slab"
 version = "0.4.12"
@@ -5282,7 +5298,7 @@ dependencies = [
  "kurbo 0.13.1",
  "rustc-hash 2.1.3",
  "skrifa 0.42.1",
- "write-fonts",
+ "write-fonts 0.48.1",
 ]
 
 [[package]]
@@ -6336,7 +6352,7 @@ dependencies = [
  "serde",
  "serde_json",
  "sha2",
- "skrifa 0.47.0",
+ "skrifa 0.49.0",
  "smallvec",
  "thiserror 2.0.21",
  "vectorcraft-brush",
@@ -6411,7 +6427,7 @@ dependencies = [
  "resvg",
  "serde",
  "serde_json",
- "skrifa 0.47.0",
+ "skrifa 0.49.0",
  "svgtypes 0.16.1",
  "thiserror 2.0.21",
  "usvg 0.48.1",
@@ -6446,11 +6462,11 @@ dependencies = [
 name = "vectorcraft-text"
 version = "0.17.0"
 dependencies = [
- "harfrust 0.13.3",
+ "harfrust 0.15.0",
  "icu_segmenter",
  "kurbo 0.13.1",
  "log",
- "skrifa 0.47.0",
+ "skrifa 0.49.0",
  "subsetter",
  "unicode-bidi",
  "unicode-general-category",
@@ -6460,7 +6476,7 @@ dependencies = [
  "vectorcraft-geom",
  "vello_cpu",
  "windows-registry",
- "write-fonts",
+ "write-fonts 0.55.0",
 ]
 
 [[package]]
@@ -7537,6 +7553,19 @@ dependencies = [
  "read-fonts 0.39.2",
 ]
 
+[[package]]
+name = "write-fonts"
+version = "0.55.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3e91ad74b39f48f456560ed1ccc75959efa19bf6f0817d1560751bb49db84f6c"
+dependencies = [
+ "font-types 0.12.7",
+ "indexmap",
+ "kurbo 0.13.1",
+ "log",
+ "read-fonts 0.46.0",
+]
+
 [[package]]
 name = "write16"
 version = "1.0.0"
diff --git a/Cargo.toml b/Cargo.toml
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -83,8 +83,8 @@ usvg = { version = "0.48", default-features = false, features = ["svgz"] }
 # Without `simple-text` (its text shaping, the only user of rustybuzz and ttf-parser, which are
 # unmaintained, #1730): the PDF writer places glyphs itself. A test of the PDF crate turns it on.
 krilla = { version = "0.8", default-features = false, features = ["raster-images"] }
-skrifa = "0.47"
-harfrust = "0.13"
+skrifa = "0.49"
+harfrust = "0.15"
 linesweeper = "0.5"
 flate2 = { version = "1", default-features = false, features = ["rust_backend"] }
 rustix = { version = "1.1", default-features = false }
diff --git a/crates/text/Cargo.toml b/crates/text/Cargo.toml
--- a/crates/text/Cargo.toml
+++ b/crates/text/Cargo.toml
@@ -33,7 +33,7 @@ unicode-segmentation = "1.13"
 vello_cpu = { workspace = true }
 # Builds a small variable font for tests (`test_fonts`; no font file is committed). MIT OR
 # Apache-2.0, already in the build through subsetter.
-write-fonts = { version = "0.48", optional = true }
+write-fonts = { version = "0.55", optional = true }
 
 [features]
 default = ["bundled-fonts"]
@@ -47,7 +47,7 @@ bundled-fonts = []
 test-fonts = ["dep:write-fonts"]
 
 [dev-dependencies]
-write-fonts = "0.48"
+write-fonts = "0.55"
 
 # Fonts registered with Windows outside its font folders ("install as shortcut", installers);
 # MIT OR Apache-2.0, a safe wrapper of the registry API from the windows-rs project.
