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