create-lumen 2.0.0-alpha.2 → 2.0.0-beta.1

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.
Files changed (137) hide show
  1. package/README.md +24 -6
  2. package/bin/cli.js +2 -1
  3. package/package.json +2 -2
  4. package/src/cli-args.js +105 -5
  5. package/src/configure.js +8 -4
  6. package/src/dependencies.js +8 -2
  7. package/src/engine/capabilities.js +22 -1
  8. package/src/engine/composition.js +92 -0
  9. package/src/engine/providers/base-provider.js +4 -4
  10. package/src/main.js +33 -10
  11. package/src/manifest/emit.js +1 -1
  12. package/src/prompts.js +154 -23
  13. package/templates/bases/next/app-router/js/.provenance.json +19 -0
  14. package/templates/bases/next/app-router/js/README.md +36 -0
  15. package/templates/bases/next/app-router/js/jsconfig.json +7 -0
  16. package/templates/bases/next/app-router/js/next.config.mjs +6 -0
  17. package/templates/bases/next/app-router/js/package.json +15 -0
  18. package/templates/bases/next/app-router/js/public/file.svg +1 -0
  19. package/templates/bases/next/app-router/js/public/globe.svg +1 -0
  20. package/templates/bases/next/app-router/js/public/next.svg +1 -0
  21. package/templates/bases/next/app-router/js/public/vercel.svg +1 -0
  22. package/templates/bases/next/app-router/js/public/window.svg +1 -0
  23. package/templates/bases/next/app-router/js/src/app/api/hello/route.js +5 -0
  24. package/templates/bases/next/app-router/js/src/app/blog/[slug]/page.js +33 -0
  25. package/templates/bases/next/app-router/js/src/app/favicon.ico +0 -0
  26. package/templates/bases/next/app-router/js/src/app/globals.css +49 -0
  27. package/templates/bases/next/app-router/js/src/app/layout.js +25 -0
  28. package/templates/bases/next/app-router/js/src/app/loading.js +15 -0
  29. package/templates/bases/next/app-router/js/src/app/not-found.js +29 -0
  30. package/templates/bases/next/app-router/js/src/app/page.js +69 -0
  31. package/templates/bases/next/app-router/js/src/app/page.module.css +150 -0
  32. package/templates/bases/next/app-router/ts/.provenance.json +19 -0
  33. package/templates/bases/next/app-router/ts/README.md +36 -0
  34. package/templates/bases/next/app-router/ts/next.config.ts +7 -0
  35. package/templates/bases/next/app-router/ts/package.json +21 -0
  36. package/templates/bases/next/app-router/ts/public/file.svg +1 -0
  37. package/templates/bases/next/app-router/ts/public/globe.svg +1 -0
  38. package/templates/bases/next/app-router/ts/public/next.svg +1 -0
  39. package/templates/bases/next/app-router/ts/public/vercel.svg +1 -0
  40. package/templates/bases/next/app-router/ts/public/window.svg +1 -0
  41. package/templates/bases/next/app-router/ts/src/app/api/hello/route.ts +5 -0
  42. package/templates/bases/next/app-router/ts/src/app/blog/[slug]/page.tsx +38 -0
  43. package/templates/bases/next/app-router/ts/src/app/favicon.ico +0 -0
  44. package/templates/bases/next/app-router/ts/src/app/globals.css +49 -0
  45. package/templates/bases/next/app-router/ts/src/app/layout.tsx +30 -0
  46. package/templates/bases/next/app-router/ts/src/app/loading.tsx +15 -0
  47. package/templates/bases/next/app-router/ts/src/app/not-found.tsx +29 -0
  48. package/templates/bases/next/app-router/ts/src/app/page.module.css +150 -0
  49. package/templates/bases/next/app-router/ts/src/app/page.tsx +69 -0
  50. package/templates/bases/next/app-router/ts/tsconfig.json +34 -0
  51. package/templates/bases/next/pages-router/js/.provenance.json +19 -0
  52. package/templates/bases/next/pages-router/js/README.md +40 -0
  53. package/templates/bases/next/pages-router/js/jsconfig.json +7 -0
  54. package/templates/bases/next/pages-router/js/next.config.mjs +7 -0
  55. package/templates/bases/next/pages-router/js/package.json +15 -0
  56. package/templates/bases/next/pages-router/js/public/favicon.ico +0 -0
  57. package/templates/bases/next/pages-router/js/public/file.svg +1 -0
  58. package/templates/bases/next/pages-router/js/public/globe.svg +1 -0
  59. package/templates/bases/next/pages-router/js/public/next.svg +1 -0
  60. package/templates/bases/next/pages-router/js/public/vercel.svg +1 -0
  61. package/templates/bases/next/pages-router/js/public/window.svg +1 -0
  62. package/templates/bases/next/pages-router/js/src/pages/404.js +35 -0
  63. package/templates/bases/next/pages-router/js/src/pages/500.js +35 -0
  64. package/templates/bases/next/pages-router/js/src/pages/_app.js +20 -0
  65. package/templates/bases/next/pages-router/js/src/pages/_document.js +15 -0
  66. package/templates/bases/next/pages-router/js/src/pages/api/hello.js +5 -0
  67. package/templates/bases/next/pages-router/js/src/pages/blog/[slug].js +41 -0
  68. package/templates/bases/next/pages-router/js/src/pages/index.js +77 -0
  69. package/templates/bases/next/pages-router/js/src/styles/Home.module.css +149 -0
  70. package/templates/bases/next/pages-router/js/src/styles/globals.css +42 -0
  71. package/templates/bases/next/pages-router/ts/.provenance.json +19 -0
  72. package/templates/bases/next/pages-router/ts/README.md +40 -0
  73. package/templates/bases/next/pages-router/ts/next.config.ts +8 -0
  74. package/templates/bases/next/pages-router/ts/package.json +21 -0
  75. package/templates/bases/next/pages-router/ts/public/favicon.ico +0 -0
  76. package/templates/bases/next/pages-router/ts/public/file.svg +1 -0
  77. package/templates/bases/next/pages-router/ts/public/globe.svg +1 -0
  78. package/templates/bases/next/pages-router/ts/public/next.svg +1 -0
  79. package/templates/bases/next/pages-router/ts/public/vercel.svg +1 -0
  80. package/templates/bases/next/pages-router/ts/public/window.svg +1 -0
  81. package/templates/bases/next/pages-router/ts/src/pages/404.tsx +35 -0
  82. package/templates/bases/next/pages-router/ts/src/pages/500.tsx +35 -0
  83. package/templates/bases/next/pages-router/ts/src/pages/_app.tsx +21 -0
  84. package/templates/bases/next/pages-router/ts/src/pages/_document.tsx +15 -0
  85. package/templates/bases/next/pages-router/ts/src/pages/api/hello.ts +13 -0
  86. package/templates/bases/next/pages-router/ts/src/pages/blog/[slug].tsx +46 -0
  87. package/templates/bases/next/pages-router/ts/src/pages/index.tsx +77 -0
  88. package/templates/bases/next/pages-router/ts/src/styles/Home.module.css +149 -0
  89. package/templates/bases/next/pages-router/ts/src/styles/globals.css +42 -0
  90. package/templates/bases/next/pages-router/ts/tsconfig.json +29 -0
  91. package/templates/conditional/linting/biome/biome.json +31 -0
  92. package/templates/conditional/next/config/cloudflare/next.config.mjs +6 -0
  93. package/templates/conditional/next/config/cloudflare/next.config.ts +7 -0
  94. package/templates/conditional/next/config/node/next.config.mjs +6 -0
  95. package/templates/conditional/next/config/node/next.config.ts +7 -0
  96. package/templates/conditional/next/config/static/next.config.mjs +6 -0
  97. package/templates/conditional/next/config/static/next.config.ts +7 -0
  98. package/templates/conditional/next/config/turbopack/next.config.mjs +7 -0
  99. package/templates/conditional/next/config/turbopack/next.config.ts +8 -0
  100. package/templates/conditional/next/config/vercel/next.config.mjs +6 -0
  101. package/templates/conditional/next/config/vercel/next.config.ts +7 -0
  102. package/templates/conditional/next/config/webpack/next.config.mjs +9 -0
  103. package/templates/conditional/next/config/webpack/next.config.ts +10 -0
  104. package/templates/conditional/next/font/BUILD_SIZE_NOTE.md +17 -0
  105. package/templates/conditional/next/font/app-router/src/app/layout.js +25 -0
  106. package/templates/conditional/next/font/app-router/src/app/layout.tsx +30 -0
  107. package/templates/conditional/next/font/pages-router/src/pages/_app.js +20 -0
  108. package/templates/conditional/next/font/pages-router/src/pages/_app.tsx +21 -0
  109. package/templates/conditional/next/font/pages-router/src/pages/_document.js +18 -0
  110. package/templates/conditional/next/font/pages-router/src/pages/_document.tsx +18 -0
  111. package/templates/conditional/next/font/src/app/layout.js +25 -0
  112. package/templates/conditional/next/font/src/app/layout.tsx +30 -0
  113. package/templates/conditional/next/font/src/lib/fonts.js +11 -0
  114. package/templates/conditional/next/font/src/lib/fonts.ts +11 -0
  115. package/templates/conditional/next/font/src/pages/_app.js +20 -0
  116. package/templates/conditional/next/font/src/pages/_app.tsx +21 -0
  117. package/templates/conditional/next/font/src/pages/_document.js +18 -0
  118. package/templates/conditional/next/font/src/pages/_document.tsx +18 -0
  119. package/templates/conditional/next/image/BUILD_SIZE_NOTE.md +15 -0
  120. package/templates/conditional/next/image/app-router/src/components/ImageExample.jsx +34 -0
  121. package/templates/conditional/next/image/app-router/src/components/ImageExample.tsx +44 -0
  122. package/templates/conditional/next/image/pages-router/src/components/ImageExample.jsx +34 -0
  123. package/templates/conditional/next/image/pages-router/src/components/ImageExample.tsx +44 -0
  124. package/templates/conditional/next/image/src/components/ImageExample.jsx +44 -0
  125. package/templates/conditional/next/image/src/components/ImageExample.tsx +54 -0
  126. package/templates/conditional/next/image/src/components/image/index.js +1 -0
  127. package/templates/conditional/next/image/src/components/image/index.ts +2 -0
  128. package/templates/conditional/next/server-components/README.md +13 -0
  129. package/templates/conditional/next/server-components/eslint.config.mjs +47 -0
  130. package/templates/conditional/next/server-components/rules/no-server-imports-in-client.js +89 -0
  131. package/templates/conditional/next/server-components/rules/no-server-imports-in-client.mjs +88 -0
  132. package/templates/conditional/next/server-components/src/components/boundaries/ClientCounter.jsx +48 -0
  133. package/templates/conditional/next/server-components/src/components/boundaries/ClientCounter.tsx +53 -0
  134. package/templates/conditional/next/server-components/src/components/boundaries/ServerCard.jsx +41 -0
  135. package/templates/conditional/next/server-components/src/components/boundaries/ServerCard.tsx +46 -0
  136. package/templates/conditional/next/server-components/src/components/boundaries/index.js +2 -0
  137. package/templates/conditional/next/server-components/src/components/boundaries/index.ts +4 -0
@@ -0,0 +1,35 @@
1
+ import Head from "next/head";
2
+ import Link from "next/link";
3
+
4
+ export default function Custom404() {
5
+ return (
6
+ <>
7
+ <Head>
8
+ <title>404 - Page Not Found</title>
9
+ </Head>
10
+ <div
11
+ style={{
12
+ display: "flex",
13
+ flexDirection: "column",
14
+ alignItems: "center",
15
+ justifyContent: "center",
16
+ minHeight: "100vh",
17
+ fontFamily: "var(--font-geist-sans, sans-serif)",
18
+ padding: "2rem",
19
+ textAlign: "center",
20
+ }}
21
+ >
22
+ <h1>404 - Page Not Found</h1>
23
+ <p style={{ marginTop: "1rem" }}>
24
+ The page you are looking for does not exist.
25
+ </p>
26
+ <Link
27
+ href="/"
28
+ style={{ marginTop: "1.5rem", textDecoration: "underline" }}
29
+ >
30
+ Go back home
31
+ </Link>
32
+ </div>
33
+ </>
34
+ );
35
+ }
@@ -0,0 +1,35 @@
1
+ import Head from "next/head";
2
+ import Link from "next/link";
3
+
4
+ export default function Custom500() {
5
+ return (
6
+ <>
7
+ <Head>
8
+ <title>500 - Server Error</title>
9
+ </Head>
10
+ <div
11
+ style={{
12
+ display: "flex",
13
+ flexDirection: "column",
14
+ alignItems: "center",
15
+ justifyContent: "center",
16
+ minHeight: "100vh",
17
+ fontFamily: "var(--font-geist-sans, sans-serif)",
18
+ padding: "2rem",
19
+ textAlign: "center",
20
+ }}
21
+ >
22
+ <h1>500 - Server-side error occurred</h1>
23
+ <p style={{ marginTop: "1rem" }}>
24
+ Something went wrong on our end.
25
+ </p>
26
+ <Link
27
+ href="/"
28
+ style={{ marginTop: "1.5rem", textDecoration: "underline" }}
29
+ >
30
+ Go back home
31
+ </Link>
32
+ </div>
33
+ </>
34
+ );
35
+ }
@@ -0,0 +1,21 @@
1
+ import "@/styles/globals.css";
2
+ import type { AppProps } from "next/app";
3
+ import { Geist, Geist_Mono } from "next/font/google";
4
+
5
+ const geistSans = Geist({
6
+ variable: "--font-geist-sans",
7
+ subsets: ["latin"],
8
+ });
9
+
10
+ const geistMono = Geist_Mono({
11
+ variable: "--font-geist-mono",
12
+ subsets: ["latin"],
13
+ });
14
+
15
+ export default function App({ Component, pageProps }: AppProps) {
16
+ return (
17
+ <div className={`${geistSans.variable} ${geistMono.variable}`}>
18
+ <Component {...pageProps} />
19
+ </div>
20
+ );
21
+ }
@@ -0,0 +1,15 @@
1
+ import { Html, Head, Main, NextScript } from "next/document";
2
+
3
+ export default function Document() {
4
+ return (
5
+ <Html lang="en">
6
+ <Head>
7
+ <link rel="icon" href="/favicon.ico" />
8
+ </Head>
9
+ <body>
10
+ <Main />
11
+ <NextScript />
12
+ </body>
13
+ </Html>
14
+ );
15
+ }
@@ -0,0 +1,13 @@
1
+ // Next.js API route support: https://nextjs.org/docs/api-routes/introduction
2
+ import type { NextApiRequest, NextApiResponse } from "next";
3
+
4
+ type Data = {
5
+ hello: string;
6
+ };
7
+
8
+ export default function handler(
9
+ req: NextApiRequest,
10
+ res: NextApiResponse<Data>,
11
+ ) {
12
+ res.status(200).json({ hello: "lumen" });
13
+ }
@@ -0,0 +1,46 @@
1
+ import type { GetServerSideProps, InferGetServerSidePropsType } from "next";
2
+ import Head from "next/head";
3
+ import Link from "next/link";
4
+ import { useRouter } from "next/router";
5
+
6
+ export const getServerSideProps: GetServerSideProps<{ slug: string }> = async (
7
+ context,
8
+ ) => {
9
+ const slug = (context.params?.slug as string) || "";
10
+ return {
11
+ props: {
12
+ slug,
13
+ },
14
+ };
15
+ };
16
+
17
+ export default function BlogPost({
18
+ slug,
19
+ }: InferGetServerSidePropsType<typeof getServerSideProps>) {
20
+ const router = useRouter();
21
+ const displaySlug = slug || (router.query.slug as string) || "";
22
+
23
+ return (
24
+ <>
25
+ <Head>
26
+ <title>{displaySlug}</title>
27
+ </Head>
28
+ <main
29
+ style={{
30
+ padding: "2rem",
31
+ fontFamily: "var(--font-geist-sans, sans-serif)",
32
+ maxWidth: "800px",
33
+ margin: "0 auto",
34
+ }}
35
+ >
36
+ <h1>{displaySlug}</h1>
37
+ <p style={{ marginTop: "1rem" }}>Post slug: {displaySlug}</p>
38
+ <p style={{ marginTop: "1.5rem" }}>
39
+ <Link href="/" style={{ textDecoration: "underline" }}>
40
+ Back to home
41
+ </Link>
42
+ </p>
43
+ </main>
44
+ </>
45
+ );
46
+ }
@@ -0,0 +1,77 @@
1
+ import Head from "next/head";
2
+ import Image from "next/image";
3
+ import styles from "@/styles/Home.module.css";
4
+
5
+ export default function Home() {
6
+ return (
7
+ <>
8
+ <Head>
9
+ <title>Create Next App</title>
10
+ <meta name="description" content="Generated by create next app" />
11
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
12
+ </Head>
13
+ <div className={styles.page}>
14
+ <main className={styles.main}>
15
+ <Image
16
+ className={styles.logo}
17
+ src="/next.svg"
18
+ alt="Next.js logo"
19
+ width={100}
20
+ height={20}
21
+ priority
22
+ />
23
+ <div className={styles.intro}>
24
+ <h1>
25
+ To get started, edit the{" "}
26
+ <code className={styles.code}>index.tsx</code> file.
27
+ </h1>
28
+ <p>
29
+ Looking for a starting point or more instructions? Head over to{" "}
30
+ <a
31
+ href="https://vercel.com/templates?framework=next.js&utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
32
+ target="_blank"
33
+ rel="noopener noreferrer"
34
+ >
35
+ Templates
36
+ </a>{" "}
37
+ or the{" "}
38
+ <a
39
+ href="https://nextjs.org/learn?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
40
+ target="_blank"
41
+ rel="noopener noreferrer"
42
+ >
43
+ Learning
44
+ </a>{" "}
45
+ center.
46
+ </p>
47
+ </div>
48
+ <div className={styles.ctas}>
49
+ <a
50
+ className={styles.primary}
51
+ href="https://vercel.com/new?utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
52
+ target="_blank"
53
+ rel="noopener noreferrer"
54
+ >
55
+ <Image
56
+ className={styles.logo}
57
+ src="/vercel.svg"
58
+ alt="Vercel logomark"
59
+ width={16}
60
+ height={14}
61
+ />
62
+ Deploy Now
63
+ </a>
64
+ <a
65
+ className={styles.secondary}
66
+ href="https://nextjs.org/docs?utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
67
+ target="_blank"
68
+ rel="noopener noreferrer"
69
+ >
70
+ Documentation
71
+ </a>
72
+ </div>
73
+ </main>
74
+ </div>
75
+ </>
76
+ );
77
+ }
@@ -0,0 +1,149 @@
1
+ .page {
2
+ --background: #fafafa;
3
+ --foreground: #fff;
4
+
5
+ --text-primary: #000;
6
+ --text-secondary: #666;
7
+
8
+ --button-primary-hover: #383838;
9
+ --button-secondary-hover: #f2f2f2;
10
+ --button-secondary-border: #ebebeb;
11
+
12
+ display: flex;
13
+ min-height: 100vh;
14
+ align-items: center;
15
+ justify-content: center;
16
+ font-family: var(--font-geist-sans);
17
+ background-color: var(--background);
18
+ }
19
+
20
+ .main {
21
+ display: flex;
22
+ min-height: 100vh;
23
+ width: 100%;
24
+ max-width: 800px;
25
+ flex-direction: column;
26
+ align-items: flex-start;
27
+ justify-content: space-between;
28
+ background-color: var(--foreground);
29
+ padding: 120px 60px;
30
+ }
31
+
32
+ .intro {
33
+ display: flex;
34
+ flex-direction: column;
35
+ align-items: flex-start;
36
+ text-align: left;
37
+ gap: 24px;
38
+ }
39
+
40
+ .intro h1 {
41
+ max-width: 320px;
42
+ font-size: 40px;
43
+ font-weight: 600;
44
+ line-height: 48px;
45
+ letter-spacing: -2.4px;
46
+ text-wrap: balance;
47
+ color: var(--text-primary);
48
+ }
49
+
50
+ .intro p {
51
+ max-width: 440px;
52
+ font-size: 18px;
53
+ line-height: 32px;
54
+ text-wrap: balance;
55
+ color: var(--text-secondary);
56
+ }
57
+
58
+ .intro a {
59
+ font-weight: 500;
60
+ color: var(--text-primary);
61
+ }
62
+
63
+ .ctas {
64
+ display: flex;
65
+ flex-direction: row;
66
+ width: 100%;
67
+ max-width: 440px;
68
+ gap: 16px;
69
+ font-size: 14px;
70
+ }
71
+
72
+ .ctas a {
73
+ display: flex;
74
+ justify-content: center;
75
+ align-items: center;
76
+ height: 40px;
77
+ padding: 0 16px;
78
+ border-radius: 128px;
79
+ border: 1px solid transparent;
80
+ transition: 0.2s;
81
+ cursor: pointer;
82
+ width: fit-content;
83
+ font-weight: 500;
84
+ }
85
+
86
+ a.primary {
87
+ background: var(--text-primary);
88
+ color: var(--background);
89
+ gap: 8px;
90
+ }
91
+
92
+ a.secondary {
93
+ border-color: var(--button-secondary-border);
94
+ }
95
+
96
+ /* Enable hover only on non-touch devices */
97
+ @media (hover: hover) and (pointer: fine) {
98
+ a.primary:hover {
99
+ background: var(--button-primary-hover);
100
+ border-color: transparent;
101
+ }
102
+
103
+ a.secondary:hover {
104
+ background: var(--button-secondary-hover);
105
+ border-color: transparent;
106
+ }
107
+ }
108
+
109
+ @media (max-width: 600px) {
110
+ .main {
111
+ padding: 48px 24px;
112
+ }
113
+
114
+ .intro {
115
+ gap: 16px;
116
+ }
117
+
118
+ .intro h1 {
119
+ font-size: 32px;
120
+ line-height: 40px;
121
+ letter-spacing: -1.92px;
122
+ }
123
+ }
124
+
125
+ @media (prefers-color-scheme: dark) {
126
+ .logo {
127
+ filter: invert();
128
+ }
129
+
130
+ .page {
131
+ --background: #000;
132
+ --foreground: #000;
133
+
134
+ --text-primary: #ededed;
135
+ --text-secondary: #999;
136
+
137
+ --button-primary-hover: #ccc;
138
+ --button-secondary-hover: #1a1a1a;
139
+ --button-secondary-border: #1a1a1a;
140
+ }
141
+ }
142
+
143
+ .code {
144
+ font-family: var(--font-geist-mono);
145
+ font-size: 0.9em;
146
+ background: color-mix(in srgb, currentColor 8%, transparent);
147
+ padding: 0.1em 0.4em;
148
+ border-radius: 6px;
149
+ }
@@ -0,0 +1,42 @@
1
+ :root {
2
+ --background: #ffffff;
3
+ --foreground: #171717;
4
+ }
5
+
6
+ @media (prefers-color-scheme: dark) {
7
+ :root {
8
+ --background: #0a0a0a;
9
+ --foreground: #ededed;
10
+ }
11
+ }
12
+
13
+ html,
14
+ body {
15
+ max-width: 100vw;
16
+ overflow-x: hidden;
17
+ }
18
+
19
+ body {
20
+ color: var(--foreground);
21
+ background: var(--background);
22
+ font-family: Arial, Helvetica, sans-serif;
23
+ -webkit-font-smoothing: antialiased;
24
+ -moz-osx-font-smoothing: grayscale;
25
+ }
26
+
27
+ * {
28
+ box-sizing: border-box;
29
+ padding: 0;
30
+ margin: 0;
31
+ }
32
+
33
+ a {
34
+ color: inherit;
35
+ text-decoration: none;
36
+ }
37
+
38
+ @media (prefers-color-scheme: dark) {
39
+ html {
40
+ color-scheme: dark;
41
+ }
42
+ }
@@ -0,0 +1,29 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2017",
4
+ "lib": ["dom", "dom.iterable", "esnext"],
5
+ "allowJs": true,
6
+ "skipLibCheck": true,
7
+ "strict": true,
8
+ "noEmit": true,
9
+ "esModuleInterop": true,
10
+ "module": "esnext",
11
+ "moduleResolution": "bundler",
12
+ "resolveJsonModule": true,
13
+ "isolatedModules": true,
14
+ "jsx": "react-jsx",
15
+ "incremental": true,
16
+ "paths": {
17
+ "@/*": ["./src/*"]
18
+ }
19
+ },
20
+ "include": [
21
+ "next-env.d.ts",
22
+ "**/*.ts",
23
+ "**/*.tsx",
24
+ ".next/types/**/*.ts",
25
+ ".next/dev/types/**/*.ts",
26
+ "**/*.mts"
27
+ ],
28
+ "exclude": ["node_modules"]
29
+ }
@@ -0,0 +1,31 @@
1
+ {
2
+ "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
3
+ "vcs": {
4
+ "enabled": false,
5
+ "clientKind": "git",
6
+ "useIgnoreFile": true
7
+ },
8
+ "files": {
9
+ "ignoreUnknown": false,
10
+ "ignore": []
11
+ },
12
+ "formatter": {
13
+ "enabled": true,
14
+ "indentStyle": "space",
15
+ "indentWidth": 2
16
+ },
17
+ "organizeImports": {
18
+ "enabled": true
19
+ },
20
+ "linter": {
21
+ "enabled": true,
22
+ "rules": {
23
+ "recommended": true
24
+ }
25
+ },
26
+ "javascript": {
27
+ "formatter": {
28
+ "quoteStyle": "double"
29
+ }
30
+ }
31
+ }
@@ -0,0 +1,6 @@
1
+ /** @type {import('next').NextConfig} */
2
+ const nextConfig = {
3
+ /* Cloudflare deployment adapter configuration */
4
+ };
5
+
6
+ export default nextConfig;
@@ -0,0 +1,7 @@
1
+ import type { NextConfig } from "next";
2
+
3
+ const nextConfig: NextConfig = {
4
+ /* Cloudflare deployment adapter configuration */
5
+ };
6
+
7
+ export default nextConfig;
@@ -0,0 +1,6 @@
1
+ /** @type {import('next').NextConfig} */
2
+ const nextConfig = {
3
+ output: "standalone",
4
+ };
5
+
6
+ export default nextConfig;
@@ -0,0 +1,7 @@
1
+ import type { NextConfig } from "next";
2
+
3
+ const nextConfig: NextConfig = {
4
+ output: "standalone",
5
+ };
6
+
7
+ export default nextConfig;
@@ -0,0 +1,6 @@
1
+ /** @type {import('next').NextConfig} */
2
+ const nextConfig = {
3
+ output: "export",
4
+ };
5
+
6
+ export default nextConfig;
@@ -0,0 +1,7 @@
1
+ import type { NextConfig } from "next";
2
+
3
+ const nextConfig: NextConfig = {
4
+ output: "export",
5
+ };
6
+
7
+ export default nextConfig;
@@ -0,0 +1,7 @@
1
+ /** @type {import('next').NextConfig} */
2
+ const nextConfig = {
3
+ /* Turbopack configuration */
4
+ turbopack: {},
5
+ };
6
+
7
+ export default nextConfig;
@@ -0,0 +1,8 @@
1
+ import type { NextConfig } from "next";
2
+
3
+ const nextConfig: NextConfig = {
4
+ /* Turbopack configuration */
5
+ turbopack: {},
6
+ };
7
+
8
+ export default nextConfig;
@@ -0,0 +1,6 @@
1
+ /** @type {import('next').NextConfig} */
2
+ const nextConfig = {
3
+ /* Vercel deployment adapter configuration */
4
+ };
5
+
6
+ export default nextConfig;
@@ -0,0 +1,7 @@
1
+ import type { NextConfig } from "next";
2
+
3
+ const nextConfig: NextConfig = {
4
+ /* Vercel deployment adapter configuration */
5
+ };
6
+
7
+ export default nextConfig;
@@ -0,0 +1,9 @@
1
+ /** @type {import('next').NextConfig} */
2
+ const nextConfig = {
3
+ /* Webpack configuration */
4
+ webpack: (config) => {
5
+ return config;
6
+ },
7
+ };
8
+
9
+ export default nextConfig;
@@ -0,0 +1,10 @@
1
+ import type { NextConfig } from "next";
2
+
3
+ const nextConfig: NextConfig = {
4
+ /* Webpack configuration */
5
+ webpack: (config) => {
6
+ return config;
7
+ },
8
+ };
9
+
10
+ export default nextConfig;
@@ -0,0 +1,17 @@
1
+ # next/font Build Size and Performance Impact
2
+
3
+ ## Zero Layout Shift & Self-Hosting
4
+ `next/font` (specifically `Geist` and `Geist_Mono` via `next/font/google`) automatically optimizes font loading:
5
+ 1. **Self-Hosting at Build Time**: Google Fonts are downloaded during `next build` and hosted alongside your static assets directly from the same domain. No external requests are made to Google Fonts servers by the browser at runtime, improving privacy and removing DNS/TLS negotiation latency.
6
+ 2. **Zero Cumulative Layout Shift (CLS)**: Uses CSS `size-adjust` to match fallback fonts automatically while custom fonts are loading.
7
+ 3. **Preloaded Subsets**: Automatically subsets font glyphs (defaulting to `latin`) to reduce file weight.
8
+
9
+ ## Bundle Footprint
10
+ - **Runtime JavaScript**: ~0 bytes (compiled away into CSS variables and HTML classes).
11
+ - **Static Assets**: ~20-30 KB compressed WOFF2 font payload served statically with aggressive caching (`Cache-Control: public, max-age=31536000, immutable`).
12
+ - **HTML/CSS Injection**: Inline CSS variable definitions (`--font-geist-sans`, `--font-geist-mono`) attached to root wrappers, eliminating render-blocking external stylesheet links.
13
+
14
+ ## Parity Across Routers
15
+ - **App Router**: Wired into root `app/layout.tsx` (or `app/layout.js`) via `className={`${geistSans.variable} ${geistMono.variable}`}` on `<html>`.
16
+ - **Pages Router**: Wired into root `pages/_app.tsx` (or `pages/_app.js`) wrapping the page tree with `${geistSans.variable} ${geistMono.variable}`. (Note: Per Next.js compiler specifications, `next/font` is strictly prohibited inside `pages/_document.js` with a compile-time error and must be loaded in `_app.js` or page components).
17
+ - Both routers expose identical CSS custom properties for global and modular CSS styling.
@@ -0,0 +1,25 @@
1
+ import { Geist, Geist_Mono } from "next/font/google";
2
+ import "./globals.css";
3
+
4
+ const geistSans = Geist({
5
+ variable: "--font-geist-sans",
6
+ subsets: ["latin"],
7
+ });
8
+
9
+ const geistMono = Geist_Mono({
10
+ variable: "--font-geist-mono",
11
+ subsets: ["latin"],
12
+ });
13
+
14
+ export const metadata = {
15
+ title: "Create Lumen App",
16
+ description: "Generated by create-lumen",
17
+ };
18
+
19
+ export default function RootLayout({ children }) {
20
+ return (
21
+ <html lang="en" className={`${geistSans.variable} ${geistMono.variable}`}>
22
+ <body className="antialiased">{children}</body>
23
+ </html>
24
+ );
25
+ }
@@ -0,0 +1,30 @@
1
+ import type { Metadata } from "next";
2
+ import { Geist, Geist_Mono } from "next/font/google";
3
+ import "./globals.css";
4
+
5
+ const geistSans = Geist({
6
+ variable: "--font-geist-sans",
7
+ subsets: ["latin"],
8
+ });
9
+
10
+ const geistMono = Geist_Mono({
11
+ variable: "--font-geist-mono",
12
+ subsets: ["latin"],
13
+ });
14
+
15
+ export const metadata: Metadata = {
16
+ title: "Create Lumen App",
17
+ description: "Generated by create-lumen",
18
+ };
19
+
20
+ export default function RootLayout({
21
+ children,
22
+ }: Readonly<{
23
+ children: React.ReactNode;
24
+ }>) {
25
+ return (
26
+ <html lang="en" className={`${geistSans.variable} ${geistMono.variable}`}>
27
+ <body className="antialiased">{children}</body>
28
+ </html>
29
+ );
30
+ }