edgeone-makers-frameworks · diff
v1.0.0 to v1.0.0
12 added, 1 removed. Audit A to A.
---
name: edgeone-makers-frameworks
description: >-
Web framework support matrix for EdgeOne Makers — which platform adapter each
full-stack framework needs, where it plugs in, the build output directory, the
preview asset-prefix option, the 404 convention, version floors, and the
features the platform does not support yet. Read this whenever a request names
a web framework: Next.js, Nuxt, Astro, React Router, SvelteKit, TanStack Start,
Vike, Vite / React / Vue, Hugo, or any other frontend framework.
pathPatterns:
- astro.config.mjs
- astro.config.js
- astro.config.ts
- svelte.config.js
- svelte.config.ts
- vite.config.js
- vite.config.ts
- vite.config.mjs
- next.config.js
- next.config.mjs
- nuxt.config.ts
- nuxt.config.js
- react-router.config.ts
validate:
- pattern: "@astrojs/(?:vercel|netlify|cloudflare|node)"
message: "this is another platform's Astro adapter. EdgeOne Makers needs @edgeone/astro; a foreign adapter builds output this platform cannot serve."
- pattern: "@sveltejs/adapter-(?:vercel|netlify|cloudflare|node|auto)"
message: "this is not the EdgeOne SvelteKit adapter. Use @edgeone/sveltekit; adapter-auto cannot detect this platform and adapter-static only works for a fully prerendered site."
- pattern: "serverWrapper"
message: "serverWrapper is the @edgeone/vite 1.x API. Version 2.x discovers the framework entry through the Universal Deploy protocol, so the option is both unnecessary and ignored."
- pattern: "(?:async\\s+)?(?:redirects|rewrites)\\s*(?:\\(|:)"
message: "this platform does not run Next.js redirects or rewrites. Declare them in edgeone.json instead, which is the only place they take effect."
- pattern: "nitro(?:V2)?Plugin|@tanstack/start-plugin-nitro"
message: "the EdgeOne TanStack Start adapter cannot be used alongside a Nitro plugin. Drop the Nitro plugin; an official preset is not published yet."
metadata:
author: edgeone
version: "1.0.0"
---
# Web Frameworks
Which framework a request names decides seven things and nothing else. Every framework
runs the same flow — prepare the workspace, write files, install, start the preview,
verify — and differs only in the values below.
| Slot | Why it matters |
|------|----------------|
| Platform adapter | Without it, `deploy` produces output the platform cannot serve. **The preview does not catch this.** |
| Scaffold command | One command holds both the structure and a working version set |
| Preview asset-prefix option | The single option that moves framework-emitted asset URLs |
| Build command + output directory | What `edgeone.json` must declare when it is not the default |
| 404 convention | Different file in every framework |
| Version floor | Below it the platform's adapter or builder does not apply |
| Unsupported features | Generated code that uses one produces a broken site, not an error |
## The adapter is a deploy-time contract, not a preview-time one
`edgeone makers dev` starts **the framework's own dev server** (it reads `devCommand`
from `edgeone.json`, falling back to the `dev` script in `package.json`). The platform
adapter takes no part in that. `edgeone makers deploy` is different: it runs the build
and expects the adapter to have written platform output.
So a project that needs an adapter and does not have one **previews perfectly and
deploys broken**. Every gate is green. This is the single most expensive mistake
available in this skill, and it is why the adapter column below comes first.
Five frameworks need one: Astro, React Router, SvelteKit, TanStack Start, Vike.
Next.js and Nuxt are supported by the builder directly and need none.
## Read the one document for the framework in the request
| Framework | Read |
|-----------|------|
| Astro | [references/astro.md](references/astro.md) |
| React Router v7 | [references/react-router.md](references/react-router.md) |
| SvelteKit | [references/sveltekit.md](references/sveltekit.md) |
| TanStack Start | [references/tanstack-start.md](references/tanstack-start.md) |
| Vike | [references/vike.md](references/vike.md) |
| Next.js | [references/nextjs.md](references/nextjs.md) |
| Nuxt | [references/nuxt.md](references/nuxt.md) |
| Vite / React / Vue single-page app | [references/vite-spa.md](references/vite-spa.md) |
| Hugo and other static site generators | [references/static-generators.md](references/static-generators.md) |
| Anything else (Docusaurus, Angular, Gatsby, Hexo, Qwik, Remix, Solid) | [references/other-frameworks.md](references/other-frameworks.md) |
Load one. Loading the whole set is 10 documents to answer a question about one framework.
## Custom 404 pages
| Project shape | Where the 404 lives |
|---------------|---------------------|
| Static site generator | any `404.html` in the build output directory |
| Single-page app | a catch-all client route. **Do not** put `404.html` at the output root — it shadows the client router |
| Next.js App Router | `app/not-found.tsx` |
| Nuxt | `app/error.vue` |
| Astro | `src/pages/404.astro` |
| React Router v7 | export `ErrorBoundary` from `app/root.tsx` |
| SvelteKit | `src/routes/+error.svelte`, or one per route subtree |
## Machine-readable profiles
The host reads this block to decide which adapter a project is missing, which package to
add to the first install, and which output directory to expect. It is the same data the
documents above describe in prose — kept here in one parseable place so the compatibility
lint and the install warmup do not each carry their own copy.
Keep it in sync with the per-framework documents.
- `detect` names the dependencies that prove the framework is in use.
- `adapter.version` is the range to declare when a host adds the adapter to `package.json`
on the project's behalf. It is here so that declaring it does not mean `latest`: a
floating tag re-resolves against the registry on every install and dates any lockfile
next to it, which costs a full dependency re-resolution before the project is touched.
- `adapter.configFiles` is where the adapter gets wired in.
- `adapter.required` is `always` when the framework cannot build without an adapter, or
`server-output` when a fully static build needs none.
- `serverOutput` answers "does this project render on a server", which is often a
*different file* from the one the adapter goes in — React Router declares `ssr` in
`react-router.config.ts` while its adapter is a `vite.config.ts` plugin. `default`
mirrors the framework's own default when nothing says otherwise, and the pattern named
for the other mode is what overrides it.
<!-- makers-framework-profiles:start -->
```json
[
{
"id": "astro",
"label": "Astro",
"detect": ["astro"],
"adapter": {
"package": "@edgeone/astro",
"version": "^1.1.5",
"configFiles": ["astro.config.mjs", "astro.config.js", "astro.config.ts"],
"required": "server-output"
},
"serverOutput": {
"files": ["astro.config.mjs", "astro.config.js", "astro.config.ts"],
"default": "static",
"serverPattern": "output\\s*:\\s*['\"](?:server|hybrid)['\"]"
},
"outputDirectory": ".edgeone",
"unsupported": ["Image component optimization", "platform ISR"]
},
{
"id": "react-router",
"label": "React Router v7",
"detect": ["@react-router/dev"],
"adapter": {
"package": "@edgeone/react-router",
"version": "^1.1.10",
"configFiles": ["vite.config.ts", "vite.config.js", "vite.config.mjs"],
"required": "server-output"
},
"serverOutput": {
"files": ["react-router.config.ts", "react-router.config.js"],
"default": "server",
"staticPattern": "ssr\\s*:\\s*false"
},
"outputDirectory": "build",
"unsupported": []
},
{
"id": "sveltekit",
"label": "SvelteKit",
"detect": ["@sveltejs/kit"],
"adapter": {
"package": "@edgeone/sveltekit",
"version": "^1.1.1",
- "configFiles": ["svelte.config.js", "svelte.config.ts"],
+ "configFiles": [
+ "svelte.config.js",
+ "svelte.config.ts",
+ "vite.config.ts",
+ "vite.config.js",
+ "vite.config.mjs"
+ ],
+ "configOverride": {
+ "files": ["vite.config.ts", "vite.config.js", "vite.config.mjs"],
+ "pattern": "sveltekit\\(\\s*[^)\\s]",
+ "reason": "SvelteKit reads one config and prefers the Vite one: because sveltekit() is called with options here, a svelte.config.js beside it is ignored whole, adapter and all. Wire the adapter into this call, or empty the call and keep everything in svelte.config.js."
+ },
"required": "always"
},
"outputDirectory": "",
"unsupported": ["observability"]
},
{
"id": "tanstack-start",
"label": "TanStack Start",
"detect": ["@tanstack/react-start", "@tanstack/solid-start"],
"adapter": {
"package": "@edgeone/tanstack-start",
"version": "^1.1.0",
"configFiles": ["vite.config.ts", "vite.config.js", "vite.config.mjs"],
"required": "always"
},
"outputDirectory": "",
"unsupported": ["Nitro plugins alongside the adapter"]
},
{
"id": "vike",
"label": "Vike",
"detect": ["vike"],
"adapter": {
"package": "@edgeone/vite",
"version": "^2.0.1",
"configFiles": ["vite.config.ts", "vite.config.js", "vite.config.mjs"],
"required": "server-output"
},
"serverOutput": {
"files": ["vite.config.ts", "vite.config.js", "vite.config.mjs", "pages/+config.js", "pages/+config.ts"],
"default": "server",
"staticPattern": "prerender\\s*:\\s*true"
},
"outputDirectory": "dist",
"unsupported": ["server-side API routes — put them in cloud-functions/ instead"]
},
{
"id": "nextjs",
"label": "Next.js",
"detect": ["next"],
"adapter": null,
"outputDirectory": ".next",
"unsupported": ["redirects and rewrites in next.config — declare them in edgeone.json"]
},
{
"id": "nuxt",
"label": "Nuxt",
"detect": ["nuxt"],
"adapter": null,
"outputDirectory": ".output",
"unsupported": ["Nuxt Layers", "@nuxt/image optimization"]
}
]
```
<!-- makers-framework-profiles:end -->