ADR Adapter split
status: superseded
created: 2026-05-17
deciders:
- marvin-brouwerThe @rooted/application package grew to cover two unrelated concerns: build-time configuration for a Vite app (the rootedManifest wrapper, the SEO plugin, the PWA preset) and deployment -- writing the files a host needs to serve the app after a build. These two concerns have different consumers and different change rates. Mixing them in one package forced users to pull in every adapter's dependencies regardless of which host they deploy to.
Decision
Split adapters out of @rooted/application into two new layers:
@rooted/adapter-- a base package that exportsstaticAdapterandroutedAdapter. It contains the shared build logic: readingindex.html, pre-rendering static routes, injecting SEO metadata, and running the SSG pass. Adapter packages depend on this; app developers don't install it directly.@rooted-adapters/*-- one npm package per host (17 packages at the time of this ADR). Each package is a thin wrapper around@rooted/adapterthat handles the host-specific artifacts (_redirects,firebase.json,staticwebapp.config.json,routes.json, etc.).
@rooted/application keeps rootedManifest, the SEO plugin, and the PWA preset. It no longer contains any adapter code.
Consequences
Smaller install footprint. An app deploying to GitHub Pages installs @rooted-adapters/github-pages and nothing else from the adapter layer. It doesn't pull in Fastify server templates, Firebase config writers, or Azure routing rules.
Clearer responsibility. @rooted/application is for configuring a Vite build. The adapter packages are for deployment. Adding a new host means adding a new @rooted-adapters/* package, not touching the build config package.
One extra package to install. Before the split, adapters shipped with @rooted/application at no extra install cost. After the split, every project needs one @rooted-adapters/* package in devDependencies. This is a minor friction for existing users.
Custom adapters are now a supported pattern. Third-party packages can depend on @rooted/adapter and export their own adapter functions without forking or patching the core packages.