Skip to content

Commit c52fde9

Browse files
potetoeps1lon
authored andcommitted
[cna] Add reactCompiler option
This PR adds a new `reactCompiler` option to create-next-app. To provide more time for build perf measurements, this option defaults to "no" for now. When React Compiler is enabled, create-next-app will: 1. Add the experimental config enabling the compiler to next.config 2. Install babel-plugin-react-compiler, pinned to the latest rc 19.1.0-rc.2 Test plan: Double checked that the generated next.config.ts contains the flag and that babel-plugin-react-compiler was installed as a devDep. **OFF** ``` $ pnpm build $ dist/index.js ✔ What is your project named? … my-app ✔ Would you like to use TypeScript? … No / Yes ✔ Would you like to use ESLint? … No / Yes ✔ Would you like to use React Compiler (Release Candidate)? … No / Yes ✔ Would you like to use Tailwind CSS? … No / Yes ✔ Would you like your code inside a `src/` directory? … No / Yes ✔ Would you like to use App Router? (recommended) … No / Yes ✔ Would you like to use Turbopack for `next dev`? … No / Yes ✔ Would you like to customize the import alias (`@/*` by default)? … No / Yes Creating a new Next.js app in /Users/laurentan/code/next.js/packages/create-next-app/my-app. Using npm. Initializing project with template: app-tw Installing dependencies: - react - react-dom - next Installing devDependencies: - typescript - @types/node - @types/react - @types/react-dom - @tailwindcss/postcss - tailwindcss - eslint - eslint-config-next - @eslint/eslintrc <snip> Success! Created my-app at my-app ``` **ON** ``` $ pnpm build $ dist/index.js ✔ What is your project named? … my-app ✔ Would you like to use TypeScript? … No / Yes ✔ Would you like to use ESLint? … No / Yes ✔ Would you like to use React Compiler (Release Candidate)? … No / Yes ✔ Would you like to use Tailwind CSS? … No / Yes ✔ Would you like your code inside a `src/` directory? … No / Yes ✔ Would you like to use App Router? (recommended) … No / Yes ✔ Would you like to use Turbopack for `next dev`? … No / Yes ✔ Would you like to customize the import alias (`@/*` by default)? … No / Yes Creating a new Next.js app in /Users/laurentan/code/next.js/packages/create-next-app/my-app. Using npm. Initializing project with template: app-tw Installing dependencies: - react - react-dom - next Installing devDependencies: - babel-plugin-react-compiler - typescript - @types/node - @types/react - @types/react-dom - @tailwindcss/postcss - tailwindcss - eslint - eslint-config-next - @eslint/eslintrc <snip> Success! Created my-app at my-app ```
1 parent f726582 commit c52fde9

File tree

15 files changed

+98
-0
lines changed

15 files changed

+98
-0
lines changed

packages/create-next-app/create-app.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ export async function createApp({
4242
turbopack,
4343
rspack,
4444
disableGit,
45+
reactCompiler,
4546
}: {
4647
appPath: string
4748
packageManager: PackageManager
@@ -60,6 +61,7 @@ export async function createApp({
6061
turbopack: boolean
6162
rspack: boolean
6263
disableGit?: boolean
64+
reactCompiler: boolean
6365
}): Promise<void> {
6466
let repoInfo: RepoInfo | undefined
6567
const mode: TemplateMode = typescript ? 'ts' : 'js'
@@ -252,6 +254,7 @@ export async function createApp({
252254
skipInstall,
253255
turbopack,
254256
rspack,
257+
reactCompiler,
255258
})
256259
}
257260

packages/create-next-app/index.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ const program = new Command(packageJson.name)
4949
.option('--ts, --typescript', 'Initialize as a TypeScript project. (default)')
5050
.option('--js, --javascript', 'Initialize as a JavaScript project.')
5151
.option('--tailwind', 'Initialize with Tailwind CSS config. (default)')
52+
.option('--react-compiler', 'Initialize with React Compiler enabled.')
5253
.option('--eslint', 'Initialize with ESLint config.')
5354
.option('--biome', 'Initialize with Biome config.')
5455
.option('--app', 'Initialize as an App Router project.')
@@ -239,6 +240,7 @@ async function run(): Promise<void> {
239240
empty: false,
240241
turbopack: true,
241242
disableGit: false,
243+
reactCompiler: false,
242244
}
243245
const getPrefOrDefault = (field: string) =>
244246
preferences[field] ?? defaults[field]
@@ -346,6 +348,30 @@ async function run(): Promise<void> {
346348
preferences.eslint = false
347349
}
348350

351+
if (
352+
!opts.reactCompiler &&
353+
!args.includes('--no-react-compiler') &&
354+
!opts.api
355+
) {
356+
if (skipPrompt) {
357+
opts.reactCompiler = getPrefOrDefault('reactCompiler')
358+
} else {
359+
const styledReactCompiler = blue('React Compiler')
360+
const { reactCompiler } = await prompts({
361+
onState: onPromptState,
362+
type: 'toggle',
363+
name: 'reactCompiler',
364+
// TODO: Remove "Release Candidate" when React Compiler is stable
365+
message: `Would you like to use ${styledReactCompiler} (Release Candidate)?`,
366+
initial: getPrefOrDefault('reactCompiler'),
367+
active: 'Yes',
368+
inactive: 'No',
369+
})
370+
opts.reactCompiler = Boolean(reactCompiler)
371+
preferences.reactCompiler = Boolean(reactCompiler)
372+
}
373+
}
374+
349375
if (!opts.tailwind && !args.includes('--no-tailwind') && !opts.api) {
350376
if (skipPrompt) {
351377
opts.tailwind = getPrefOrDefault('tailwind')
@@ -486,6 +512,7 @@ async function run(): Promise<void> {
486512
turbopack: opts.turbopack,
487513
rspack: opts.rspack,
488514
disableGit: opts.disableGit,
515+
reactCompiler: opts.reactCompiler,
489516
})
490517
} catch (reason) {
491518
if (!(reason instanceof DownloadError)) {
@@ -520,6 +547,7 @@ async function run(): Promise<void> {
520547
turbopack: opts.turbopack,
521548
rspack: opts.rspack,
522549
disableGit: opts.disableGit,
550+
reactCompiler: opts.reactCompiler,
523551
})
524552
}
525553
conf.set('preferences', preferences)

packages/create-next-app/templates/index.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ export const installTemplate = async ({
4747
skipInstall,
4848
turbopack,
4949
rspack,
50+
reactCompiler,
5051
}: InstallTemplateArgs) => {
5152
console.log(bold(`Using ${packageManager}.`));
5253

@@ -96,6 +97,28 @@ export const installTemplate = async ({
9697
);
9798
}
9899

100+
if (reactCompiler) {
101+
const nextConfigFile = path.join(
102+
root,
103+
mode === "js" ? "next.config.mjs" : "next.config.ts",
104+
);
105+
let configContent = await fs.readFile(nextConfigFile, "utf8");
106+
107+
if (mode === "ts") {
108+
configContent = configContent.replace(
109+
"const nextConfig: NextConfig = {\n /* config options here */\n};",
110+
`const nextConfig: NextConfig = {\n reactCompiler: true,\n};`,
111+
);
112+
} else {
113+
configContent = configContent.replace(
114+
"const nextConfig = {};",
115+
`const nextConfig = {\n reactCompiler: true,\n};`,
116+
);
117+
}
118+
119+
await fs.writeFile(nextConfigFile, configContent);
120+
}
121+
99122
const tsconfigFile = path.join(
100123
root,
101124
mode === "js" ? "jsconfig.json" : "tsconfig.json",
@@ -223,6 +246,11 @@ export const installTemplate = async ({
223246
}
224247
}
225248

249+
if (reactCompiler) {
250+
// TODO: Use "^19" when React Compiler is stable
251+
packageJson.devDependencies["babel-plugin-react-compiler"] = "19.1.0-rc.3";
252+
}
253+
226254
/**
227255
* TypeScript projects will have type definitions and other devDependencies.
228256
*/

packages/create-next-app/templates/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,5 @@ export interface InstallTemplateArgs {
3333
skipInstall: boolean;
3434
turbopack: boolean;
3535
rspack: boolean;
36+
reactCompiler: boolean;
3637
}

test/integration/create-next-app/biome-config.test.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ describe('create-next-app Biome configuration', () => {
3131
'--app',
3232
'--no-turbopack',
3333
'--no-import-alias',
34+
'--no-react-compiler',
3435
'--skip-install',
3536
],
3637
nextTgzFilename,
@@ -59,6 +60,7 @@ describe('create-next-app Biome configuration', () => {
5960
'--app',
6061
'--no-turbopack',
6162
'--no-import-alias',
63+
'--no-react-compiler',
6264
],
6365
nextTgzFilename,
6466
{ cwd }
@@ -95,6 +97,7 @@ describe('create-next-app Biome configuration', () => {
9597
'--app',
9698
'--no-turbopack',
9799
'--no-import-alias',
100+
'--no-react-compiler',
98101
],
99102
nextTgzFilename,
100103
{ cwd }
@@ -131,6 +134,7 @@ describe('create-next-app Biome configuration', () => {
131134
'--app',
132135
'--no-turbopack',
133136
'--no-import-alias',
137+
'--no-react-compiler',
134138
],
135139
nextTgzFilename,
136140
{ cwd }
@@ -167,6 +171,7 @@ describe('create-next-app Biome configuration', () => {
167171
'--app',
168172
'--no-turbopack',
169173
'--no-import-alias',
174+
'--no-react-compiler',
170175
],
171176
nextTgzFilename,
172177
{ cwd }

test/integration/create-next-app/eslint-config.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ describe('create-next-app ESLint configuration', () => {
2828
'--eslint',
2929
'--no-tailwind',
3030
'--no-src-dir',
31+
'--no-react-compiler',
3132
'--app',
3233
'--no-turbopack',
3334
'--no-import-alias',
@@ -76,6 +77,7 @@ describe('create-next-app ESLint configuration', () => {
7677
'--eslint',
7778
'--no-tailwind',
7879
'--no-src-dir',
80+
'--no-react-compiler',
7981
'--app',
8082
'--no-turbopack',
8183
'--no-import-alias',

test/integration/create-next-app/index.test.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ describe('create-next-app', () => {
3939
'--no-tailwind',
4040
'--no-src-dir',
4141
'--no-import-alias',
42+
'--no-react-compiler',
4243
...(process.env.NEXT_RSPACK ? ['--rspack'] : []),
4344
],
4445
nextTgzFilename,
@@ -81,6 +82,7 @@ describe('create-next-app', () => {
8182
'--no-tailwind',
8283
'--no-src-dir',
8384
'--no-import-alias',
85+
'--no-react-compiler',
8486
...(process.env.NEXT_RSPACK ? ['--rspack'] : []),
8587
],
8688
nextTgzFilename,
@@ -113,6 +115,7 @@ describe('create-next-app', () => {
113115
'--no-src-dir',
114116
'--no-import-alias',
115117
'--skip-install',
118+
'--no-react-compiler',
116119
...(process.env.NEXT_RSPACK ? ['--rspack'] : []),
117120
],
118121
nextTgzFilename,

test/integration/create-next-app/package-manager/bun.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ describe('create-next-app with package manager bun', () => {
4949
'--no-src-dir',
5050
'--no-tailwind',
5151
'--no-import-alias',
52+
'--no-react-compiler',
5253
],
5354
nextTgzFilename,
5455
{
@@ -78,6 +79,7 @@ describe('create-next-app with package manager bun', () => {
7879
'--no-src-dir',
7980
'--no-tailwind',
8081
'--no-import-alias',
82+
'--no-react-compiler',
8183
],
8284
nextTgzFilename,
8385
{

test/integration/create-next-app/package-manager/npm.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ describe('create-next-app with package manager npm', () => {
3838
'--no-src-dir',
3939
'--no-tailwind',
4040
'--no-import-alias',
41+
'--no-react-compiler',
4142
],
4243
nextTgzFilename,
4344
{
@@ -67,6 +68,7 @@ describe('create-next-app with package manager npm', () => {
6768
'--no-src-dir',
6869
'--no-tailwind',
6970
'--no-import-alias',
71+
'--no-react-compiler',
7072
],
7173
nextTgzFilename,
7274
{

test/integration/create-next-app/package-manager/pnpm.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ describe('create-next-app with package manager pnpm', () => {
3838
'--no-src-dir',
3939
'--no-tailwind',
4040
'--no-import-alias',
41+
'--no-react-compiler',
4142
],
4243
nextTgzFilename,
4344
{
@@ -67,6 +68,7 @@ describe('create-next-app with package manager pnpm', () => {
6768
'--no-src-dir',
6869
'--no-tailwind',
6970
'--no-import-alias',
71+
'--no-react-compiler',
7072
],
7173
nextTgzFilename,
7274
{

0 commit comments

Comments
 (0)