Today I published @wendermedia/astro-components v3.0.0 to npm. This isn’t a patch or a minor — it’s a major bump bundling three connected migrations: Astro 5 → 6, Tailwind 3 → 4 in the templates, and a license change from MIT to the Wender Media Source License v1.0.
Why three migrations in one release
Three breaking changes in a single major bump look like bad engineering — but the alternative would be worse. Three separate major releases (3.0 for Astro 6, 4.0 for Tailwind 4 in templates, 5.0 for the license) would have forced consumers through three back-to-back migrations. That’s friction without value.
Instead: one migration, one migration guide, one CHANGELOG entry. Anyone who wants to stay on v2.x (because their codebase is still on Astro 5) just pins @wendermedia/astro-components@2.1.0 and continues to get MIT-licensed code.
Astro 5 → 6: what changes
Astro 6 isn’t just a dependency bump. It removes several APIs entirely and changes defaults for others:
Node 18 and 20 are no longer supported. Vite 7 is new (or optionally Vite 8 — both work).
The import `import { ViewTransitions } from "astro:transitions"` no longer works. Replacement: `ClientRouter` (same API, new name).
The legacy collections API with `type: "content"` and `type: "data"` is gone. New loader-based API with `glob()` and `file()` from `astro/loaders`.
`z.string().email()` → `z.email()`. Import path is now `astro/zod`. No more `astro:schema`.
Replacement: `import.meta.glob()` with `{ eager: true }` or content collections.
The old Tailwind integration does not support Astro 6. Replacement: `@tailwindcss/vite` as a Vite plugin.
The library itself (src/, integrations/) is surprisingly unaffected by these changes — zero Astro.glob calls, zero <ViewTransitions />, zero content collections in source. All the migration work lives in the templates and bundles — the scaffolds consumers copy into their own projects.
Tailwind 4 in templates: integration becomes Vite plugin
In v2.x all templates used @astrojs/tailwind (the official Astro integration). That integration has been deprecated since Tailwind 4 and does not support Astro 6. The swap:
import { defineConfig } from 'astro/config';
import tailwind from '@astrojs/tailwind';
export default defineConfig({
integrations: [tailwind()],
}); import { defineConfig } from 'astro/config';
import tailwindcss from '@tailwindcss/vite';
export default defineConfig({
integrations: [],
vite: {
plugins: [tailwindcss()],
},
}); Plus: tailwind.config.js is dead. Tailwind 4 doesn’t read the JS config anymore — all tokens live as CSS custom properties in @theme blocks in global.css. That’s its own migration topic, but relevant for library consumers: anyone copying a template also has to migrate their own theme system to @theme.
Storybook 8 → 10: addons absorbed
Storybook 9 absorbed most essential addons into core. Storybook 10 removed the empty stub packages entirely. What used to be separate packages now lives as subpath exports in the main storybook package:
| Storybook 8 | Storybook 10 |
|---|---|
| @storybook/addon-essentials | Absorbed into core (storybook/actions, storybook/viewport, storybook/highlight) |
| @storybook/addon-interactions | Absorbed into core (storybook/test with fn()) |
| @storybook/addon-links | Absorbed into core |
| @storybook/blocks | @storybook/addon-docs/blocks |
| @storybook/manager-api | storybook/manager-api |
| @storybook/theming/create | storybook/theming/create |
In practice: remove four packages from devDependencies, add one new (@storybook/addon-docs for MDX/Meta parsing in Welcome stories), rewrite three subpath imports in .storybook/manager.ts. The 158 story files themselves were untouched — the canonical Meta/StoryObj import from @storybook/web-components is still valid in v10.
License change: MIT → Wender Media Source License v1.0
The most interesting change. v2.x ran under the MIT license. v3.0 runs under a new, custom-written license: the Wender Media Source License v1.0 (WMSL v1.0). SPDX identifier: LicenseRef-Wender-Media-Source-1.0.
This is not an OSI-approved open-source license. It is a source-available license with copyleft elements, inspired by the structure of the Mozilla Public License 2.0:
Free commercial use, local modifications, redistribution under the same license, inclusion in projects under compatible licenses.
Preserve copyright headers in modified files, ship LICENSE in redistributions, preserve author/contributors in derivative package.json files.
README badge "Built with @wendermedia/astro-components" or a credits section mention. Not mandatory — adoption beats forced visibility.
Sublicensing under more permissive license (no relicense to MIT/Apache), removing copyright headers, misrepresenting authorship, using "Wender Media" trademark in derivative names.
If you need MIT code, use v2.1.0. If you’re on Astro 6 and can live with WMSL, you get v3.0 with all the new patterns.
The library vs site migration asymmetry
Migrating a library that lives in a library repo (an npm package, not a site build) has a quirk: the source code directory (src/) is surprisingly neutral to Astro major bumps. All the work concentrates in four disjoint areas:
New LICENSE (354 lines, 14 sections), NOTICE file, package.json (license, version, peerDeps, optionalDeps, engines), README with attribution section, CHANGELOG, MIGRATION guide, all copyright headers.
Seven ViewTransitions → ClientRouter, four content-collections schemas to Content Layer API, five astro.configs to @tailwindcss/vite, all z.string().method() calls to zod-4 syntax.
Eight bundle astro.configs to Tailwind 4, four content-collection configs moved (src/content/config.ts → src/content.config.ts), bundles/blog rss.xml.ts post.slug → post.id, Starlight bumped to 0.39.1.
.storybook/ configs on new subpath imports, Welcome.mdx on @storybook/addon-docs/blocks, four deprecated addons dropped, addon-docs added, vitest compat verified.
The four areas don’t overlap — LICENSE/package.json/README at the root, templates/, bundles/, and .storybook/ are file-scope-disjoint. Once you see this asymmetry, the migration strategy writes itself: each layer can be tackled independently, no git worktree dance needed because nothing collides. The library’s barrel index.ts is essentially neutral — only the copyright header and version string change.
Consumer migration: what you have to do
If you use @wendermedia/astro-components in your project and want to upgrade to v3.0, there’s a complete migration guide in the repo. The short version:
Upgrade from v2.x to v3.0 in five steps
- Check Node
node --version should be 22.12 or higher. If not: nvm install 22 && nvm use 22.
- Install Astro 6
npm install astro@^6 in your project. Follow the official Astro migration for your templates.
- Update the library
npm install @wendermedia/astro-components@^3 — the old v2.1.0 stays available if you need to roll back.
- Set up Tailwind 4
If you copy the templates: replace @astrojs/tailwind with @tailwindcss/vite, replace tailwind.config.js with @theme in CSS.
- Verify
npm run build must complete. If problems arise: pinning v2.1.0 (npm install @wendermedia/astro-components@2.1.0) gives you back the old MIT version.
What’s next
v3.0 is the start of a new line. v3.x will keep Astro 6 as the platform, but the 158 components will keep growing. Two things are in the pipeline:
- React/Vue/Svelte/Solid components — the framework-agnostic versions under
integrations/react/,integrations/vue/etc. will gain about 30 more components. - Experimental component generation CLI —
wm-components new <description>scaffolds new components from a brief description, matching the design system. Experimental, ships with v3.2.
The v2.1.0 pin remains as a long-term LTS option for Astro 5 projects — no updates, but no download penalty either.
Links: