Skip to content

feat(init): onboard MDX and Tailwind v4 apps on first build - #3239

Open
JamesbbBriz wants to merge 40 commits into
cloudflare:mainfrom
JamesbbBriz:fix/init-framework-onboarding
Open

JamesbbBriz wants to merge 40 commits into
cloudflare:mainfrom
JamesbbBriz:fix/init-framework-onboarding

Conversation

@JamesbbBriz

@JamesbbBriz JamesbbBriz commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

What changed

vinext init now completes the Vite-side setup for existing Next.js projects that use MDX or Tailwind CSS v4:

  • detected MDX routes add @mdx-js/rollup, which vinext already auto-injects at runtime
  • detected Tailwind v4 projects add @tailwindcss/vite and generated Node and Cloudflare configs register tailwindcss()
  • existing Node and Cloudflare configs are updated idempotently with the same Tailwind import and plugin call, including ESM default, named-default, and namespace imports plus existing CommonJS namespace, destructured-default, and already-unwrapped requires; new CommonJS configs load the ESM-only Tailwind plugin through Vite-supported thenable plugins
  • Tailwind v3 projects keep their existing PostCSS setup and are not moved to the v4 plugin
  • the ignored webpack warning explains Vite's native TypeScript resolution and directs genuinely custom rules to vite.config.ts

Tailwind detection prefers v4-specific packages and the exact installed tailwindcss package major through project-aware resolution, including Yarn PnP. That handles comparator, prerelease-only, workspace, git, and tag declarations without maintaining a partial semver parser. Simple explicit v4 declarations remain a fallback when dependencies are not installed; unresolved complex specifiers are not guessed.

Next.js currently scaffolds Tailwind v4 with @tailwindcss/postcss: https://github.com/vercel/next.js/blob/canary/packages/create-next-app/templates/app-tw/ts/postcss.config.mjs

Fixes #3240.

Validation

  • vp test run tests/init.test.ts tests/init-cloudflare.test.ts tests/create-vinext-app.test.ts tests/next-config.test.ts tests/deploy.test.ts — 887 passed
  • vp check packages/vinext/src/init.ts packages/vinext/src/init-cloudflare.ts packages/vinext/src/utils/project.ts packages/vinext/src/config/next-config.ts packages/vinext/src/plugins/ast-utils.ts tests/init.test.ts tests/init-cloudflare.test.ts tests/create-vinext-app.test.ts tests/next-config.test.ts tests/deploy.test.ts — clean
  • vp run vinext#build — passed

Regression coverage exercises App and Pages Router init on Node and Cloudflare for Tailwind v3 and v4, MDX dependency onboarding for both router types, installed-major detection across supported dependency specifiers, generated-config syntax/type checking and real Vite loading of the ESM-only Tailwind package, the supported ESM and CommonJS default-import interop matrix, including typed CommonJS require wrappers, type-only imports before runtime imports, typed/parenthesized plugin-call wrappers, nested and nested, statically spread, logical, conditional, and top-level plain and exported variable-backed plugin arrays, computed ESM and CommonJS default access, and unchanged output when Tailwind is absent.

Migrating a Next.js app that uses MDX pages and Tailwind v4 currently
fails twice before the first successful build:

- @mdx-js/rollup is required for the documented MDX auto-injection but
  was never installed by init
- Tailwind v4 configured through postcss.config string plugins cannot
  resolve under Vite; it needs @tailwindcss/vite in the config

detectProject now reports hasTailwind (tailwindcss dependency); init
installs @mdx-js/rollup / @tailwindcss/vite for detected frameworks and
generates vite configs that wire tailwindcss() for both platforms. The
next.config webpack-ignore warning now explains that Vite resolves
TS/TSX natively, since every Payload-style extensionAlias config trips
it today.

Output for projects without Tailwind stays byte-identical.
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

@pkg-pr-new

pkg-pr-new Bot commented Sep 11, 2026

Copy link
Copy Markdown

Open in StackBlitz

@vinext/cloudflare

npm i https://pkg.pr.new/@vinext/cloudflare@3239

create-vinext-app

npm i https://pkg.pr.new/create-vinext-app@3239

@vinext/types

npm i https://pkg.pr.new/@vinext/types@3239

vinext

npm i https://pkg.pr.new/vinext@3239

@cloudflare/workers-response-store

npm i https://pkg.pr.new/@cloudflare/workers-response-store@3239

commit: 8fc29d5

@github-actions

github-actions Bot commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

Performance benchmarks

Compared 8fc29d5 against base e97de29 using alternating same-runner rounds. Next.js was unchanged and skipped.

0 improved · 0 regressed · 6 within ±1.5%

Scenario Framework Baseline Current Change
Client bundle size (gzip) vinext 142.2 KB 142.2 KB ⚫ -0.0%
Client entry size (gzip) vinext 129.6 KB 129.6 KB ⚫ -0.0%
Dev server cold start vinext 2.60 s 2.61 s ⚫ +0.4%
Production build time vinext 2.70 s 2.71 s ⚫ +0.1%
RSC entry closure size (gzip) vinext 121.0 KB 121.0 KB ⚫ 0.0%
Server bundle size (gzip) vinext 218.3 KB 218.3 KB ⚫ -0.0%

View detailed results and traces

🟢 improvement · 🔴 regression · ⚫ change below 1.5% · paired base/head

JamesbbBriz and others added 4 commits September 12, 2026 02:45
The first pass rewrapped a dozen untouched call sites onto multiple
lines. main is format-clean with the single-line forms, so the rewraps
were pure review noise.
@james-elicx

Copy link
Copy Markdown
Member

/bigbonk review for issues

Time limit: 8 minutes. Complete the review and post all findings within that limit.

1 similar comment
@james-elicx

Copy link
Copy Markdown
Member

/bigbonk review for issues

Time limit: 8 minutes. Complete the review and post all findings within that limit.

Comment thread packages/vinext/src/utils/project.ts Outdated
@ask-bonk

ask-bonk Bot commented Sep 17, 2026

Copy link
Copy Markdown
Contributor

Posted 1 actionable inline finding.

github run

@james-elicx

Copy link
Copy Markdown
Member

/bigbonk review for issues

Time limit: 8 minutes. Complete the review and post all findings within that limit.

Comment thread packages/vinext/src/init-cloudflare.ts
Comment thread packages/vinext/src/utils/project.ts Outdated
@ask-bonk

ask-bonk Bot commented Sep 17, 2026

Copy link
Copy Markdown
Contributor

Posted 2 actionable inline findings.

github run

@james-elicx

Copy link
Copy Markdown
Member

/bigbonk review for issues

Time limit: 8 minutes. Complete the review and post all findings within that limit.

Comment thread packages/vinext/src/utils/project.ts Outdated
@ask-bonk

ask-bonk Bot commented Sep 17, 2026

Copy link
Copy Markdown
Contributor

Posted 1 actionable inline finding.

github run

@james-elicx

Copy link
Copy Markdown
Member

/bigbonk review for issues

Time limit: 8 minutes. Complete the review and post all findings within that limit.

Comment thread packages/vinext/src/init-cloudflare.ts Outdated
@ask-bonk

ask-bonk Bot commented Sep 17, 2026

Copy link
Copy Markdown
Contributor

Posted 1 actionable inline finding.

github run

@james-elicx

Copy link
Copy Markdown
Member

/bigbonk review for issues

Time limit: 8 minutes. Complete the review and post all findings within that limit.

Comment thread packages/vinext/src/init-cloudflare.ts Outdated
@ask-bonk

ask-bonk Bot commented Sep 17, 2026

Copy link
Copy Markdown
Contributor

Posted 1 actionable inline finding.

github run

@james-elicx

Copy link
Copy Markdown
Member

/bigbonk review for issues

Time limit: 8 minutes. Complete the review and post all findings within that limit.

Comment thread packages/vinext/src/init-cloudflare.ts Outdated
Comment thread packages/vinext/src/init-cloudflare.ts Outdated
Comment thread packages/vinext/src/init-cloudflare.ts
@ask-bonk

ask-bonk Bot commented Sep 17, 2026

Copy link
Copy Markdown
Contributor

Posted 3 actionable inline findings.

github run

@james-elicx

Copy link
Copy Markdown
Member

/bigbonk review for issues

Time limit: 8 minutes. Complete the review and post all findings within that limit.

Comment thread packages/vinext/src/init-cloudflare.ts
Comment thread packages/vinext/src/init-cloudflare.ts
Comment thread packages/vinext/src/init-cloudflare.ts Outdated
@ask-bonk

ask-bonk Bot commented Sep 17, 2026

Copy link
Copy Markdown
Contributor

Posted 3 actionable inline findings.

github run

@james-elicx

Copy link
Copy Markdown
Member

/bigbonk review for issues

Time limit: 8 minutes. Complete the review and post all findings within that limit.

Comment thread packages/vinext/src/init-cloudflare.ts Outdated
Comment thread packages/vinext/src/init-cloudflare.ts
Comment thread packages/vinext/src/init-cloudflare.ts
Comment thread packages/vinext/src/init-cloudflare.ts
Comment thread packages/vinext/src/utils/project.ts
@ask-bonk

ask-bonk Bot commented Sep 17, 2026

Copy link
Copy Markdown
Contributor

Posted 5 actionable inline findings.

github run

@james-elicx

Copy link
Copy Markdown
Member

/bigbonk review for issues

Time limit: 8 minutes. Complete the review and post all findings within that limit.

Comment thread packages/vinext/src/init-cloudflare.ts Outdated
Comment thread packages/vinext/src/init-cloudflare.ts
Comment thread packages/vinext/src/init-cloudflare.ts Outdated
Comment thread packages/vinext/src/init-cloudflare.ts Outdated
Comment thread packages/vinext/src/init-cloudflare.ts Outdated
Comment thread packages/vinext/src/init-cloudflare.ts
@ask-bonk

ask-bonk Bot commented Sep 17, 2026

Copy link
Copy Markdown
Contributor

Posted 6 actionable inline findings.

github run

@james-elicx

Copy link
Copy Markdown
Member

/bigbonk review for issues

Time limit: 8 minutes. Complete the review and post all findings within that limit.

Comment thread packages/vinext/src/init-cloudflare.ts
Comment thread packages/vinext/src/init-cloudflare.ts
@ask-bonk

ask-bonk Bot commented Sep 18, 2026

Copy link
Copy Markdown
Contributor

Posted 2 actionable inline findings.

github run

@james-elicx

Copy link
Copy Markdown
Member

/bigbonk review for issues

Time limit: 8 minutes. Complete the review and post all findings within that limit.

Comment thread packages/vinext/src/init-cloudflare.ts
@ask-bonk

ask-bonk Bot commented Sep 18, 2026

Copy link
Copy Markdown
Contributor

Posted 1 actionable inline finding.

github run

@james-elicx

Copy link
Copy Markdown
Member

/bigbonk review for issues

Time limit: 8 minutes. Complete the review and post all findings within that limit.

@ask-bonk

ask-bonk Bot commented Sep 18, 2026

Copy link
Copy Markdown
Contributor

@james-elicx Bonk workflow was cancelled.

View workflow run · To retry, trigger Bonk again.

@james-elicx

Copy link
Copy Markdown
Member

/bigbonk review for issues

Time limit: 8 minutes. Complete the review and post all findings within that limit.

);
}
if (expression?.type === "Identifier" && !seenBindings.has(expression.name)) {
const initializer = findVisibleConstInitializer(program, scopeTarget, expression.name);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Validate identifier-backed nested arrays before trusting their calls

This follows a nested const array but only the outer plugins array is checked by assertPluginArrayIsStatic. For const nested = [tw()]; nested.pop(); export default { plugins: [nested] }, the scan finds tw() in the initializer and leaves the config unchanged, although the effective plugins array is empty at runtime. Please apply the post-initializer mutation check to every identifier-backed array traversed here (including aliases), or conservatively append Tailwind when its effective contents are not static.

return;
}
}
forEachAstChild(node, visit);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Do not treat mutations inside unexecuted functions as top-level writes

This recursively scans function bodies, so an unrelated declaration such as const config = { plugins: [] }; function unused() { config.plugins.push(custom()) } export default config makes Tailwind onboarding abort even though unused is never executed and the exported config remains static. Existing Node configs were previously skipped, so rerunning init now rejects this otherwise supported static form. Skip nested function/class bodies when looking for post-initializer execution, and account for a mutation only when the function is actually part of the evaluated config path.

statement.type === "ExportNamedDeclaration" ? statement.declaration : statement;
if (declaration?.type !== "VariableDeclaration" || declaration.kind !== "const") continue;
for (const declarator of declaration.declarations) {
if (declarator.id.type !== "Identifier") continue;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Follow destructured aliases of namespace default exports

Restricting aliases to identifier declarators misses import * as tailwind from "@tailwindcss/vite"; const { default: tw } = tailwind; export default { plugins: [tw({ optimize: false })] }. prepareTailwindPlugin knows the namespace binding, but neither this alias collector nor callee resolution associates tw with tailwind.default, so init appends tailwind.default() and registers Tailwind twice. Please recognize immutable { default: local } aliases here as well.

@ask-bonk

ask-bonk Bot commented Sep 18, 2026

Copy link
Copy Markdown
Contributor

Posted 3 actionable inline findings.

github run

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

init: MDX + Tailwind v4 apps fail on first build (missing @mdx-js/rollup install, postcss string-form Tailwind unresolvable)

2 participants