diff --git a/packages/astro/src/assets/fonts/README.md b/packages/astro/src/assets/fonts/README.md
index bd5a5cbdc788..dd630a729340 100644
--- a/packages/astro/src/assets/fonts/README.md
+++ b/packages/astro/src/assets/fonts/README.md
@@ -1,11 +1,20 @@
# fonts
-The vite plugin orchestrates the fonts logic:
+Here is an overview of the architecture of the fonts in Astro:
-- Retrieves data from the config
-- Initializes font providers
-- Fetches fonts data
-- In dev, serves a middleware that dynamically loads and caches fonts data
-- In build, download fonts data (from cache if possible)
-
-The `` component is the only aspect not managed in the vite plugin, since it's exported from `astro:assets`.
+- [`orchestrate()`](./orchestrate.ts) combines sub steps and takes care of getting useful data from the config
+ - It resolves font families (eg. import remote font providers)
+ - It prepares [`unifont`](https://github.com/unjs/unifont) providers
+ - It initializes `unifont`
+ - For each family, it resolves fonts data and normalizes them
+ - For each family, optimized fallbacks (and related CSS) are generated if applicable
+ - It returns the data
+- [`/logic`](./logic/) contains the sub steps of `orchestrate()` so they can be easily tested
+- The logic uses [inversion of control](https://en.wikipedia.org/wiki/Inversion_of_control) to make it easily testable and swappable
+ - [`definitions.ts`](./definitions.ts) defines dependencies
+ - Those dependencies are implemented in [`/implementations`](./implementations/)
+- [`fontsPlugin()`](./vite-plugin-fonts.ts) calls `orchestrate()` and using its result, setups anything required so that fonts can
+ - Be exposed to users (virual module)
+ - Be used in dev (middleware)
+ - Be used in build (copy)
+- [``](../../../components/Font.astro) is managed in [`assets()`](../vite-plugin-assets.ts) so it can be imported from `astro:assets` and consumes the virtual module