vinext 0.0.3 → 0.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2026 Vinext contributors
3
+ Copyright (c) 2026 Cloudflare, Inc.
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -1 +1,510 @@
1
1
  # vinext
2
+
3
+ The Next.js API surface, reimplemented on Vite.
4
+
5
+ > **Read the announcement:** [How we rebuilt Next.js with AI in one week](https://blog.cloudflare.com/vinext/)
6
+
7
+ > 🚧 **Experimental — under heavy development.** This project is an experiment in AI-driven software development. The vast majority of the code, tests, and documentation were written by AI (Claude Code). Humans direct architecture, priorities, and design decisions, but have not reviewed most of the code line-by-line. Treat this accordingly — there will be bugs, rough edges, and things that don't work. Use at your own risk.
8
+
9
+ ## Quick start
10
+
11
+ vinext includes an [Agent Skill](https://agentskills.io/home) that handles migration for you. It works with Claude Code, OpenCode, Cursor, Codex, and dozens of other AI coding tools. Install it, open your Next.js project, and tell the AI to migrate:
12
+
13
+ ```sh
14
+ npx skills add cloudflare/vinext
15
+ ```
16
+
17
+ Then open your Next.js project in any supported tool and say:
18
+
19
+ ```
20
+ migrate this project to vinext
21
+ ```
22
+
23
+ The skill handles compatibility checking, dependency installation, config generation, and dev server startup. It knows what vinext supports and will flag anything that needs manual attention.
24
+
25
+ ### Or do it manually
26
+
27
+ ```bash
28
+ npm install vinext
29
+ ```
30
+
31
+ Replace `next` with `vinext` in your scripts:
32
+
33
+ ```json
34
+ {
35
+ "scripts": {
36
+ "dev": "vinext dev",
37
+ "build": "vinext build",
38
+ "start": "vinext start"
39
+ }
40
+ }
41
+ ```
42
+
43
+ ```bash
44
+ vinext dev # Development server with HMR
45
+ vinext build # Production build
46
+ vinext deploy # Build and deploy to Cloudflare Workers
47
+ ```
48
+
49
+ vinext auto-detects your `app/` or `pages/` directory, loads `next.config.js`, and configures Vite automatically. No `vite.config.ts` required for basic usage.
50
+
51
+ Your existing `pages/`, `app/`, `next.config.js`, and `public/` directories work as-is. Run `vinext check` first to scan for known compatibility issues, or use `vinext init` to [automate the full migration](#migrating-an-existing-nextjs-project).
52
+
53
+ ### CLI reference
54
+
55
+ | Command | Description |
56
+ |---------|-------------|
57
+ | `vinext dev` | Start dev server with HMR |
58
+ | `vinext build` | Production build (multi-environment for App Router: RSC + SSR + client) |
59
+ | `vinext start` | Start local production server for testing |
60
+ | `vinext deploy` | Build and deploy to Cloudflare Workers |
61
+ | `vinext init` | Migrate a Next.js project to run under vinext |
62
+ | `vinext check` | Scan your Next.js app for compatibility issues before migrating |
63
+ | `vinext lint` | Delegate to eslint or oxlint |
64
+
65
+ Options: `-p / --port <port>`, `-H / --hostname <host>`, `--turbopack` (accepted, no-op).
66
+
67
+ `vinext deploy` options: `--preview`, `--name <name>`, `--skip-build`, `--dry-run`, `--experimental-tpr`.
68
+
69
+ `vinext init` options: `--port <port>` (default: 3001), `--skip-check`, `--force`.
70
+
71
+ ### Migrating an existing Next.js project
72
+
73
+ `vinext init` automates the migration in one command:
74
+
75
+ ```bash
76
+ npx vinext init
77
+ ```
78
+
79
+ This will:
80
+
81
+ 1. Run `vinext check` to scan for compatibility issues
82
+ 2. Install `vite` (and `@vitejs/plugin-rsc` for App Router projects) as devDependencies
83
+ 3. Rename CJS config files (e.g. `postcss.config.js` -> `.cjs`) to avoid ESM conflicts
84
+ 4. Add `"type": "module"` to `package.json`
85
+ 5. Add `dev:vinext` and `build:vinext` scripts to `package.json`
86
+ 6. Generate a minimal `vite.config.ts`
87
+
88
+ The migration is non-destructive -- your existing Next.js setup continues to work alongside vinext. It does not modify `next.config`, `tsconfig.json`, or any source files, and it does not remove Next.js dependencies.
89
+
90
+ ```bash
91
+ npm run dev:vinext # Start the vinext dev server (port 3001)
92
+ npm run dev # Still runs Next.js as before
93
+ ```
94
+
95
+ Use `--force` to overwrite an existing `vite.config.ts`, or `--skip-check` to skip the compatibility report.
96
+
97
+ ## Why
98
+
99
+ Vite has become the default build tool for modern web frameworks — fast HMR, a clean plugin API, native ESM, and a growing ecosystem. With [`@vitejs/plugin-rsc`](https://github.com/vitejs/vite-plugin-rsc) adding React Server Components support, it's now possible to build a full RSC framework on Vite.
100
+
101
+ vinext is an experiment: can we reimplement the Next.js API surface on Vite, so that existing Next.js applications can run on a completely different toolchain? The answer, so far, is mostly yes — about 94% of the API surface works.
102
+
103
+ The current deployment target is Cloudflare Workers — zero cold starts, global by default, integrated platform (KV, R2, D1, AI). The `vinext deploy` command handles the full build-and-deploy pipeline. Expanding to other deployment targets is something we'd like to explore.
104
+
105
+ **Alternatives worth knowing about:**
106
+ - **[OpenNext](https://opennext.js.org/)** — adapts `next build` output for AWS, Cloudflare, and other platforms. More mature and battle-tested than vinext.
107
+ - **[Next.js self-hosting](https://nextjs.org/docs/app/building-your-application/deploying#self-hosting)** — Next.js can be deployed to any Node.js server, Docker container, or as a static export.
108
+
109
+ ### Design principles
110
+
111
+ - **Start with Cloudflare, expand later.** Workers is the current deployment target. Every feature is built and tested for Workers. We're interested in supporting other platforms and welcome contributions.
112
+ - **Pragmatic compatibility, not bug-for-bug parity.** Targets 95%+ of real-world Next.js apps. Edge cases that depend on undocumented Vercel behavior are intentionally not supported.
113
+ - **Latest Next.js only.** Targets Next.js 16.x. No support for deprecated APIs from older versions.
114
+ - **Incremental adoption.** Drop in the plugin, fix what breaks, deploy.
115
+
116
+ ## FAQ
117
+
118
+ **What is this?**
119
+ vinext is a Vite plugin that reimplements the public Next.js API — routing, server rendering, `next/*` module imports, the CLI — so you can run Next.js applications on Vite instead of the Next.js compiler toolchain. Cloudflare Workers is the current deployment target.
120
+
121
+ **Is this a fork of Next.js?**
122
+ No. vinext is an alternative implementation of the Next.js API surface built on Vite. It does import some Next.js types and utilities, but the core is written from scratch. The goal is not to create a competing framework or add features beyond what Next.js offers — it's an experiment in how far AI-driven development and Vite's toolchain can go in replicating an existing, well-defined API surface.
123
+
124
+ **How is this different from OpenNext?**
125
+ [OpenNext](https://opennext.js.org/) adapts the *output* of a standard `next build` to run on various platforms. vinext replaces the build entirely — it reimplements the Next.js APIs on Vite from scratch. OpenNext is a great choice if you need production-ready Next.js on non-Vercel platforms today.
126
+
127
+ **Can I use this in production?**
128
+ You can, with caution. This is experimental software with known bugs. It works well enough for demos and exploration, but it hasn't been battle-tested with real production traffic.
129
+
130
+ **Can I just self-host Next.js?**
131
+ Yes. Next.js supports [self-hosting](https://nextjs.org/docs/app/building-your-application/deploying#self-hosting) on Node.js servers, Docker containers, and static exports. If you're happy with the Next.js toolchain and just want to run it somewhere other than Vercel, self-hosting is the simplest path.
132
+
133
+ **How are you verifying this works?**
134
+ The test suite has over 1,700 Vitest tests and 380 Playwright E2E tests. This includes tests ported directly from the [Next.js test suite](https://github.com/vercel/next.js/tree/canary/test) and [OpenNext's Cloudflare conformance suite](https://github.com/opennextjs/opennextjs-cloudflare), covering routing, SSR, RSC, server actions, caching, metadata, middleware, streaming, and more. Vercel's [App Router Playground](https://github.com/vercel/next-app-router-playground) also runs on vinext as an integration test. See the [Tests](#tests) section and `tests/nextjs-compat/TRACKING.md` for details.
135
+
136
+ **Who is reviewing this code?**
137
+ Mostly nobody. This is an experiment in seeing how far AI-driven development can go. The test suite is the primary quality gate — not human code review. Contributions and code review are welcome.
138
+
139
+ **Why Vite?**
140
+ Vite is an excellent build tool with a rich plugin ecosystem, first-class ESM support, and fast HMR. The [`@vitejs/plugin-rsc`](https://github.com/vitejs/vite-plugin-rsc) plugin adds React Server Components support with multi-environment builds. This project is an experiment to see how much of the Next.js developer experience can be replicated on top of Vite's infrastructure.
141
+
142
+ **Does this support the Pages Router, App Router, or both?**
143
+ Both. File-system routing, SSR, client hydration, and deployment to Cloudflare Workers work for both routers.
144
+
145
+ **What version of Next.js does this target?**
146
+ Next.js 16.x. No support for deprecated APIs from older versions.
147
+
148
+ **Can I deploy to AWS/Netlify/other platforms?**
149
+ Currently only Cloudflare Workers is supported and tested. We're interested in exploring other deployment targets in the future and welcome contributions in that direction.
150
+
151
+ **What happens when Next.js releases a new feature?**
152
+ We track the public Next.js API surface and add support for new stable features. Experimental or unstable Next.js features are lower priority. The plan is to add commit-level tracking of the Next.js repo so we can stay current as new versions are released.
153
+
154
+ ## Deploying to Cloudflare Workers
155
+
156
+ `vinext deploy` is the simplest path. It auto-generates the necessary configuration files (`vite.config.ts`, `wrangler.jsonc`, `worker/index.ts`) if they don't exist, builds the application, and deploys to Workers.
157
+
158
+ ```bash
159
+ vinext deploy
160
+ ```
161
+
162
+ The deploy command also auto-detects and fixes common migration issues:
163
+ - Adds `"type": "module"` to package.json if missing
164
+ - Resolves tsconfig.json path aliases automatically (via `vite-tsconfig-paths`)
165
+ - Detects MDX usage and configures `@mdx-js/rollup`
166
+ - Renames CJS config files (postcss.config.js, etc.) to `.cjs` when needed
167
+ - Detects native Node.js modules (sharp, resvg, satori, lightningcss, @napi-rs/canvas) and auto-stubs them for Workers. If you encounter others that need stubbing, PRs are welcome.
168
+
169
+ Both App Router and Pages Router work on Workers with full client-side hydration — interactive components, client-side navigation, and React state all work.
170
+
171
+ ### Traffic-aware Pre-Rendering (experimental)
172
+
173
+ TPR queries Cloudflare zone analytics at deploy time to find which pages actually get traffic, pre-renders only those, and uploads them to KV cache. The result is SSG-level latency for popular pages without pre-rendering your entire site.
174
+
175
+ ```bash
176
+ vinext deploy --experimental-tpr # Pre-render pages covering 90% of traffic
177
+ vinext deploy --experimental-tpr --tpr-coverage 95 # More aggressive coverage
178
+ vinext deploy --experimental-tpr --tpr-limit 500 # Cap at 500 pages
179
+ vinext deploy --experimental-tpr --tpr-window 48 # Use 48h of analytics
180
+ ```
181
+
182
+ Requires a custom domain (zone analytics are unavailable on `*.workers.dev`) and `CLOUDFLARE_API_TOKEN` with Zone.Analytics read permission.
183
+
184
+ For production caching (ISR), use the built-in Cloudflare KV cache handler:
185
+
186
+ ```ts
187
+ import { KVCacheHandler } from "vinext/cloudflare";
188
+ import { setCacheHandler } from "next/cache";
189
+
190
+ setCacheHandler(new KVCacheHandler(env.MY_KV_NAMESPACE));
191
+ ```
192
+
193
+ ### Custom Vite configuration
194
+
195
+ If you need to customize the Vite config, create a `vite.config.ts`. vinext will merge its config with yours. This is required for Cloudflare Workers deployment with the App Router (RSC needs explicit plugin configuration):
196
+
197
+ ```ts
198
+ import { defineConfig } from "vite";
199
+ import vinext from "vinext";
200
+ import rsc from "@vitejs/plugin-rsc";
201
+ import { cloudflare } from "@cloudflare/vite-plugin";
202
+
203
+ export default defineConfig({
204
+ plugins: [
205
+ vinext(),
206
+ rsc({
207
+ entries: {
208
+ rsc: "virtual:vinext-rsc-entry",
209
+ ssr: "virtual:vinext-app-ssr-entry",
210
+ client: "virtual:vinext-app-browser-entry",
211
+ },
212
+ }),
213
+ cloudflare({
214
+ viteEnvironment: { name: "rsc", childEnvironments: ["ssr"] },
215
+ }),
216
+ ],
217
+ });
218
+ ```
219
+
220
+ See the [examples](#live-examples) for complete working configurations.
221
+
222
+ ## Live examples
223
+
224
+ These are deployed to Cloudflare Workers and updated on every push to `main`:
225
+
226
+ | Example | Description | URL |
227
+ |---------|-------------|-----|
228
+ | App Router Playground | [Vercel's Next.js App Router Playground](https://github.com/vercel/next-app-router-playground) running on vinext | [app-router-playground.vinext.workers.dev](https://app-router-playground.vinext.workers.dev) |
229
+ | Hacker News | HN clone (App Router, RSC) | [hackernews.vinext.workers.dev](https://hackernews.vinext.workers.dev) |
230
+ | Nextra Docs | Nextra docs site (MDX, App Router) | [nextra-docs-template.vinext.workers.dev](https://nextra-docs-template.vinext.workers.dev) |
231
+ | App Router (minimal) | Minimal App Router on Workers | [app-router-cloudflare.vinext.workers.dev](https://app-router-cloudflare.vinext.workers.dev) |
232
+ | Pages Router (minimal) | Minimal Pages Router on Workers | [pages-router-cloudflare.vinext.workers.dev](https://pages-router-cloudflare.vinext.workers.dev) |
233
+ | RealWorld API | REST API routes example | [realworld-api-rest.vinext.workers.dev](https://realworld-api-rest.vinext.workers.dev) |
234
+ | Benchmarks Dashboard | Build performance tracking over time (D1-backed) | [benchmarks.vinext.workers.dev](https://benchmarks.vinext.workers.dev) |
235
+
236
+ ## API coverage
237
+
238
+ ~94% of the Next.js 16 API surface has full or partial support. The remaining gaps are intentional stubs for deprecated features and Partial Prerendering (which Next.js 16 reworked into `"use cache"` — that directive is fully supported).
239
+
240
+ > ✅ = full implementation | 🟡 = partial (runtime behavior correct, some build-time optimizations missing) | ⬜ = intentional stub/no-op
241
+
242
+ ### Module shims
243
+
244
+ Every `next/*` import is shimmed to a Vite-compatible implementation.
245
+
246
+ | Module | | Notes |
247
+ |--------|---|-------|
248
+ | `next/link` | ✅ | All props including `prefetch` (IntersectionObserver), `onNavigate`, scroll restoration, `basePath`, `locale` |
249
+ | `next/image` | 🟡 | Remote images via [@unpic/react](https://unpic.pics) (28 CDNs). Local images via `<img>` + srcSet. No build-time optimization/resizing |
250
+ | `next/head` | ✅ | SSR collection + client-side DOM manipulation |
251
+ | `next/router` | ✅ | `useRouter`, `Router` singleton, events, client-side navigation, SSR context, i18n |
252
+ | `next/navigation` | ✅ | `usePathname`, `useSearchParams`, `useParams`, `useRouter`, `redirect`, `notFound`, `forbidden`, `unauthorized` |
253
+ | `next/server` | ✅ | `NextRequest`, `NextResponse`, `NextURL`, cookies, `userAgent`, `after`, `connection`, `URLPattern` |
254
+ | `next/headers` | ✅ | Async `headers()`, `cookies()`, `draftMode()` |
255
+ | `next/dynamic` | ✅ | `ssr: true`, `ssr: false`, `loading` component |
256
+ | `next/script` | ✅ | All 4 strategies (`beforeInteractive`, `afterInteractive`, `lazyOnload`, `worker`) |
257
+ | `next/font/google` | 🟡 | Runtime CDN loading. No self-hosting, font subsetting, or fallback metrics |
258
+ | `next/font/local` | 🟡 | Runtime `@font-face` injection. Not extracted at build time |
259
+ | `next/og` | ✅ | OG image generation via `@vercel/og` (Satori + resvg) |
260
+ | `next/cache` | ✅ | `revalidateTag`, `revalidatePath`, `unstable_cache`, pluggable `CacheHandler`, `"use cache"` with `cacheLife()` and `cacheTag()` |
261
+ | `next/form` | ✅ | GET form interception + POST server action delegation |
262
+ | `next/legacy/image` | ✅ | Translates legacy props to modern Image |
263
+ | `next/error` | ✅ | Default error page component |
264
+ | `next/config` | ✅ | `getConfig` / `setConfig` |
265
+ | `next/document` | ✅ | `Html`, `Head`, `Main`, `NextScript` |
266
+ | `next/constants` | ✅ | All phase constants |
267
+ | `next/amp` | ⬜ | No-op (AMP is deprecated) |
268
+ | `next/web-vitals` | ⬜ | No-op (use the `web-vitals` library directly) |
269
+
270
+ ### Routing
271
+
272
+ | Feature | | Notes |
273
+ |---------|---|-------|
274
+ | File-system routing (`pages/`) | ✅ | Automatic scanning with hot-reload on file changes |
275
+ | File-system routing (`app/`) | ✅ | Pages, routes, layouts, templates, loading, error, not-found, forbidden, unauthorized |
276
+ | Dynamic routes `[param]` | ✅ | Both routers |
277
+ | Catch-all `[...slug]` | ✅ | Both routers |
278
+ | Optional catch-all `[[...slug]]` | ✅ | Both routers |
279
+ | Route groups `(group)` | ✅ | URL-transparent, layouts still apply |
280
+ | Parallel routes `@slot` | ✅ | Discovery, layout props, `default.tsx`, inherited slots |
281
+ | Intercepting routes | ✅ | `(.)`, `(..)`, `(..)(..)`, `(...)` conventions |
282
+ | Route handlers (`route.ts`) | ✅ | Named HTTP methods, auto OPTIONS/HEAD, cookie attachment |
283
+ | Middleware | ✅ | `middleware.ts` and `proxy.ts` (Next.js 16). Matcher patterns (string, array, regex, `:param`, `:path*`, `:path+`) |
284
+ | i18n routing | 🟡 | Pages Router locale prefix, Accept-Language detection, NEXT_LOCALE cookie. No domain-based routing |
285
+ | `basePath` | ✅ | Applied everywhere — URLs, Link, Router, navigation hooks |
286
+ | `trailingSlash` | ✅ | 308 redirects to canonical form |
287
+
288
+ ### Server features
289
+
290
+ | Feature | | Notes |
291
+ |---------|---|-------|
292
+ | SSR (Pages Router) | ✅ | Streaming, `_app`/`_document`, `__NEXT_DATA__`, hydration |
293
+ | SSR (App Router) | ✅ | RSC pipeline, nested layouts, streaming, nav context for client components |
294
+ | `getStaticProps` | ✅ | Props, redirect, notFound, revalidate |
295
+ | `getStaticPaths` | ✅ | `fallback: false`, `true`, `"blocking"` |
296
+ | `getServerSideProps` | ✅ | Full context including locale |
297
+ | ISR | ✅ | Stale-while-revalidate, pluggable `CacheHandler`, background regeneration |
298
+ | Server Actions (`"use server"`) | ✅ | Action execution, FormData, re-render after mutation, `redirect()` in actions |
299
+ | React Server Components | ✅ | Via `@vitejs/plugin-rsc`. `"use client"` boundaries work correctly |
300
+ | Streaming SSR | ✅ | Both routers |
301
+ | Metadata API | ✅ | `metadata`, `generateMetadata`, `viewport`, `generateViewport`, title templates |
302
+ | `generateStaticParams` | ✅ | With `dynamicParams` enforcement |
303
+ | Metadata file routes | ✅ | sitemap.xml, robots.txt, manifest, favicon, OG images (static + dynamic) |
304
+ | Static export (`output: 'export'`) | ✅ | Generates static HTML/JSON for all routes |
305
+ | `connection()` | ✅ | Forces dynamic rendering |
306
+ | `"use cache"` directive | ✅ | File-level and function-level. `cacheLife()` profiles, `cacheTag()`, stale-while-revalidate |
307
+ | `instrumentation.ts` | ✅ | `register()` and `onRequestError()` callbacks |
308
+ | Route segment config | 🟡 | `revalidate`, `dynamic`, `dynamicParams`. `runtime` and `preferredRegion` are ignored |
309
+
310
+ ### Configuration
311
+
312
+ | Feature | | Notes |
313
+ |---------|---|-------|
314
+ | `next.config.js` / `.ts` / `.mjs` | ✅ | Function configs, phase argument |
315
+ | `rewrites` / `redirects` / `headers` | ✅ | All phases, param interpolation |
316
+ | Environment variables (`NEXT_PUBLIC_*`) | ✅ | Inlined at build time via Vite |
317
+ | `images` config | 🟡 | Parsed but not used for optimization |
318
+
319
+ ### Caching
320
+
321
+ The cache is pluggable. The default `MemoryCacheHandler` works out of the box. Swap in your own backend for production:
322
+
323
+ ```ts
324
+ import { setCacheHandler } from "next/cache";
325
+ setCacheHandler(new MyCacheHandler()); // Redis, DynamoDB, etc.
326
+ ```
327
+
328
+ The `CacheHandler` interface matches Next.js 16's shape, so community adapters should be compatible.
329
+
330
+ ## What's NOT supported (and won't be)
331
+
332
+ These are intentional exclusions:
333
+
334
+ - **Vercel-specific features** — `@vercel/og` edge runtime, Vercel Analytics integration, Vercel KV/Blob/Postgres bindings. Use platform equivalents.
335
+ - **AMP** — Deprecated since Next.js 13. `useAmp()` returns `false`.
336
+ - **`next export` (legacy)** — Use `output: 'export'` in config instead.
337
+ - **Turbopack/webpack configuration** — This runs on Vite. Use Vite plugins instead of webpack loaders/plugins.
338
+ - **`next/jest`** — Use Vitest.
339
+ - **`create-next-app` scaffolding** — Not a goal.
340
+ - **Bug-for-bug parity with undocumented behavior** — If it's not in the Next.js docs, we probably don't replicate it.
341
+
342
+ ## Known limitations
343
+
344
+ - **Image optimization doesn't happen at build time.** Remote images work via `@unpic/react` (auto-detects 28 CDN providers). Local images are routed through a `/_vinext/image` endpoint that can resize and transcode on Cloudflare Workers (via the Images binding) in production, but no build-time optimization or static resizing occurs.
345
+ - **Google Fonts are loaded from the CDN, not self-hosted.** No `size-adjust` fallback font metrics. Local fonts work but `@font-face` CSS is injected at runtime, not extracted at build time.
346
+ - **`useSelectedLayoutSegment(s)`** derives segments from the pathname rather than being truly layout-aware. May differ from Next.js in edge cases with parallel routes.
347
+ - **Route segment config** — `runtime` and `preferredRegion` are ignored (everything runs in the same environment).
348
+ - **Node.js production server (`vinext start`)** works for testing but is less complete than Workers deployment. Cloudflare Workers is the primary target.
349
+ - **Native Node modules (sharp, resvg, satori, lightningcss, @napi-rs/canvas)** crash Vite's RSC dev environment. Dynamic OG image/icon routes using these work in production builds but not in dev mode. These are auto-stubbed during `vinext deploy`.
350
+
351
+ ## Benchmarks
352
+
353
+ > **Caveat:** Benchmarks are hard to get right and these are early results. Take them as directional, not definitive.
354
+
355
+ These benchmarks measure **compilation and bundling speed**, not production serving performance. Next.js and vinext have fundamentally different default approaches: Next.js statically pre-renders pages at build time (making builds slower but production serving faster for static content), while vinext server-renders all pages on each request. To make the comparison apples-to-apples, the benchmark app uses `export const dynamic = "force-dynamic"` to disable Next.js static pre-rendering — both frameworks are doing the same work: compiling, bundling, and preparing server-rendered routes.
356
+
357
+ The benchmark app is a shared 33-route App Router application (server components, client components, dynamic routes, nested layouts, API routes) built identically by both tools. We compare Next.js 16 (Turbopack) against vinext on both Vite 7 (Rollup) and Vite 8 (Rolldown). Turbopack and Rolldown both parallelize across cores, so results on machines with more cores may differ significantly.
358
+
359
+ We measure three things:
360
+
361
+ - **Production build time** — 5 runs, timed with `hyperfine`.
362
+ - **Client bundle size** — gzipped output of each build.
363
+ - **Dev server cold start** — 10 runs, randomized execution order. Vite's dependency optimizer cache is cleared before each run.
364
+
365
+ Benchmarks run on GitHub CI runners (2-core Ubuntu) on every merge to `main`. See the launch numbers in the [announcement blog post](https://blog.cloudflare.com/vinext/) and the latest results at **[benchmarks.vinext.workers.dev](https://benchmarks.vinext.workers.dev)**.
366
+
367
+ <details>
368
+ <summary>Why the bundle size difference?</summary>
369
+
370
+ Analysis of the build output shows two main factors:
371
+
372
+ 1. **Tree-shaking**: Vite/Rollup produces a smaller React+ReactDOM bundle than Next.js/Turbopack. Rollup's more aggressive dead-code elimination accounts for roughly half the overall difference.
373
+ 2. **Framework overhead**: Next.js ships more client-side infrastructure (router, Turbopack runtime loader, prefetching, error handling) than vinext's lighter client runtime.
374
+
375
+ Both frameworks ship the same app code and the same RSC client runtime (`react-server-dom-webpack`). The difference is in how much of React's internals survive tree-shaking and how much framework plumbing each tool adds.
376
+
377
+ </details>
378
+
379
+ Reproduce with `node benchmarks/run.mjs --runs=5 --dev-runs=10`. Exact framework versions are recorded in each result.
380
+
381
+ ## Architecture
382
+
383
+ vinext is a Vite plugin that:
384
+
385
+ 1. **Resolves all `next/*` imports** to local shim modules that reimplement the Next.js API using standard Web APIs and React primitives.
386
+ 2. **Scans your `pages/` and `app/` directories** to build a file-system router matching Next.js conventions.
387
+ 3. **Generates virtual entry modules** for the RSC, SSR, and browser environments that handle request routing, component rendering, and client hydration.
388
+ 4. **Integrates with `@vitejs/plugin-rsc`** for React Server Components — handling `"use client"` / `"use server"` directives, RSC stream serialization, and multi-environment builds.
389
+
390
+ The result is a standard Vite application that happens to be API-compatible with Next.js.
391
+
392
+ ### Pages Router flow
393
+
394
+ ```
395
+ Request → Vite dev server middleware → Route match → getServerSideProps/getStaticProps
396
+ → renderToReadableStream(App + Page) → HTML with __NEXT_DATA__ → Client hydration
397
+ ```
398
+
399
+ ### App Router flow
400
+
401
+ ```
402
+ Request → RSC entry (Vite rsc environment) → Route match → Build layout/page tree
403
+ → renderToReadableStream (RSC payload) → SSR entry (Vite ssr environment)
404
+ → renderToReadableStream (HTML) → Client hydration from RSC stream
405
+ ```
406
+
407
+ ## Project structure
408
+
409
+ ```
410
+ packages/vinext/
411
+ src/
412
+ index.ts # Main plugin — resolve aliases, config, virtual modules
413
+ cli.ts # vinext CLI (dev/build/start/deploy/init/check/lint)
414
+ check.ts # Compatibility scanner
415
+ deploy.ts # Cloudflare Workers deployment
416
+ init.ts # vinext init — one-command migration for Next.js apps
417
+ client/
418
+ entry.ts # Client-side hydration entry
419
+ routing/
420
+ pages-router.ts # Pages Router file-system scanner
421
+ app-router.ts # App Router file-system scanner
422
+ server/
423
+ dev-server.ts # Pages Router SSR request handler
424
+ app-dev-server.ts # App Router RSC entry generator
425
+ prod-server.ts # Production server with compression
426
+ api-handler.ts # Pages Router API routes
427
+ isr-cache.ts # ISR cache layer
428
+ middleware.ts # middleware.ts / proxy.ts runner
429
+ metadata-routes.ts # File-based metadata route scanner
430
+ instrumentation.ts # instrumentation.ts support
431
+ cloudflare/
432
+ kv-cache-handler.ts # Cloudflare KV-backed CacheHandler for ISR
433
+ shims/ # One file per next/* module (33 shims + 6 internal)
434
+ build/
435
+ static-export.ts # output: 'export' support
436
+ utils/
437
+ project.ts # Shared project utilities (ESM, CJS, package manager detection)
438
+ config/
439
+ next-config.ts # next.config.js loader
440
+ config-matchers.ts # Config matching utilities
441
+
442
+ tests/
443
+ *.test.ts # Vitest unit + integration tests
444
+ nextjs-compat/ # Tests ported from Next.js test suite
445
+ fixtures/ # Test apps (pages-basic, app-basic, ecosystem libs)
446
+ e2e/ # Playwright E2E tests (5 projects)
447
+
448
+ examples/ # Deployed demo apps (see Live Examples above)
449
+ ```
450
+
451
+ ## Tests
452
+
453
+ ```bash
454
+ pnpm test # Vitest unit + integration tests
455
+ pnpm run test:e2e # Playwright E2E tests (5 projects)
456
+ pnpm run typecheck # TypeScript checking (tsgo)
457
+ pnpm run lint # Linting (oxlint)
458
+ ```
459
+
460
+ E2E tests cover Pages Router (dev + production), App Router (dev), and both routers on Cloudflare Workers via `wrangler dev`.
461
+
462
+ The [Vercel App Router Playground](https://github.com/vercel/next-app-router-playground) runs on vinext as an integration test — see it live at [app-router-playground.vinext.workers.dev](https://app-router-playground.vinext.workers.dev).
463
+
464
+ ## Local setup (from source)
465
+
466
+ If you're working from the repo instead of installing from npm:
467
+
468
+ ```bash
469
+ git clone https://github.com/cloudflare/vinext.git
470
+ cd vinext
471
+ pnpm install
472
+ pnpm run build
473
+ ```
474
+
475
+ This compiles the vinext package to `packages/vinext/dist/`. For active development, use `pnpm --filter vinext run dev` to run `tsc --watch`.
476
+
477
+ To use it against an external Next.js app, link the built package:
478
+
479
+ ```bash
480
+ # From your Next.js project directory:
481
+ pnpm link /path/to/vinext/packages/vinext
482
+ ```
483
+
484
+ Or add it to your `package.json` as a file dependency:
485
+
486
+ ```json
487
+ {
488
+ "dependencies": {
489
+ "vinext": "file:/path/to/vinext/packages/vinext"
490
+ }
491
+ }
492
+ ```
493
+
494
+ vinext has peer dependencies on `react ^19.2.4`, `react-dom ^19.2.4`, and `vite ^7.0.0`. Then replace `next` with `vinext` in your scripts and run as normal.
495
+
496
+ ## Contributing
497
+
498
+ This project is experimental and under active development. Issues and PRs are welcome.
499
+
500
+ ### Reporting bugs
501
+
502
+ If something doesn't work with your Next.js app, please file an issue — we want to hear about it.
503
+
504
+ Before you do, try pointing an AI agent at the problem. Open your project with Claude Code, Cursor, OpenCode, or whatever you use, and ask it to figure out why your app isn't working with vinext. In our experience, agents are very good at tracing through the vinext source, identifying the gap or bug, and often producing a fix or at least a clear diagnosis. An issue that includes "here's what the agent found" is significantly more actionable than "it doesn't work."
505
+
506
+ Even a partial diagnosis helps — stack traces, which `next/*` import is involved, whether it's a dev or production build issue, App Router vs Pages Router. The more context, the faster we can fix it.
507
+
508
+ ## License
509
+
510
+ MIT
package/dist/check.d.ts CHANGED
@@ -47,6 +47,8 @@ export declare function runCheck(root: string): CheckResult;
47
47
  /**
48
48
  * Format the check result as a colored terminal report.
49
49
  */
50
- export declare function formatReport(result: CheckResult): string;
50
+ export declare function formatReport(result: CheckResult, opts?: {
51
+ calledFromInit?: boolean;
52
+ }): string;
51
53
  export {};
52
54
  //# sourceMappingURL=check.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../src/check.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH,KAAK,MAAM,GAAG,WAAW,GAAG,SAAS,GAAG,aAAa,CAAC;AAEtD,UAAU,SAAS;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,SAAS,EAAE,CAAC;IACrB,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,SAAS,EAAE,SAAS,EAAE,CAAC;IACvB,WAAW,EAAE,SAAS,EAAE,CAAC;IACzB,OAAO,EAAE;QACP,SAAS,EAAE,MAAM,CAAC;QAClB,OAAO,EAAE,MAAM,CAAC;QAChB,WAAW,EAAE,MAAM,CAAC;QACpB,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;CACH;AAoGD;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,CAyDrD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,CA4DvD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,CAyBxD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,CAkI1D;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAqBlD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CA8FxD"}
1
+ {"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../src/check.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH,KAAK,MAAM,GAAG,WAAW,GAAG,SAAS,GAAG,aAAa,CAAC;AAEtD,UAAU,SAAS;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,SAAS,EAAE,CAAC;IACrB,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,SAAS,EAAE,SAAS,EAAE,CAAC;IACvB,WAAW,EAAE,SAAS,EAAE,CAAC;IACzB,OAAO,EAAE;QACP,SAAS,EAAE,MAAM,CAAC;QAClB,OAAO,EAAE,MAAM,CAAC;QAChB,WAAW,EAAE,MAAM,CAAC;QACpB,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;CACH;AAoGD;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,CAyDrD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,CA4DvD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,CAyBxD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,CAkI1D;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAqBlD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,CAAC,EAAE;IAAE,cAAc,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,MAAM,CAgG7F"}
package/dist/check.js CHANGED
@@ -321,7 +321,7 @@ export function checkConventions(root) {
321
321
  items.push({
322
322
  name: 'Missing "type": "module" in package.json',
323
323
  status: "unsupported",
324
- detail: "required for Vite — run `vinext init` to add it automatically",
324
+ detail: "required for Vite — vinext init will add it automatically",
325
325
  });
326
326
  }
327
327
  }
@@ -395,7 +395,7 @@ export function runCheck(root) {
395
395
  /**
396
396
  * Format the check result as a colored terminal report.
397
397
  */
398
- export function formatReport(result) {
398
+ export function formatReport(result, opts) {
399
399
  const lines = [];
400
400
  const statusIcon = (s) => s === "supported" ? "\x1b[32m✓\x1b[0m" : s === "partial" ? "\x1b[33m~\x1b[0m" : "\x1b[31m✗\x1b[0m";
401
401
  lines.push("");
@@ -467,16 +467,18 @@ export function formatReport(result) {
467
467
  }
468
468
  }
469
469
  }
470
- // Actionable next steps
471
- lines.push("");
472
- lines.push(" \x1b[1mRecommended next steps:\x1b[0m");
473
- lines.push(` Run \x1b[36mvinext init\x1b[0m to set up your project automatically`);
474
- lines.push("");
475
- lines.push(" Or manually:");
476
- lines.push(` 1. Add \x1b[36m"type": "module"\x1b[0m to package.json`);
477
- lines.push(` 2. Install: \x1b[36mnpm install -D vinext vite @vitejs/plugin-rsc\x1b[0m`);
478
- lines.push(` 3. Create vite.config.ts (see docs)`);
479
- lines.push(` 4. Run: \x1b[36mnpx vite dev\x1b[0m`);
470
+ // Actionable next steps (skip when called from init — it prints its own summary)
471
+ if (!opts?.calledFromInit) {
472
+ lines.push("");
473
+ lines.push(" \x1b[1mRecommended next steps:\x1b[0m");
474
+ lines.push(` Run \x1b[36mvinext init\x1b[0m to set up your project automatically`);
475
+ lines.push("");
476
+ lines.push(" Or manually:");
477
+ lines.push(` 1. Add \x1b[36m"type": "module"\x1b[0m to package.json`);
478
+ lines.push(` 2. Install: \x1b[36mnpm install -D vinext vite @vitejs/plugin-rsc\x1b[0m`);
479
+ lines.push(` 3. Create vite.config.ts (see docs)`);
480
+ lines.push(` 4. Run: \x1b[36mnpx vite dev\x1b[0m`);
481
+ }
480
482
  lines.push("");
481
483
  return lines.join("\n");
482
484
  }
package/dist/check.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"check.js","sourceRoot":"","sources":["../src/check.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * vinext check — compatibility scanner for Next.js apps\n *\n * Scans an existing Next.js app and produces a compatibility report\n * showing what will work, what needs changes, and an overall score.\n */\n\nimport fs from \"node:fs\";\nimport path from \"node:path\";\n\n// ── Support status definitions ─────────────────────────────────────────────\n\ntype Status = \"supported\" | \"partial\" | \"unsupported\";\n\ninterface CheckItem {\n name: string;\n status: Status;\n detail?: string;\n files?: string[];\n}\n\nexport interface CheckResult {\n imports: CheckItem[];\n config: CheckItem[];\n libraries: CheckItem[];\n conventions: CheckItem[];\n summary: {\n supported: number;\n partial: number;\n unsupported: number;\n total: number;\n score: number;\n };\n}\n\n// ── Import support map ─────────────────────────────────────────────────────\n\nconst IMPORT_SUPPORT: Record<string, { status: Status; detail?: string }> = {\n \"next\": { status: \"supported\", detail: \"type-only exports (Metadata, NextPage, etc.)\" },\n \"next/link\": { status: \"supported\" },\n \"next/image\": { status: \"supported\", detail: \"uses @unpic/react (no local optimization yet)\" },\n \"next/router\": { status: \"supported\" },\n \"next/navigation\": { status: \"supported\" },\n \"next/headers\": { status: \"supported\" },\n \"next/server\": { status: \"supported\", detail: \"NextRequest/NextResponse shimmed\" },\n \"next/cache\": { status: \"supported\", detail: \"revalidateTag, revalidatePath, unstable_cache, cacheLife, cacheTag\" },\n \"next/dynamic\": { status: \"supported\" },\n \"next/head\": { status: \"supported\" },\n \"next/script\": { status: \"supported\" },\n \"next/font/google\": { status: \"partial\", detail: \"fonts loaded from CDN, not self-hosted at build time\" },\n \"next/font/local\": { status: \"partial\", detail: \"font.className works but font.variable mode broken (CSS variable not set) — fonts fall back to system sans-serif\" },\n \"next/og\": { status: \"supported\", detail: \"ImageResponse via @vercel/og\" },\n \"next/config\": { status: \"supported\" },\n \"next/amp\": { status: \"unsupported\", detail: \"AMP is not supported\" },\n \"next/document\": { status: \"supported\", detail: \"custom _document.tsx\" },\n \"next/app\": { status: \"supported\", detail: \"custom _app.tsx\" },\n \"next/error\": { status: \"supported\" },\n \"next/third-parties/google\": { status: \"unsupported\", detail: \"third-party script optimization not implemented\" },\n \"server-only\": { status: \"supported\" },\n \"client-only\": { status: \"supported\" },\n};\n\n// ── Config support map ─────────────────────────────────────────────────────\n\nconst CONFIG_SUPPORT: Record<string, { status: Status; detail?: string }> = {\n basePath: { status: \"supported\" },\n trailingSlash: { status: \"supported\" },\n redirects: { status: \"supported\" },\n rewrites: { status: \"supported\" },\n headers: { status: \"supported\" },\n i18n: { status: \"supported\", detail: \"path-prefix routing (domains not yet supported)\" },\n env: { status: \"supported\" },\n images: { status: \"partial\", detail: \"remotePatterns validated, no local optimization\" },\n output: { status: \"supported\", detail: \"'export' and 'standalone' modes\" },\n transpilePackages: { status: \"supported\", detail: \"Vite handles this natively\" },\n webpack: { status: \"unsupported\", detail: \"Vite replaces webpack — custom webpack configs need migration\" },\n \"experimental.ppr\": { status: \"unsupported\", detail: \"partial prerendering not yet implemented\" },\n \"experimental.typedRoutes\": { status: \"unsupported\", detail: \"typed routes not implemented\" },\n \"experimental.serverActions\": { status: \"supported\", detail: \"server actions via 'use server' directive\" },\n \"i18n.domains\": { status: \"unsupported\", detail: \"domain-based i18n routing not implemented\" },\n reactStrictMode: { status: \"supported\", detail: \"always enabled\" },\n poweredByHeader: { status: \"supported\", detail: \"not sent (matching Next.js default when disabled)\" },\n};\n\n// ── Library support map ────────────────────────────────────────────────────\n\nconst LIBRARY_SUPPORT: Record<string, { status: Status; detail?: string }> = {\n \"next-themes\": { status: \"supported\" },\n nuqs: { status: \"supported\" },\n \"next-view-transitions\": { status: \"supported\" },\n \"@vercel/analytics\": { status: \"supported\", detail: \"analytics script injected client-side\" },\n \"next-intl\": { status: \"partial\", detail: \"works with middleware-based setup, some server component features may differ\" },\n \"@clerk/nextjs\": { status: \"unsupported\", detail: \"deep Next.js middleware integration not compatible\" },\n \"@auth/nextjs\": { status: \"unsupported\", detail: \"relies on Next.js internal auth handlers; consider migrating to better-auth\" },\n \"next-auth\": { status: \"unsupported\", detail: \"relies on Next.js API route internals; consider migrating to better-auth (see https://authjs.dev/getting-started/migrate-to-better-auth)\" },\n \"better-auth\": { status: \"supported\", detail: \"uses only public next/* APIs (headers, cookies, NextRequest/NextResponse)\" },\n \"@sentry/nextjs\": { status: \"partial\", detail: \"client-side works, server integration needs manual setup\" },\n \"@t3-oss/env-nextjs\": { status: \"supported\" },\n \"tailwindcss\": { status: \"supported\" },\n \"styled-components\": { status: \"partial\", detail: \"needs useServerInsertedHTML (not yet implemented)\" },\n \"@emotion/react\": { status: \"partial\", detail: \"needs useServerInsertedHTML (not yet implemented)\" },\n \"lucide-react\": { status: \"supported\" },\n \"framer-motion\": { status: \"supported\" },\n \"@radix-ui/react-dialog\": { status: \"supported\" },\n \"shadcn-ui\": { status: \"supported\" },\n zod: { status: \"supported\" },\n \"react-hook-form\": { status: \"supported\" },\n prisma: { status: \"supported\", detail: \"works on Cloudflare Workers with Prisma Accelerate\" },\n drizzle: { status: \"supported\", detail: \"works with D1 on Cloudflare Workers\" },\n};\n\n// ── Scanning functions ─────────────────────────────────────────────────────\n\n/**\n * Recursively find all source files in a directory.\n */\nfunction findSourceFiles(dir: string, extensions = [\".ts\", \".tsx\", \".js\", \".jsx\", \".mjs\"]): string[] {\n const results: string[] = [];\n if (!fs.existsSync(dir)) return results;\n\n const entries = fs.readdirSync(dir, { withFileTypes: true });\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n if (entry.isDirectory()) {\n if (entry.name === \"node_modules\" || entry.name === \".next\" || entry.name === \"dist\" || entry.name === \".git\") continue;\n results.push(...findSourceFiles(fullPath, extensions));\n } else if (extensions.some(ext => entry.name.endsWith(ext))) {\n results.push(fullPath);\n }\n }\n return results;\n}\n\n/**\n * Scan source files for `import ... from 'next/...'` statements.\n */\nexport function scanImports(root: string): CheckItem[] {\n const files = findSourceFiles(root);\n const importUsage = new Map<string, string[]>();\n\n const importRegex = /(?:import\\s+(?:[\\w{},\\s*]+\\s+from\\s+)?|require\\s*\\()['\"]([^'\"]+)['\"]\\)?/g;\n // Skip `import type` and `import { type ... }` — they're erased at compile time\n const typeOnlyImportRegex = /import\\s+type\\s+/;\n\n for (const file of files) {\n const content = fs.readFileSync(file, \"utf-8\");\n let match;\n while ((match = importRegex.exec(content)) !== null) {\n const mod = match[1];\n // Skip type-only imports (no runtime effect)\n const lineStart = content.lastIndexOf(\"\\n\", match.index) + 1;\n const line = content.slice(lineStart, match.index + match[0].length);\n if (typeOnlyImportRegex.test(line)) continue;\n // Only track next/* imports and server-only/client-only\n if (mod.startsWith(\"next/\") || mod === \"next\" || mod === \"server-only\" || mod === \"client-only\") {\n // Normalize: next/font/google -> next/font/google\n const normalized = mod === \"next\" ? \"next\" : mod;\n if (!importUsage.has(normalized)) importUsage.set(normalized, []);\n const relFile = path.relative(root, file);\n if (!importUsage.get(normalized)!.includes(relFile)) {\n importUsage.get(normalized)!.push(relFile);\n }\n }\n }\n }\n\n const items: CheckItem[] = [];\n for (const [mod, usedFiles] of importUsage) {\n const support = IMPORT_SUPPORT[mod];\n if (support) {\n items.push({\n name: mod,\n status: support.status,\n detail: support.detail,\n files: usedFiles,\n });\n } else {\n items.push({\n name: mod,\n status: \"unsupported\",\n detail: \"not recognized by vinext\",\n files: usedFiles,\n });\n }\n }\n\n // Sort: unsupported first, then partial, then supported\n items.sort((a, b) => {\n const order: Record<Status, number> = { unsupported: 0, partial: 1, supported: 2 };\n return order[a.status] - order[b.status];\n });\n\n return items;\n}\n\n/**\n * Analyze next.config.js/mjs/ts for supported and unsupported options.\n */\nexport function analyzeConfig(root: string): CheckItem[] {\n const configFiles = [\"next.config.ts\", \"next.config.mjs\", \"next.config.js\", \"next.config.cjs\"];\n let configPath: string | null = null;\n for (const f of configFiles) {\n const p = path.join(root, f);\n if (fs.existsSync(p)) { configPath = p; break; }\n }\n\n if (!configPath) {\n return [{ name: \"next.config\", status: \"supported\", detail: \"no config file found (defaults are fine)\" }];\n }\n\n const content = fs.readFileSync(configPath, \"utf-8\");\n const items: CheckItem[] = [];\n\n // Check for known config options by searching for property names in the config file\n const configOptions = [\n \"basePath\", \"trailingSlash\", \"redirects\", \"rewrites\", \"headers\",\n \"i18n\", \"env\", \"images\", \"output\", \"transpilePackages\", \"webpack\",\n \"reactStrictMode\", \"poweredByHeader\",\n ];\n\n for (const opt of configOptions) {\n // Simple heuristic: check if the option name appears as a property in the config\n const regex = new RegExp(`\\\\b${opt}\\\\b`);\n if (regex.test(content)) {\n const support = CONFIG_SUPPORT[opt];\n if (support) {\n items.push({ name: opt, status: support.status, detail: support.detail });\n } else {\n items.push({ name: opt, status: \"unsupported\", detail: \"not recognized\" });\n }\n }\n }\n\n // Check for experimental options\n if (/experimental\\s*[:=]\\s*\\{/.test(content)) {\n if (/\\bppr\\b/.test(content)) {\n items.push({ name: \"experimental.ppr\", ...CONFIG_SUPPORT[\"experimental.ppr\"]! });\n }\n if (/\\btypedRoutes\\b/.test(content)) {\n items.push({ name: \"experimental.typedRoutes\", ...CONFIG_SUPPORT[\"experimental.typedRoutes\"]! });\n }\n if (/\\bserverActions\\b/.test(content)) {\n items.push({ name: \"experimental.serverActions\", ...CONFIG_SUPPORT[\"experimental.serverActions\"]! });\n }\n }\n\n // Check for i18n.domains\n if (/domains\\s*:/.test(content) && /i18n/.test(content)) {\n items.push({ name: \"i18n.domains\", ...CONFIG_SUPPORT[\"i18n.domains\"]! });\n }\n\n // Sort: unsupported first\n items.sort((a, b) => {\n const order: Record<Status, number> = { unsupported: 0, partial: 1, supported: 2 };\n return order[a.status] - order[b.status];\n });\n\n return items;\n}\n\n/**\n * Check package.json dependencies for known libraries.\n */\nexport function checkLibraries(root: string): CheckItem[] {\n const pkgPath = path.join(root, \"package.json\");\n if (!fs.existsSync(pkgPath)) return [];\n\n const pkg = JSON.parse(fs.readFileSync(pkgPath, \"utf-8\"));\n const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };\n const items: CheckItem[] = [];\n\n for (const [lib, support] of Object.entries(LIBRARY_SUPPORT)) {\n if (allDeps[lib]) {\n items.push({\n name: lib,\n status: support.status,\n detail: support.detail,\n });\n }\n }\n\n // Sort: unsupported first\n items.sort((a, b) => {\n const order: Record<Status, number> = { unsupported: 0, partial: 1, supported: 2 };\n return order[a.status] - order[b.status];\n });\n\n return items;\n}\n\n/**\n * Check file conventions (pages, app directory, middleware, etc.)\n */\nexport function checkConventions(root: string): CheckItem[] {\n const items: CheckItem[] = [];\n\n // Check for pages/ and app/ at root level, then fall back to src/\n const pagesDir = fs.existsSync(path.join(root, \"pages\"))\n ? path.join(root, \"pages\")\n : fs.existsSync(path.join(root, \"src\", \"pages\"))\n ? path.join(root, \"src\", \"pages\")\n : null;\n const appDirPath = fs.existsSync(path.join(root, \"app\"))\n ? path.join(root, \"app\")\n : fs.existsSync(path.join(root, \"src\", \"app\"))\n ? path.join(root, \"src\", \"app\")\n : null;\n\n const hasPages = pagesDir !== null;\n const hasApp = appDirPath !== null;\n const hasProxy = fs.existsSync(path.join(root, \"proxy.ts\")) || fs.existsSync(path.join(root, \"proxy.js\"));\n const hasMiddleware = fs.existsSync(path.join(root, \"middleware.ts\")) || fs.existsSync(path.join(root, \"middleware.js\"));\n\n if (hasPages) {\n const isSrc = pagesDir!.includes(path.join(\"src\", \"pages\"));\n items.push({ name: isSrc ? \"Pages Router (src/pages/)\" : \"Pages Router (pages/)\", status: \"supported\" });\n\n // Count pages\n const pageFiles = findSourceFiles(pagesDir!);\n const pages = pageFiles.filter(f => !f.includes(\"/api/\") && !f.includes(\"_app\") && !f.includes(\"_document\") && !f.includes(\"_error\"));\n const apiRoutes = pageFiles.filter(f => f.includes(\"/api/\"));\n items.push({ name: `${pages.length} page(s)`, status: \"supported\" });\n if (apiRoutes.length) {\n items.push({ name: `${apiRoutes.length} API route(s)`, status: \"supported\" });\n }\n\n // Check for _app, _document\n if (pageFiles.some(f => f.includes(\"_app\"))) {\n items.push({ name: \"Custom _app\", status: \"supported\" });\n }\n if (pageFiles.some(f => f.includes(\"_document\"))) {\n items.push({ name: \"Custom _document\", status: \"supported\" });\n }\n }\n\n if (hasApp) {\n const isSrc = appDirPath!.includes(path.join(\"src\", \"app\"));\n items.push({ name: isSrc ? \"App Router (src/app/)\" : \"App Router (app/)\", status: \"supported\" });\n\n const appFiles = findSourceFiles(appDirPath!);\n const pages = appFiles.filter(f => f.endsWith(\"page.tsx\") || f.endsWith(\"page.jsx\") || f.endsWith(\"page.ts\") || f.endsWith(\"page.js\"));\n const layouts = appFiles.filter(f => f.endsWith(\"layout.tsx\") || f.endsWith(\"layout.jsx\") || f.endsWith(\"layout.ts\") || f.endsWith(\"layout.js\"));\n const routes = appFiles.filter(f => f.endsWith(\"route.tsx\") || f.endsWith(\"route.ts\") || f.endsWith(\"route.js\"));\n const loadings = appFiles.filter(f => f.endsWith(\"loading.tsx\") || f.endsWith(\"loading.jsx\"));\n const errors = appFiles.filter(f => f.endsWith(\"error.tsx\") || f.endsWith(\"error.jsx\"));\n const notFounds = appFiles.filter(f => f.endsWith(\"not-found.tsx\") || f.endsWith(\"not-found.jsx\"));\n\n items.push({ name: `${pages.length} page(s)`, status: \"supported\" });\n if (layouts.length) items.push({ name: `${layouts.length} layout(s)`, status: \"supported\" });\n if (routes.length) items.push({ name: `${routes.length} route handler(s)`, status: \"supported\" });\n if (loadings.length) items.push({ name: `${loadings.length} loading boundary(ies)`, status: \"supported\" });\n if (errors.length) items.push({ name: `${errors.length} error boundary(ies)`, status: \"supported\" });\n if (notFounds.length) items.push({ name: `${notFounds.length} not-found page(s)`, status: \"supported\" });\n }\n\n if (hasProxy) {\n items.push({ name: \"proxy.ts (Next.js 16)\", status: \"supported\" });\n } else if (hasMiddleware) {\n items.push({ name: \"middleware.ts (deprecated in Next.js 16)\", status: \"supported\" });\n }\n\n if (!hasPages && !hasApp) {\n items.push({ name: \"No pages/ or app/ directory found\", status: \"unsupported\", detail: \"vinext requires a pages/ or app/ directory\" });\n }\n\n // Check for \"type\": \"module\" in package.json\n const pkgPath = path.join(root, \"package.json\");\n if (fs.existsSync(pkgPath)) {\n const pkg = JSON.parse(fs.readFileSync(pkgPath, \"utf-8\"));\n if (pkg.type !== \"module\") {\n items.push({\n name: 'Missing \"type\": \"module\" in package.json',\n status: \"unsupported\",\n detail: \"required for Vite — run `vinext init` to add it automatically\",\n });\n }\n }\n\n // Scan for ViewTransition import from react\n const allSourceFiles = findSourceFiles(root);\n const viewTransitionRegex = /import\\s+\\{[^}]*\\bViewTransition\\b[^}]*\\}\\s+from\\s+['\"]react['\"]/;\n const viewTransitionFiles: string[] = [];\n for (const file of allSourceFiles) {\n const content = fs.readFileSync(file, \"utf-8\");\n if (viewTransitionRegex.test(content)) {\n viewTransitionFiles.push(path.relative(root, file));\n }\n }\n if (viewTransitionFiles.length > 0) {\n items.push({\n name: \"ViewTransition (React canary API)\",\n status: \"partial\",\n detail: \"vinext auto-shims with a passthrough fallback, view transitions won't animate\",\n files: viewTransitionFiles,\n });\n }\n\n // Check PostCSS config for string-form plugins\n const postcssConfigs = [\"postcss.config.mjs\", \"postcss.config.js\", \"postcss.config.cjs\"];\n for (const configFile of postcssConfigs) {\n const configPath = path.join(root, configFile);\n if (fs.existsSync(configPath)) {\n const content = fs.readFileSync(configPath, \"utf-8\");\n // Detect string-form plugins: plugins: [\"...\"] or plugins: ['...']\n const stringPluginRegex = /plugins\\s*:\\s*\\[[\\s\\S]*?(['\"][^'\"]+['\"])[\\s\\S]*?\\]/;\n const match = stringPluginRegex.exec(content);\n if (match) {\n // Check it's not require() or import() form — just bare string literals in the array\n const pluginsBlock = match[0];\n // If plugins array contains string literals not wrapped in require()\n if (/plugins\\s*:\\s*\\[[\\s\\n]*['\"]/.test(pluginsBlock)) {\n items.push({\n name: `PostCSS string-form plugins (${configFile})`,\n status: \"partial\",\n detail: \"string-form PostCSS plugins need resolution — vinext handles this automatically\",\n });\n }\n }\n break; // Only check the first config file found\n }\n }\n\n return items;\n}\n\n/**\n * Run the full compatibility check.\n */\nexport function runCheck(root: string): CheckResult {\n const imports = scanImports(root);\n const config = analyzeConfig(root);\n const libraries = checkLibraries(root);\n const conventions = checkConventions(root);\n\n const allItems = [...imports, ...config, ...libraries, ...conventions];\n const supported = allItems.filter(i => i.status === \"supported\").length;\n const partial = allItems.filter(i => i.status === \"partial\").length;\n const unsupported = allItems.filter(i => i.status === \"unsupported\").length;\n const total = allItems.length;\n // Score: supported = 1, partial = 0.5, unsupported = 0\n const score = total > 0 ? Math.round(((supported + partial * 0.5) / total) * 100) : 100;\n\n return {\n imports,\n config,\n libraries,\n conventions,\n summary: { supported, partial, unsupported, total, score },\n };\n}\n\n/**\n * Format the check result as a colored terminal report.\n */\nexport function formatReport(result: CheckResult): string {\n const lines: string[] = [];\n const statusIcon = (s: Status) => s === \"supported\" ? \"\\x1b[32m✓\\x1b[0m\" : s === \"partial\" ? \"\\x1b[33m~\\x1b[0m\" : \"\\x1b[31m✗\\x1b[0m\";\n\n lines.push(\"\");\n lines.push(\" \\x1b[1mvinext compatibility report\\x1b[0m\");\n lines.push(\" \" + \"=\".repeat(40));\n lines.push(\"\");\n\n // Imports\n if (result.imports.length > 0) {\n const importSupported = result.imports.filter(i => i.status === \"supported\").length;\n lines.push(` \\x1b[1mImports\\x1b[0m: ${importSupported}/${result.imports.length} fully supported`);\n for (const item of result.imports) {\n const suffix = item.detail ? ` \\x1b[90m— ${item.detail}\\x1b[0m` : \"\";\n const fileCount = item.files ? ` \\x1b[90m(${item.files.length} file${item.files.length === 1 ? \"\" : \"s\"})\\x1b[0m` : \"\";\n lines.push(` ${statusIcon(item.status)} ${item.name}${fileCount}${suffix}`);\n }\n lines.push(\"\");\n }\n\n // Config\n if (result.config.length > 0) {\n const configSupported = result.config.filter(i => i.status === \"supported\").length;\n lines.push(` \\x1b[1mConfig\\x1b[0m: ${configSupported}/${result.config.length} options supported`);\n for (const item of result.config) {\n const suffix = item.detail ? ` \\x1b[90m— ${item.detail}\\x1b[0m` : \"\";\n lines.push(` ${statusIcon(item.status)} ${item.name}${suffix}`);\n }\n lines.push(\"\");\n }\n\n // Libraries\n if (result.libraries.length > 0) {\n const libSupported = result.libraries.filter(i => i.status === \"supported\").length;\n lines.push(` \\x1b[1mLibraries\\x1b[0m: ${libSupported}/${result.libraries.length} compatible`);\n for (const item of result.libraries) {\n const suffix = item.detail ? ` \\x1b[90m— ${item.detail}\\x1b[0m` : \"\";\n lines.push(` ${statusIcon(item.status)} ${item.name}${suffix}`);\n }\n lines.push(\"\");\n }\n\n // Conventions\n if (result.conventions.length > 0) {\n lines.push(` \\x1b[1mProject structure\\x1b[0m:`);\n for (const item of result.conventions) {\n const suffix = item.detail ? ` \\x1b[90m— ${item.detail}\\x1b[0m` : \"\";\n lines.push(` ${statusIcon(item.status)} ${item.name}${suffix}`);\n }\n lines.push(\"\");\n }\n\n // Summary\n const { score, supported, partial, unsupported } = result.summary;\n const scoreColor = score >= 90 ? \"\\x1b[32m\" : score >= 70 ? \"\\x1b[33m\" : \"\\x1b[31m\";\n lines.push(\" \" + \"-\".repeat(40));\n lines.push(` \\x1b[1mOverall\\x1b[0m: ${scoreColor}${score}% compatible\\x1b[0m (${supported} supported, ${partial} partial, ${unsupported} issues)`);\n\n if (unsupported > 0) {\n lines.push(\"\");\n lines.push(\" \\x1b[1mIssues to address:\\x1b[0m\");\n const allItems = [...result.imports, ...result.config, ...result.libraries, ...result.conventions];\n for (const item of allItems) {\n if (item.status === \"unsupported\") {\n lines.push(` \\x1b[31m✗\\x1b[0m ${item.name}${item.detail ? ` — ${item.detail}` : \"\"}`);\n }\n }\n }\n\n if (result.summary.partial > 0) {\n lines.push(\"\");\n lines.push(\" \\x1b[1mPartial support (may need attention):\\x1b[0m\");\n const allItems = [...result.imports, ...result.config, ...result.libraries, ...result.conventions];\n for (const item of allItems) {\n if (item.status === \"partial\") {\n lines.push(` \\x1b[33m~\\x1b[0m ${item.name}${item.detail ? ` — ${item.detail}` : \"\"}`);\n }\n }\n }\n\n // Actionable next steps\n lines.push(\"\");\n lines.push(\" \\x1b[1mRecommended next steps:\\x1b[0m\");\n lines.push(` Run \\x1b[36mvinext init\\x1b[0m to set up your project automatically`);\n lines.push(\"\");\n lines.push(\" Or manually:\");\n lines.push(` 1. Add \\x1b[36m\"type\": \"module\"\\x1b[0m to package.json`);\n lines.push(` 2. Install: \\x1b[36mnpm install -D vinext vite @vitejs/plugin-rsc\\x1b[0m`);\n lines.push(` 3. Create vite.config.ts (see docs)`);\n lines.push(` 4. Run: \\x1b[36mnpx vite dev\\x1b[0m`);\n\n lines.push(\"\");\n return lines.join(\"\\n\");\n}\n"]}
1
+ {"version":3,"file":"check.js","sourceRoot":"","sources":["../src/check.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * vinext check — compatibility scanner for Next.js apps\n *\n * Scans an existing Next.js app and produces a compatibility report\n * showing what will work, what needs changes, and an overall score.\n */\n\nimport fs from \"node:fs\";\nimport path from \"node:path\";\n\n// ── Support status definitions ─────────────────────────────────────────────\n\ntype Status = \"supported\" | \"partial\" | \"unsupported\";\n\ninterface CheckItem {\n name: string;\n status: Status;\n detail?: string;\n files?: string[];\n}\n\nexport interface CheckResult {\n imports: CheckItem[];\n config: CheckItem[];\n libraries: CheckItem[];\n conventions: CheckItem[];\n summary: {\n supported: number;\n partial: number;\n unsupported: number;\n total: number;\n score: number;\n };\n}\n\n// ── Import support map ─────────────────────────────────────────────────────\n\nconst IMPORT_SUPPORT: Record<string, { status: Status; detail?: string }> = {\n \"next\": { status: \"supported\", detail: \"type-only exports (Metadata, NextPage, etc.)\" },\n \"next/link\": { status: \"supported\" },\n \"next/image\": { status: \"supported\", detail: \"uses @unpic/react (no local optimization yet)\" },\n \"next/router\": { status: \"supported\" },\n \"next/navigation\": { status: \"supported\" },\n \"next/headers\": { status: \"supported\" },\n \"next/server\": { status: \"supported\", detail: \"NextRequest/NextResponse shimmed\" },\n \"next/cache\": { status: \"supported\", detail: \"revalidateTag, revalidatePath, unstable_cache, cacheLife, cacheTag\" },\n \"next/dynamic\": { status: \"supported\" },\n \"next/head\": { status: \"supported\" },\n \"next/script\": { status: \"supported\" },\n \"next/font/google\": { status: \"partial\", detail: \"fonts loaded from CDN, not self-hosted at build time\" },\n \"next/font/local\": { status: \"partial\", detail: \"font.className works but font.variable mode broken (CSS variable not set) — fonts fall back to system sans-serif\" },\n \"next/og\": { status: \"supported\", detail: \"ImageResponse via @vercel/og\" },\n \"next/config\": { status: \"supported\" },\n \"next/amp\": { status: \"unsupported\", detail: \"AMP is not supported\" },\n \"next/document\": { status: \"supported\", detail: \"custom _document.tsx\" },\n \"next/app\": { status: \"supported\", detail: \"custom _app.tsx\" },\n \"next/error\": { status: \"supported\" },\n \"next/third-parties/google\": { status: \"unsupported\", detail: \"third-party script optimization not implemented\" },\n \"server-only\": { status: \"supported\" },\n \"client-only\": { status: \"supported\" },\n};\n\n// ── Config support map ─────────────────────────────────────────────────────\n\nconst CONFIG_SUPPORT: Record<string, { status: Status; detail?: string }> = {\n basePath: { status: \"supported\" },\n trailingSlash: { status: \"supported\" },\n redirects: { status: \"supported\" },\n rewrites: { status: \"supported\" },\n headers: { status: \"supported\" },\n i18n: { status: \"supported\", detail: \"path-prefix routing (domains not yet supported)\" },\n env: { status: \"supported\" },\n images: { status: \"partial\", detail: \"remotePatterns validated, no local optimization\" },\n output: { status: \"supported\", detail: \"'export' and 'standalone' modes\" },\n transpilePackages: { status: \"supported\", detail: \"Vite handles this natively\" },\n webpack: { status: \"unsupported\", detail: \"Vite replaces webpack — custom webpack configs need migration\" },\n \"experimental.ppr\": { status: \"unsupported\", detail: \"partial prerendering not yet implemented\" },\n \"experimental.typedRoutes\": { status: \"unsupported\", detail: \"typed routes not implemented\" },\n \"experimental.serverActions\": { status: \"supported\", detail: \"server actions via 'use server' directive\" },\n \"i18n.domains\": { status: \"unsupported\", detail: \"domain-based i18n routing not implemented\" },\n reactStrictMode: { status: \"supported\", detail: \"always enabled\" },\n poweredByHeader: { status: \"supported\", detail: \"not sent (matching Next.js default when disabled)\" },\n};\n\n// ── Library support map ────────────────────────────────────────────────────\n\nconst LIBRARY_SUPPORT: Record<string, { status: Status; detail?: string }> = {\n \"next-themes\": { status: \"supported\" },\n nuqs: { status: \"supported\" },\n \"next-view-transitions\": { status: \"supported\" },\n \"@vercel/analytics\": { status: \"supported\", detail: \"analytics script injected client-side\" },\n \"next-intl\": { status: \"partial\", detail: \"works with middleware-based setup, some server component features may differ\" },\n \"@clerk/nextjs\": { status: \"unsupported\", detail: \"deep Next.js middleware integration not compatible\" },\n \"@auth/nextjs\": { status: \"unsupported\", detail: \"relies on Next.js internal auth handlers; consider migrating to better-auth\" },\n \"next-auth\": { status: \"unsupported\", detail: \"relies on Next.js API route internals; consider migrating to better-auth (see https://authjs.dev/getting-started/migrate-to-better-auth)\" },\n \"better-auth\": { status: \"supported\", detail: \"uses only public next/* APIs (headers, cookies, NextRequest/NextResponse)\" },\n \"@sentry/nextjs\": { status: \"partial\", detail: \"client-side works, server integration needs manual setup\" },\n \"@t3-oss/env-nextjs\": { status: \"supported\" },\n \"tailwindcss\": { status: \"supported\" },\n \"styled-components\": { status: \"partial\", detail: \"needs useServerInsertedHTML (not yet implemented)\" },\n \"@emotion/react\": { status: \"partial\", detail: \"needs useServerInsertedHTML (not yet implemented)\" },\n \"lucide-react\": { status: \"supported\" },\n \"framer-motion\": { status: \"supported\" },\n \"@radix-ui/react-dialog\": { status: \"supported\" },\n \"shadcn-ui\": { status: \"supported\" },\n zod: { status: \"supported\" },\n \"react-hook-form\": { status: \"supported\" },\n prisma: { status: \"supported\", detail: \"works on Cloudflare Workers with Prisma Accelerate\" },\n drizzle: { status: \"supported\", detail: \"works with D1 on Cloudflare Workers\" },\n};\n\n// ── Scanning functions ─────────────────────────────────────────────────────\n\n/**\n * Recursively find all source files in a directory.\n */\nfunction findSourceFiles(dir: string, extensions = [\".ts\", \".tsx\", \".js\", \".jsx\", \".mjs\"]): string[] {\n const results: string[] = [];\n if (!fs.existsSync(dir)) return results;\n\n const entries = fs.readdirSync(dir, { withFileTypes: true });\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n if (entry.isDirectory()) {\n if (entry.name === \"node_modules\" || entry.name === \".next\" || entry.name === \"dist\" || entry.name === \".git\") continue;\n results.push(...findSourceFiles(fullPath, extensions));\n } else if (extensions.some(ext => entry.name.endsWith(ext))) {\n results.push(fullPath);\n }\n }\n return results;\n}\n\n/**\n * Scan source files for `import ... from 'next/...'` statements.\n */\nexport function scanImports(root: string): CheckItem[] {\n const files = findSourceFiles(root);\n const importUsage = new Map<string, string[]>();\n\n const importRegex = /(?:import\\s+(?:[\\w{},\\s*]+\\s+from\\s+)?|require\\s*\\()['\"]([^'\"]+)['\"]\\)?/g;\n // Skip `import type` and `import { type ... }` — they're erased at compile time\n const typeOnlyImportRegex = /import\\s+type\\s+/;\n\n for (const file of files) {\n const content = fs.readFileSync(file, \"utf-8\");\n let match;\n while ((match = importRegex.exec(content)) !== null) {\n const mod = match[1];\n // Skip type-only imports (no runtime effect)\n const lineStart = content.lastIndexOf(\"\\n\", match.index) + 1;\n const line = content.slice(lineStart, match.index + match[0].length);\n if (typeOnlyImportRegex.test(line)) continue;\n // Only track next/* imports and server-only/client-only\n if (mod.startsWith(\"next/\") || mod === \"next\" || mod === \"server-only\" || mod === \"client-only\") {\n // Normalize: next/font/google -> next/font/google\n const normalized = mod === \"next\" ? \"next\" : mod;\n if (!importUsage.has(normalized)) importUsage.set(normalized, []);\n const relFile = path.relative(root, file);\n if (!importUsage.get(normalized)!.includes(relFile)) {\n importUsage.get(normalized)!.push(relFile);\n }\n }\n }\n }\n\n const items: CheckItem[] = [];\n for (const [mod, usedFiles] of importUsage) {\n const support = IMPORT_SUPPORT[mod];\n if (support) {\n items.push({\n name: mod,\n status: support.status,\n detail: support.detail,\n files: usedFiles,\n });\n } else {\n items.push({\n name: mod,\n status: \"unsupported\",\n detail: \"not recognized by vinext\",\n files: usedFiles,\n });\n }\n }\n\n // Sort: unsupported first, then partial, then supported\n items.sort((a, b) => {\n const order: Record<Status, number> = { unsupported: 0, partial: 1, supported: 2 };\n return order[a.status] - order[b.status];\n });\n\n return items;\n}\n\n/**\n * Analyze next.config.js/mjs/ts for supported and unsupported options.\n */\nexport function analyzeConfig(root: string): CheckItem[] {\n const configFiles = [\"next.config.ts\", \"next.config.mjs\", \"next.config.js\", \"next.config.cjs\"];\n let configPath: string | null = null;\n for (const f of configFiles) {\n const p = path.join(root, f);\n if (fs.existsSync(p)) { configPath = p; break; }\n }\n\n if (!configPath) {\n return [{ name: \"next.config\", status: \"supported\", detail: \"no config file found (defaults are fine)\" }];\n }\n\n const content = fs.readFileSync(configPath, \"utf-8\");\n const items: CheckItem[] = [];\n\n // Check for known config options by searching for property names in the config file\n const configOptions = [\n \"basePath\", \"trailingSlash\", \"redirects\", \"rewrites\", \"headers\",\n \"i18n\", \"env\", \"images\", \"output\", \"transpilePackages\", \"webpack\",\n \"reactStrictMode\", \"poweredByHeader\",\n ];\n\n for (const opt of configOptions) {\n // Simple heuristic: check if the option name appears as a property in the config\n const regex = new RegExp(`\\\\b${opt}\\\\b`);\n if (regex.test(content)) {\n const support = CONFIG_SUPPORT[opt];\n if (support) {\n items.push({ name: opt, status: support.status, detail: support.detail });\n } else {\n items.push({ name: opt, status: \"unsupported\", detail: \"not recognized\" });\n }\n }\n }\n\n // Check for experimental options\n if (/experimental\\s*[:=]\\s*\\{/.test(content)) {\n if (/\\bppr\\b/.test(content)) {\n items.push({ name: \"experimental.ppr\", ...CONFIG_SUPPORT[\"experimental.ppr\"]! });\n }\n if (/\\btypedRoutes\\b/.test(content)) {\n items.push({ name: \"experimental.typedRoutes\", ...CONFIG_SUPPORT[\"experimental.typedRoutes\"]! });\n }\n if (/\\bserverActions\\b/.test(content)) {\n items.push({ name: \"experimental.serverActions\", ...CONFIG_SUPPORT[\"experimental.serverActions\"]! });\n }\n }\n\n // Check for i18n.domains\n if (/domains\\s*:/.test(content) && /i18n/.test(content)) {\n items.push({ name: \"i18n.domains\", ...CONFIG_SUPPORT[\"i18n.domains\"]! });\n }\n\n // Sort: unsupported first\n items.sort((a, b) => {\n const order: Record<Status, number> = { unsupported: 0, partial: 1, supported: 2 };\n return order[a.status] - order[b.status];\n });\n\n return items;\n}\n\n/**\n * Check package.json dependencies for known libraries.\n */\nexport function checkLibraries(root: string): CheckItem[] {\n const pkgPath = path.join(root, \"package.json\");\n if (!fs.existsSync(pkgPath)) return [];\n\n const pkg = JSON.parse(fs.readFileSync(pkgPath, \"utf-8\"));\n const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };\n const items: CheckItem[] = [];\n\n for (const [lib, support] of Object.entries(LIBRARY_SUPPORT)) {\n if (allDeps[lib]) {\n items.push({\n name: lib,\n status: support.status,\n detail: support.detail,\n });\n }\n }\n\n // Sort: unsupported first\n items.sort((a, b) => {\n const order: Record<Status, number> = { unsupported: 0, partial: 1, supported: 2 };\n return order[a.status] - order[b.status];\n });\n\n return items;\n}\n\n/**\n * Check file conventions (pages, app directory, middleware, etc.)\n */\nexport function checkConventions(root: string): CheckItem[] {\n const items: CheckItem[] = [];\n\n // Check for pages/ and app/ at root level, then fall back to src/\n const pagesDir = fs.existsSync(path.join(root, \"pages\"))\n ? path.join(root, \"pages\")\n : fs.existsSync(path.join(root, \"src\", \"pages\"))\n ? path.join(root, \"src\", \"pages\")\n : null;\n const appDirPath = fs.existsSync(path.join(root, \"app\"))\n ? path.join(root, \"app\")\n : fs.existsSync(path.join(root, \"src\", \"app\"))\n ? path.join(root, \"src\", \"app\")\n : null;\n\n const hasPages = pagesDir !== null;\n const hasApp = appDirPath !== null;\n const hasProxy = fs.existsSync(path.join(root, \"proxy.ts\")) || fs.existsSync(path.join(root, \"proxy.js\"));\n const hasMiddleware = fs.existsSync(path.join(root, \"middleware.ts\")) || fs.existsSync(path.join(root, \"middleware.js\"));\n\n if (hasPages) {\n const isSrc = pagesDir!.includes(path.join(\"src\", \"pages\"));\n items.push({ name: isSrc ? \"Pages Router (src/pages/)\" : \"Pages Router (pages/)\", status: \"supported\" });\n\n // Count pages\n const pageFiles = findSourceFiles(pagesDir!);\n const pages = pageFiles.filter(f => !f.includes(\"/api/\") && !f.includes(\"_app\") && !f.includes(\"_document\") && !f.includes(\"_error\"));\n const apiRoutes = pageFiles.filter(f => f.includes(\"/api/\"));\n items.push({ name: `${pages.length} page(s)`, status: \"supported\" });\n if (apiRoutes.length) {\n items.push({ name: `${apiRoutes.length} API route(s)`, status: \"supported\" });\n }\n\n // Check for _app, _document\n if (pageFiles.some(f => f.includes(\"_app\"))) {\n items.push({ name: \"Custom _app\", status: \"supported\" });\n }\n if (pageFiles.some(f => f.includes(\"_document\"))) {\n items.push({ name: \"Custom _document\", status: \"supported\" });\n }\n }\n\n if (hasApp) {\n const isSrc = appDirPath!.includes(path.join(\"src\", \"app\"));\n items.push({ name: isSrc ? \"App Router (src/app/)\" : \"App Router (app/)\", status: \"supported\" });\n\n const appFiles = findSourceFiles(appDirPath!);\n const pages = appFiles.filter(f => f.endsWith(\"page.tsx\") || f.endsWith(\"page.jsx\") || f.endsWith(\"page.ts\") || f.endsWith(\"page.js\"));\n const layouts = appFiles.filter(f => f.endsWith(\"layout.tsx\") || f.endsWith(\"layout.jsx\") || f.endsWith(\"layout.ts\") || f.endsWith(\"layout.js\"));\n const routes = appFiles.filter(f => f.endsWith(\"route.tsx\") || f.endsWith(\"route.ts\") || f.endsWith(\"route.js\"));\n const loadings = appFiles.filter(f => f.endsWith(\"loading.tsx\") || f.endsWith(\"loading.jsx\"));\n const errors = appFiles.filter(f => f.endsWith(\"error.tsx\") || f.endsWith(\"error.jsx\"));\n const notFounds = appFiles.filter(f => f.endsWith(\"not-found.tsx\") || f.endsWith(\"not-found.jsx\"));\n\n items.push({ name: `${pages.length} page(s)`, status: \"supported\" });\n if (layouts.length) items.push({ name: `${layouts.length} layout(s)`, status: \"supported\" });\n if (routes.length) items.push({ name: `${routes.length} route handler(s)`, status: \"supported\" });\n if (loadings.length) items.push({ name: `${loadings.length} loading boundary(ies)`, status: \"supported\" });\n if (errors.length) items.push({ name: `${errors.length} error boundary(ies)`, status: \"supported\" });\n if (notFounds.length) items.push({ name: `${notFounds.length} not-found page(s)`, status: \"supported\" });\n }\n\n if (hasProxy) {\n items.push({ name: \"proxy.ts (Next.js 16)\", status: \"supported\" });\n } else if (hasMiddleware) {\n items.push({ name: \"middleware.ts (deprecated in Next.js 16)\", status: \"supported\" });\n }\n\n if (!hasPages && !hasApp) {\n items.push({ name: \"No pages/ or app/ directory found\", status: \"unsupported\", detail: \"vinext requires a pages/ or app/ directory\" });\n }\n\n // Check for \"type\": \"module\" in package.json\n const pkgPath = path.join(root, \"package.json\");\n if (fs.existsSync(pkgPath)) {\n const pkg = JSON.parse(fs.readFileSync(pkgPath, \"utf-8\"));\n if (pkg.type !== \"module\") {\n items.push({\n name: 'Missing \"type\": \"module\" in package.json',\n status: \"unsupported\",\n detail: \"required for Vite — vinext init will add it automatically\",\n });\n }\n }\n\n // Scan for ViewTransition import from react\n const allSourceFiles = findSourceFiles(root);\n const viewTransitionRegex = /import\\s+\\{[^}]*\\bViewTransition\\b[^}]*\\}\\s+from\\s+['\"]react['\"]/;\n const viewTransitionFiles: string[] = [];\n for (const file of allSourceFiles) {\n const content = fs.readFileSync(file, \"utf-8\");\n if (viewTransitionRegex.test(content)) {\n viewTransitionFiles.push(path.relative(root, file));\n }\n }\n if (viewTransitionFiles.length > 0) {\n items.push({\n name: \"ViewTransition (React canary API)\",\n status: \"partial\",\n detail: \"vinext auto-shims with a passthrough fallback, view transitions won't animate\",\n files: viewTransitionFiles,\n });\n }\n\n // Check PostCSS config for string-form plugins\n const postcssConfigs = [\"postcss.config.mjs\", \"postcss.config.js\", \"postcss.config.cjs\"];\n for (const configFile of postcssConfigs) {\n const configPath = path.join(root, configFile);\n if (fs.existsSync(configPath)) {\n const content = fs.readFileSync(configPath, \"utf-8\");\n // Detect string-form plugins: plugins: [\"...\"] or plugins: ['...']\n const stringPluginRegex = /plugins\\s*:\\s*\\[[\\s\\S]*?(['\"][^'\"]+['\"])[\\s\\S]*?\\]/;\n const match = stringPluginRegex.exec(content);\n if (match) {\n // Check it's not require() or import() form — just bare string literals in the array\n const pluginsBlock = match[0];\n // If plugins array contains string literals not wrapped in require()\n if (/plugins\\s*:\\s*\\[[\\s\\n]*['\"]/.test(pluginsBlock)) {\n items.push({\n name: `PostCSS string-form plugins (${configFile})`,\n status: \"partial\",\n detail: \"string-form PostCSS plugins need resolution — vinext handles this automatically\",\n });\n }\n }\n break; // Only check the first config file found\n }\n }\n\n return items;\n}\n\n/**\n * Run the full compatibility check.\n */\nexport function runCheck(root: string): CheckResult {\n const imports = scanImports(root);\n const config = analyzeConfig(root);\n const libraries = checkLibraries(root);\n const conventions = checkConventions(root);\n\n const allItems = [...imports, ...config, ...libraries, ...conventions];\n const supported = allItems.filter(i => i.status === \"supported\").length;\n const partial = allItems.filter(i => i.status === \"partial\").length;\n const unsupported = allItems.filter(i => i.status === \"unsupported\").length;\n const total = allItems.length;\n // Score: supported = 1, partial = 0.5, unsupported = 0\n const score = total > 0 ? Math.round(((supported + partial * 0.5) / total) * 100) : 100;\n\n return {\n imports,\n config,\n libraries,\n conventions,\n summary: { supported, partial, unsupported, total, score },\n };\n}\n\n/**\n * Format the check result as a colored terminal report.\n */\nexport function formatReport(result: CheckResult, opts?: { calledFromInit?: boolean }): string {\n const lines: string[] = [];\n const statusIcon = (s: Status) => s === \"supported\" ? \"\\x1b[32m✓\\x1b[0m\" : s === \"partial\" ? \"\\x1b[33m~\\x1b[0m\" : \"\\x1b[31m✗\\x1b[0m\";\n\n lines.push(\"\");\n lines.push(\" \\x1b[1mvinext compatibility report\\x1b[0m\");\n lines.push(\" \" + \"=\".repeat(40));\n lines.push(\"\");\n\n // Imports\n if (result.imports.length > 0) {\n const importSupported = result.imports.filter(i => i.status === \"supported\").length;\n lines.push(` \\x1b[1mImports\\x1b[0m: ${importSupported}/${result.imports.length} fully supported`);\n for (const item of result.imports) {\n const suffix = item.detail ? ` \\x1b[90m— ${item.detail}\\x1b[0m` : \"\";\n const fileCount = item.files ? ` \\x1b[90m(${item.files.length} file${item.files.length === 1 ? \"\" : \"s\"})\\x1b[0m` : \"\";\n lines.push(` ${statusIcon(item.status)} ${item.name}${fileCount}${suffix}`);\n }\n lines.push(\"\");\n }\n\n // Config\n if (result.config.length > 0) {\n const configSupported = result.config.filter(i => i.status === \"supported\").length;\n lines.push(` \\x1b[1mConfig\\x1b[0m: ${configSupported}/${result.config.length} options supported`);\n for (const item of result.config) {\n const suffix = item.detail ? ` \\x1b[90m— ${item.detail}\\x1b[0m` : \"\";\n lines.push(` ${statusIcon(item.status)} ${item.name}${suffix}`);\n }\n lines.push(\"\");\n }\n\n // Libraries\n if (result.libraries.length > 0) {\n const libSupported = result.libraries.filter(i => i.status === \"supported\").length;\n lines.push(` \\x1b[1mLibraries\\x1b[0m: ${libSupported}/${result.libraries.length} compatible`);\n for (const item of result.libraries) {\n const suffix = item.detail ? ` \\x1b[90m— ${item.detail}\\x1b[0m` : \"\";\n lines.push(` ${statusIcon(item.status)} ${item.name}${suffix}`);\n }\n lines.push(\"\");\n }\n\n // Conventions\n if (result.conventions.length > 0) {\n lines.push(` \\x1b[1mProject structure\\x1b[0m:`);\n for (const item of result.conventions) {\n const suffix = item.detail ? ` \\x1b[90m— ${item.detail}\\x1b[0m` : \"\";\n lines.push(` ${statusIcon(item.status)} ${item.name}${suffix}`);\n }\n lines.push(\"\");\n }\n\n // Summary\n const { score, supported, partial, unsupported } = result.summary;\n const scoreColor = score >= 90 ? \"\\x1b[32m\" : score >= 70 ? \"\\x1b[33m\" : \"\\x1b[31m\";\n lines.push(\" \" + \"-\".repeat(40));\n lines.push(` \\x1b[1mOverall\\x1b[0m: ${scoreColor}${score}% compatible\\x1b[0m (${supported} supported, ${partial} partial, ${unsupported} issues)`);\n\n if (unsupported > 0) {\n lines.push(\"\");\n lines.push(\" \\x1b[1mIssues to address:\\x1b[0m\");\n const allItems = [...result.imports, ...result.config, ...result.libraries, ...result.conventions];\n for (const item of allItems) {\n if (item.status === \"unsupported\") {\n lines.push(` \\x1b[31m✗\\x1b[0m ${item.name}${item.detail ? ` — ${item.detail}` : \"\"}`);\n }\n }\n }\n\n if (result.summary.partial > 0) {\n lines.push(\"\");\n lines.push(\" \\x1b[1mPartial support (may need attention):\\x1b[0m\");\n const allItems = [...result.imports, ...result.config, ...result.libraries, ...result.conventions];\n for (const item of allItems) {\n if (item.status === \"partial\") {\n lines.push(` \\x1b[33m~\\x1b[0m ${item.name}${item.detail ? ` — ${item.detail}` : \"\"}`);\n }\n }\n }\n\n // Actionable next steps (skip when called from init — it prints its own summary)\n if (!opts?.calledFromInit) {\n lines.push(\"\");\n lines.push(\" \\x1b[1mRecommended next steps:\\x1b[0m\");\n lines.push(` Run \\x1b[36mvinext init\\x1b[0m to set up your project automatically`);\n lines.push(\"\");\n lines.push(\" Or manually:\");\n lines.push(` 1. Add \\x1b[36m\"type\": \"module\"\\x1b[0m to package.json`);\n lines.push(` 2. Install: \\x1b[36mnpm install -D vinext vite @vitejs/plugin-rsc\\x1b[0m`);\n lines.push(` 3. Create vite.config.ts (see docs)`);\n lines.push(` 4. Run: \\x1b[36mnpx vite dev\\x1b[0m`);\n }\n\n lines.push(\"\");\n return lines.join(\"\\n\");\n}\n"]}
package/dist/init.js CHANGED
@@ -120,7 +120,7 @@ export async function init(options) {
120
120
  if (!options.skipCheck) {
121
121
  console.log(" Running compatibility check...\n");
122
122
  const checkResult = runCheck(root);
123
- console.log(formatReport(checkResult));
123
+ console.log(formatReport(checkResult, { calledFromInit: true }));
124
124
  console.log(); // blank line before migration steps
125
125
  }
126
126
  // ── Step 2: Install dependencies ───────────────────────────────────────
package/dist/init.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"init.js","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * vinext init — one-command project migration for Next.js apps.\n *\n * Automates the steps needed to run a Next.js app under vinext:\n *\n * 1. Run `vinext check` to show compatibility report\n * 2. Install dependencies (vite, @vitejs/plugin-rsc for App Router)\n * 3. Add \"type\": \"module\" to package.json\n * 4. Rename CJS config files to .cjs\n * 5. Add vinext scripts to package.json\n * 6. Generate vite.config.ts\n * 7. Print summary\n *\n * Non-destructive: does NOT modify next.config, tsconfig, or source files.\n * The project should work with both Next.js and vinext simultaneously.\n */\n\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { execSync } from \"node:child_process\";\nimport { runCheck, formatReport } from \"./check.js\";\nimport {\n ensureESModule,\n renameCJSConfigs,\n detectPackageManager,\n detectPackageManagerName,\n hasViteConfig,\n hasAppDir,\n} from \"./utils/project.js\";\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\nexport interface InitOptions {\n /** Project root directory */\n root: string;\n /** Dev server port (default: 3001) */\n port?: number;\n /** Skip the compatibility check step */\n skipCheck?: boolean;\n /** Force overwrite even if vite.config.ts exists */\n force?: boolean;\n /** @internal — override exec for testing (avoids ESM spy issues) */\n _exec?: (cmd: string, opts: { cwd: string; stdio: string }) => void;\n}\n\nexport interface InitResult {\n /** Whether dependencies were installed */\n installedDeps: string[];\n /** Whether \"type\": \"module\" was added */\n addedTypeModule: boolean;\n /** CJS config files that were renamed ([old, new] pairs) */\n renamedConfigs: Array<[string, string]>;\n /** Whether scripts were added to package.json */\n addedScripts: string[];\n /** Whether vite.config.ts was generated */\n generatedViteConfig: boolean;\n /** Whether vite.config.ts generation was skipped (already exists) */\n skippedViteConfig: boolean;\n}\n\n// ─── Vite Config Generation (minimal, non-Cloudflare) ────────────────────────\n\nexport function generateViteConfig(_isAppRouter: boolean): string {\n return `import vinext from \"vinext\";\nimport { defineConfig } from \"vite\";\n\nexport default defineConfig({\n plugins: [vinext()],\n});\n`;\n}\n\n// ─── Script Addition ─────────────────────────────────────────────────────────\n\n/**\n * Add vinext scripts to package.json without overwriting existing scripts.\n * Returns the list of script names that were added.\n */\nexport function addScripts(root: string, port: number): string[] {\n const pkgPath = path.join(root, \"package.json\");\n if (!fs.existsSync(pkgPath)) return [];\n\n try {\n const raw = fs.readFileSync(pkgPath, \"utf-8\");\n const pkg = JSON.parse(raw);\n\n if (!pkg.scripts) {\n pkg.scripts = {};\n }\n\n const added: string[] = [];\n\n if (!pkg.scripts[\"dev:vinext\"]) {\n pkg.scripts[\"dev:vinext\"] = `vite dev --port ${port}`;\n added.push(\"dev:vinext\");\n }\n\n if (!pkg.scripts[\"build:vinext\"]) {\n pkg.scripts[\"build:vinext\"] = \"vite build\";\n added.push(\"build:vinext\");\n }\n\n if (added.length > 0) {\n fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + \"\\n\", \"utf-8\");\n }\n\n return added;\n } catch {\n return [];\n }\n}\n\n// ─── Dependency Installation ─────────────────────────────────────────────────\n\nexport function getInitDeps(isAppRouter: boolean): string[] {\n const deps = [\"vinext\", \"vite\"];\n if (isAppRouter) {\n deps.push(\"@vitejs/plugin-rsc\");\n }\n return deps;\n}\n\nexport function isDepInstalled(root: string, dep: string): boolean {\n const pkgPath = path.join(root, \"package.json\");\n if (!fs.existsSync(pkgPath)) return false;\n try {\n const pkg = JSON.parse(fs.readFileSync(pkgPath, \"utf-8\"));\n const allDeps = {\n ...pkg.dependencies,\n ...pkg.devDependencies,\n ...pkg.peerDependencies,\n };\n return dep in allDeps;\n } catch {\n return false;\n }\n}\n\nfunction installDeps(\n root: string,\n deps: string[],\n exec: (cmd: string, opts: { cwd: string; stdio: string }) => void,\n): void {\n if (deps.length === 0) return;\n\n const installCmd = detectPackageManager(root);\n const depsStr = deps.join(\" \");\n\n exec(`${installCmd} ${depsStr}`, {\n cwd: root,\n stdio: \"inherit\",\n });\n}\n\n// ─── Main Entry ──────────────────────────────────────────────────────────────\n\nexport async function init(options: InitOptions): Promise<InitResult> {\n const root = path.resolve(options.root);\n const port = options.port ?? 3001;\n const exec = options._exec ?? ((cmd: string, opts: { cwd: string; stdio: string }) => {\n execSync(cmd, opts as Parameters<typeof execSync>[1]);\n });\n\n // ── Pre-flight checks ──────────────────────────────────────────────────\n\n // Ensure package.json exists\n const pkgPath = path.join(root, \"package.json\");\n if (!fs.existsSync(pkgPath)) {\n console.error(\" Error: No package.json found in the current directory.\");\n console.error(\" Run this command from the root of a Next.js project.\\n\");\n process.exit(1);\n }\n\n // Check if vite.config already exists — skip generation later, but continue\n const viteConfigExists = hasViteConfig(root);\n\n const isApp = hasAppDir(root);\n const pmName = detectPackageManagerName(root);\n\n // ── Step 1: Compatibility check ────────────────────────────────────────\n\n if (!options.skipCheck) {\n console.log(\" Running compatibility check...\\n\");\n const checkResult = runCheck(root);\n console.log(formatReport(checkResult));\n console.log(); // blank line before migration steps\n }\n\n // ── Step 2: Install dependencies ───────────────────────────────────────\n\n const neededDeps = getInitDeps(isApp);\n const missingDeps = neededDeps.filter((dep) => !isDepInstalled(root, dep));\n\n if (missingDeps.length > 0) {\n console.log(` Installing ${missingDeps.join(\", \")}...`);\n installDeps(root, missingDeps, exec);\n console.log();\n }\n\n // ── Step 3: Add \"type\": \"module\" ───────────────────────────────────────\n\n // Rename CJS configs first (before adding \"type\": \"module\") to avoid breakage\n const renamedConfigs = renameCJSConfigs(root);\n const addedTypeModule = ensureESModule(root);\n\n // ── Step 4: Add scripts ────────────────────────────────────────────────\n\n const addedScripts = addScripts(root, port);\n\n // ── Step 5: Generate vite.config.ts ────────────────────────────────────\n\n let generatedViteConfig = false;\n const skippedViteConfig = viteConfigExists && !options.force;\n if (!skippedViteConfig) {\n const configContent = generateViteConfig(isApp);\n fs.writeFileSync(path.join(root, \"vite.config.ts\"), configContent, \"utf-8\");\n generatedViteConfig = true;\n }\n\n // ── Step 6: Print summary ──────────────────────────────────────────────\n\n console.log(\" vinext init complete!\\n\");\n\n if (missingDeps.length > 0) {\n console.log(` \\u2713 Added ${missingDeps.join(\", \")} to devDependencies`);\n }\n if (addedTypeModule) {\n console.log(` \\u2713 Added \"type\": \"module\" to package.json`);\n }\n for (const [oldName, newName] of renamedConfigs) {\n console.log(` \\u2713 Renamed ${oldName} \\u2192 ${newName}`);\n }\n for (const script of addedScripts) {\n console.log(` \\u2713 Added ${script} script`);\n }\n if (generatedViteConfig) {\n console.log(` \\u2713 Generated vite.config.ts`);\n }\n if (skippedViteConfig) {\n console.log(` - Skipped vite.config.ts (already exists, use --force to overwrite)`);\n }\n\n console.log(`\n Next steps:\n ${pmName} run dev:vinext Start the vinext dev server\n ${pmName} run dev Start Next.js (still works as before)\n`);\n\n return {\n installedDeps: missingDeps,\n addedTypeModule,\n renamedConfigs,\n addedScripts,\n generatedViteConfig,\n skippedViteConfig,\n };\n}\n"]}
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * vinext init — one-command project migration for Next.js apps.\n *\n * Automates the steps needed to run a Next.js app under vinext:\n *\n * 1. Run `vinext check` to show compatibility report\n * 2. Install dependencies (vite, @vitejs/plugin-rsc for App Router)\n * 3. Add \"type\": \"module\" to package.json\n * 4. Rename CJS config files to .cjs\n * 5. Add vinext scripts to package.json\n * 6. Generate vite.config.ts\n * 7. Print summary\n *\n * Non-destructive: does NOT modify next.config, tsconfig, or source files.\n * The project should work with both Next.js and vinext simultaneously.\n */\n\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { execSync } from \"node:child_process\";\nimport { runCheck, formatReport } from \"./check.js\";\nimport {\n ensureESModule,\n renameCJSConfigs,\n detectPackageManager,\n detectPackageManagerName,\n hasViteConfig,\n hasAppDir,\n} from \"./utils/project.js\";\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\nexport interface InitOptions {\n /** Project root directory */\n root: string;\n /** Dev server port (default: 3001) */\n port?: number;\n /** Skip the compatibility check step */\n skipCheck?: boolean;\n /** Force overwrite even if vite.config.ts exists */\n force?: boolean;\n /** @internal — override exec for testing (avoids ESM spy issues) */\n _exec?: (cmd: string, opts: { cwd: string; stdio: string }) => void;\n}\n\nexport interface InitResult {\n /** Whether dependencies were installed */\n installedDeps: string[];\n /** Whether \"type\": \"module\" was added */\n addedTypeModule: boolean;\n /** CJS config files that were renamed ([old, new] pairs) */\n renamedConfigs: Array<[string, string]>;\n /** Whether scripts were added to package.json */\n addedScripts: string[];\n /** Whether vite.config.ts was generated */\n generatedViteConfig: boolean;\n /** Whether vite.config.ts generation was skipped (already exists) */\n skippedViteConfig: boolean;\n}\n\n// ─── Vite Config Generation (minimal, non-Cloudflare) ────────────────────────\n\nexport function generateViteConfig(_isAppRouter: boolean): string {\n return `import vinext from \"vinext\";\nimport { defineConfig } from \"vite\";\n\nexport default defineConfig({\n plugins: [vinext()],\n});\n`;\n}\n\n// ─── Script Addition ─────────────────────────────────────────────────────────\n\n/**\n * Add vinext scripts to package.json without overwriting existing scripts.\n * Returns the list of script names that were added.\n */\nexport function addScripts(root: string, port: number): string[] {\n const pkgPath = path.join(root, \"package.json\");\n if (!fs.existsSync(pkgPath)) return [];\n\n try {\n const raw = fs.readFileSync(pkgPath, \"utf-8\");\n const pkg = JSON.parse(raw);\n\n if (!pkg.scripts) {\n pkg.scripts = {};\n }\n\n const added: string[] = [];\n\n if (!pkg.scripts[\"dev:vinext\"]) {\n pkg.scripts[\"dev:vinext\"] = `vite dev --port ${port}`;\n added.push(\"dev:vinext\");\n }\n\n if (!pkg.scripts[\"build:vinext\"]) {\n pkg.scripts[\"build:vinext\"] = \"vite build\";\n added.push(\"build:vinext\");\n }\n\n if (added.length > 0) {\n fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + \"\\n\", \"utf-8\");\n }\n\n return added;\n } catch {\n return [];\n }\n}\n\n// ─── Dependency Installation ─────────────────────────────────────────────────\n\nexport function getInitDeps(isAppRouter: boolean): string[] {\n const deps = [\"vinext\", \"vite\"];\n if (isAppRouter) {\n deps.push(\"@vitejs/plugin-rsc\");\n }\n return deps;\n}\n\nexport function isDepInstalled(root: string, dep: string): boolean {\n const pkgPath = path.join(root, \"package.json\");\n if (!fs.existsSync(pkgPath)) return false;\n try {\n const pkg = JSON.parse(fs.readFileSync(pkgPath, \"utf-8\"));\n const allDeps = {\n ...pkg.dependencies,\n ...pkg.devDependencies,\n ...pkg.peerDependencies,\n };\n return dep in allDeps;\n } catch {\n return false;\n }\n}\n\nfunction installDeps(\n root: string,\n deps: string[],\n exec: (cmd: string, opts: { cwd: string; stdio: string }) => void,\n): void {\n if (deps.length === 0) return;\n\n const installCmd = detectPackageManager(root);\n const depsStr = deps.join(\" \");\n\n exec(`${installCmd} ${depsStr}`, {\n cwd: root,\n stdio: \"inherit\",\n });\n}\n\n// ─── Main Entry ──────────────────────────────────────────────────────────────\n\nexport async function init(options: InitOptions): Promise<InitResult> {\n const root = path.resolve(options.root);\n const port = options.port ?? 3001;\n const exec = options._exec ?? ((cmd: string, opts: { cwd: string; stdio: string }) => {\n execSync(cmd, opts as Parameters<typeof execSync>[1]);\n });\n\n // ── Pre-flight checks ──────────────────────────────────────────────────\n\n // Ensure package.json exists\n const pkgPath = path.join(root, \"package.json\");\n if (!fs.existsSync(pkgPath)) {\n console.error(\" Error: No package.json found in the current directory.\");\n console.error(\" Run this command from the root of a Next.js project.\\n\");\n process.exit(1);\n }\n\n // Check if vite.config already exists — skip generation later, but continue\n const viteConfigExists = hasViteConfig(root);\n\n const isApp = hasAppDir(root);\n const pmName = detectPackageManagerName(root);\n\n // ── Step 1: Compatibility check ────────────────────────────────────────\n\n if (!options.skipCheck) {\n console.log(\" Running compatibility check...\\n\");\n const checkResult = runCheck(root);\n console.log(formatReport(checkResult, { calledFromInit: true }));\n console.log(); // blank line before migration steps\n }\n\n // ── Step 2: Install dependencies ───────────────────────────────────────\n\n const neededDeps = getInitDeps(isApp);\n const missingDeps = neededDeps.filter((dep) => !isDepInstalled(root, dep));\n\n if (missingDeps.length > 0) {\n console.log(` Installing ${missingDeps.join(\", \")}...`);\n installDeps(root, missingDeps, exec);\n console.log();\n }\n\n // ── Step 3: Add \"type\": \"module\" ───────────────────────────────────────\n\n // Rename CJS configs first (before adding \"type\": \"module\") to avoid breakage\n const renamedConfigs = renameCJSConfigs(root);\n const addedTypeModule = ensureESModule(root);\n\n // ── Step 4: Add scripts ────────────────────────────────────────────────\n\n const addedScripts = addScripts(root, port);\n\n // ── Step 5: Generate vite.config.ts ────────────────────────────────────\n\n let generatedViteConfig = false;\n const skippedViteConfig = viteConfigExists && !options.force;\n if (!skippedViteConfig) {\n const configContent = generateViteConfig(isApp);\n fs.writeFileSync(path.join(root, \"vite.config.ts\"), configContent, \"utf-8\");\n generatedViteConfig = true;\n }\n\n // ── Step 6: Print summary ──────────────────────────────────────────────\n\n console.log(\" vinext init complete!\\n\");\n\n if (missingDeps.length > 0) {\n console.log(` \\u2713 Added ${missingDeps.join(\", \")} to devDependencies`);\n }\n if (addedTypeModule) {\n console.log(` \\u2713 Added \"type\": \"module\" to package.json`);\n }\n for (const [oldName, newName] of renamedConfigs) {\n console.log(` \\u2713 Renamed ${oldName} \\u2192 ${newName}`);\n }\n for (const script of addedScripts) {\n console.log(` \\u2713 Added ${script} script`);\n }\n if (generatedViteConfig) {\n console.log(` \\u2713 Generated vite.config.ts`);\n }\n if (skippedViteConfig) {\n console.log(` - Skipped vite.config.ts (already exists, use --force to overwrite)`);\n }\n\n console.log(`\n Next steps:\n ${pmName} run dev:vinext Start the vinext dev server\n ${pmName} run dev Start Next.js (still works as before)\n`);\n\n return {\n installedDeps: missingDeps,\n addedTypeModule,\n renamedConfigs,\n addedScripts,\n generatedViteConfig,\n skippedViteConfig,\n };\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vinext",
3
- "version": "0.0.3",
3
+ "version": "0.0.5",
4
4
  "description": "Run Next.js apps on Vite. Drop-in replacement for the next CLI.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -44,7 +44,7 @@
44
44
  ],
45
45
  "scripts": {
46
46
  "build": "tsc",
47
- "prepack": "pnpm run build",
47
+ "prepack": "cp ../../README.md README.md && pnpm run build",
48
48
  "dev": "tsc --watch"
49
49
  },
50
50
  "peerDependencies": {