@@ -225,7 +225,8 @@ async function run(): Promise<void> {
225225 * If the user does not provide the necessary flags, prompt them for their
226226 * preferences, unless `--yes` option was specified, or when running in CI.
227227 */
228- const skipPrompt = ciInfo . isCI || opts . yes
228+ let skipPrompt = ciInfo . isCI || opts . yes
229+ let useRecommendedDefaults = false
229230
230231 if ( ! example ) {
231232 const defaults : typeof preferences = {
@@ -242,8 +243,124 @@ async function run(): Promise<void> {
242243 disableGit : false ,
243244 reactCompiler : false ,
244245 }
245- const getPrefOrDefault = ( field : string ) =>
246- preferences [ field ] ?? defaults [ field ]
246+
247+ type DisplayConfigItem = {
248+ key : keyof typeof defaults
249+ values ? : Record < string , string>
250+ }
251+
252+ const displayConfig : DisplayConfigItem [ ] = [
253+ {
254+ key : 'typescript' ,
255+ values : { true : 'TypeScript' , false : 'JavaScript' } ,
256+ } ,
257+ { key : 'linter' , values : { eslint : 'ESLint' , biome : 'Biome' } } ,
258+ { key : 'reactCompiler' , values : { true : 'React Compiler' } } ,
259+ { key : 'tailwind' , values : { true : 'Tailwind CSS' } } ,
260+ { key : 'srcDir' , values : { true : 'src/ dir' } } ,
261+ { key : 'app' , values : { true : 'App Router' , false : 'Pages Router' } } ,
262+ { key : 'turbopack' , values : { true : 'Turbopack' } } ,
263+ ]
264+
265+ // Helper to format settings for display based on displayConfig
266+ const formatSettingsDescription = (
267+ settings : Record < string , boolean | string >
268+ ) => {
269+ const descriptions : string [ ] = [ ]
270+
271+ for ( const config of displayConfig ) {
272+ const value = settings [ config . key ]
273+
274+ if ( config . values ) {
275+ // Look up the display label for this value
276+ const label = config . values [ String ( value ) ]
277+ if ( label ) {
278+ descriptions . push ( label )
279+ }
280+ }
281+ }
282+
283+ return descriptions . join ( ', ' )
284+ }
285+
286+ // Check if we have saved preferences
287+ const hasSavedPreferences = Object . keys ( preferences ) . length > 0
288+
289+ // Check if user provided any configuration flags
290+ // If they did, skip the "recommended defaults" prompt and go straight to
291+ // individual prompts for any missing options
292+ const hasProvidedOptions = process . argv . some ( ( arg ) => arg . startsWith ( '--' ) )
293+
294+ // Only show the "recommended defaults" prompt if:
295+ // - Not in CI and not using --yes flag
296+ // - User hasn't provided any custom options
297+ if ( ! skipPrompt && ! hasProvidedOptions ) {
298+ const choices : Array < {
299+ title : string
300+ value : string
301+ description ?: string
302+ } > = [
303+ {
304+ title : 'Yes, use recommended defaults' ,
305+ value : 'recommended' ,
306+ description : formatSettingsDescription ( defaults ) ,
307+ } ,
308+ {
309+ title : 'No, customize settings' ,
310+ value : 'customize' ,
311+ description : 'Choose your own preferences' ,
312+ } ,
313+ ]
314+
315+ // Add "reuse previous settings" option if we have saved preferences
316+ if ( hasSavedPreferences ) {
317+ const prefDescription = formatSettingsDescription ( preferences )
318+ choices . splice ( 1 , 0 , {
319+ title : 'No, reuse previous settings' ,
320+ value : 'reuse' ,
321+ description : prefDescription ,
322+ } )
323+ }
324+
325+ const { setupChoice } = await prompts (
326+ {
327+ type : 'select' ,
328+ name : 'setupChoice' ,
329+ message : 'Would you like to use the recommended Next.js defaults?' ,
330+ choices,
331+ initial : 0 ,
332+ } ,
333+ {
334+ onCancel : ( ) => {
335+ console . error ( 'Exiting.' )
336+ process . exit ( 1 )
337+ } ,
338+ }
339+ )
340+
341+ if ( setupChoice === 'recommended' ) {
342+ useRecommendedDefaults = true
343+ skipPrompt = true
344+ } else if ( setupChoice === 'reuse' ) {
345+ skipPrompt = true
346+ }
347+ }
348+
349+ // If using recommended defaults, populate preferences with defaults
350+ // This ensures they are saved for reuse next time
351+ if ( useRecommendedDefaults ) {
352+ Object . assign ( preferences , defaults )
353+ }
354+
355+ const getPrefOrDefault = ( field : string ) => {
356+ // If using recommended defaults, always use hardcoded defaults
357+ if ( useRecommendedDefaults ) {
358+ return defaults [ field ]
359+ }
360+
361+ // If not using the recommended template, we prefer saved preferences, otherwise defaults.
362+ return preferences [ field ] ?? defaults [ field ]
363+ }
247364
248365 if ( ! opts . typescript && ! opts . javascript ) {
249366 if ( skipPrompt ) {
0 commit comments