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

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 (174) hide show
  1. package/README.md +24 -6
  2. package/bin/cli.js +2 -1
  3. package/package.json +2 -2
  4. package/schema/lumen.config.v2.json +29 -0
  5. package/src/agent-context.js +71 -47
  6. package/src/cleanup.js +19 -1
  7. package/src/cli-args.js +131 -5
  8. package/src/configure.js +8 -4
  9. package/src/dependencies.js +46 -13
  10. package/src/engine/capabilities.js +71 -1
  11. package/src/engine/composition.js +334 -17
  12. package/src/engine/providers/base-provider.js +4 -4
  13. package/src/env.js +24 -6
  14. package/src/main.js +38 -15
  15. package/src/manifest/emit.js +14 -1
  16. package/src/manifest/schema.js +30 -0
  17. package/src/prompts.js +227 -23
  18. package/templates/bases/next/app-router/js/.provenance.json +19 -0
  19. package/templates/bases/next/app-router/js/README.md +36 -0
  20. package/templates/bases/next/app-router/js/jsconfig.json +7 -0
  21. package/templates/bases/next/app-router/js/next.config.mjs +6 -0
  22. package/templates/bases/next/app-router/js/package.json +15 -0
  23. package/templates/bases/next/app-router/js/public/file.svg +1 -0
  24. package/templates/bases/next/app-router/js/public/globe.svg +1 -0
  25. package/templates/bases/next/app-router/js/public/next.svg +1 -0
  26. package/templates/bases/next/app-router/js/public/vercel.svg +1 -0
  27. package/templates/bases/next/app-router/js/public/window.svg +1 -0
  28. package/templates/bases/next/app-router/js/src/app/api/hello/route.js +5 -0
  29. package/templates/bases/next/app-router/js/src/app/blog/[slug]/page.js +33 -0
  30. package/templates/bases/next/app-router/js/src/app/favicon.ico +0 -0
  31. package/templates/bases/next/app-router/js/src/app/globals.css +49 -0
  32. package/templates/bases/next/app-router/js/src/app/layout.js +25 -0
  33. package/templates/bases/next/app-router/js/src/app/loading.js +15 -0
  34. package/templates/bases/next/app-router/js/src/app/not-found.js +29 -0
  35. package/templates/bases/next/app-router/js/src/app/page.js +69 -0
  36. package/templates/bases/next/app-router/js/src/app/page.module.css +150 -0
  37. package/templates/bases/next/app-router/ts/.provenance.json +19 -0
  38. package/templates/bases/next/app-router/ts/README.md +36 -0
  39. package/templates/bases/next/app-router/ts/next.config.ts +7 -0
  40. package/templates/bases/next/app-router/ts/package.json +21 -0
  41. package/templates/bases/next/app-router/ts/public/file.svg +1 -0
  42. package/templates/bases/next/app-router/ts/public/globe.svg +1 -0
  43. package/templates/bases/next/app-router/ts/public/next.svg +1 -0
  44. package/templates/bases/next/app-router/ts/public/vercel.svg +1 -0
  45. package/templates/bases/next/app-router/ts/public/window.svg +1 -0
  46. package/templates/bases/next/app-router/ts/src/app/api/hello/route.ts +5 -0
  47. package/templates/bases/next/app-router/ts/src/app/blog/[slug]/page.tsx +38 -0
  48. package/templates/bases/next/app-router/ts/src/app/favicon.ico +0 -0
  49. package/templates/bases/next/app-router/ts/src/app/globals.css +49 -0
  50. package/templates/bases/next/app-router/ts/src/app/layout.tsx +30 -0
  51. package/templates/bases/next/app-router/ts/src/app/loading.tsx +15 -0
  52. package/templates/bases/next/app-router/ts/src/app/not-found.tsx +29 -0
  53. package/templates/bases/next/app-router/ts/src/app/page.module.css +150 -0
  54. package/templates/bases/next/app-router/ts/src/app/page.tsx +69 -0
  55. package/templates/bases/next/app-router/ts/tsconfig.json +34 -0
  56. package/templates/bases/next/pages-router/js/.provenance.json +19 -0
  57. package/templates/bases/next/pages-router/js/README.md +40 -0
  58. package/templates/bases/next/pages-router/js/jsconfig.json +7 -0
  59. package/templates/bases/next/pages-router/js/next.config.mjs +7 -0
  60. package/templates/bases/next/pages-router/js/package.json +15 -0
  61. package/templates/bases/next/pages-router/js/public/favicon.ico +0 -0
  62. package/templates/bases/next/pages-router/js/public/file.svg +1 -0
  63. package/templates/bases/next/pages-router/js/public/globe.svg +1 -0
  64. package/templates/bases/next/pages-router/js/public/next.svg +1 -0
  65. package/templates/bases/next/pages-router/js/public/vercel.svg +1 -0
  66. package/templates/bases/next/pages-router/js/public/window.svg +1 -0
  67. package/templates/bases/next/pages-router/js/src/pages/404.js +35 -0
  68. package/templates/bases/next/pages-router/js/src/pages/500.js +35 -0
  69. package/templates/bases/next/pages-router/js/src/pages/_app.js +20 -0
  70. package/templates/bases/next/pages-router/js/src/pages/_document.js +15 -0
  71. package/templates/bases/next/pages-router/js/src/pages/api/hello.js +5 -0
  72. package/templates/bases/next/pages-router/js/src/pages/blog/[slug].js +41 -0
  73. package/templates/bases/next/pages-router/js/src/pages/index.js +77 -0
  74. package/templates/bases/next/pages-router/js/src/styles/Home.module.css +149 -0
  75. package/templates/bases/next/pages-router/js/src/styles/globals.css +42 -0
  76. package/templates/bases/next/pages-router/ts/.provenance.json +19 -0
  77. package/templates/bases/next/pages-router/ts/README.md +40 -0
  78. package/templates/bases/next/pages-router/ts/next.config.ts +8 -0
  79. package/templates/bases/next/pages-router/ts/package.json +21 -0
  80. package/templates/bases/next/pages-router/ts/public/favicon.ico +0 -0
  81. package/templates/bases/next/pages-router/ts/public/file.svg +1 -0
  82. package/templates/bases/next/pages-router/ts/public/globe.svg +1 -0
  83. package/templates/bases/next/pages-router/ts/public/next.svg +1 -0
  84. package/templates/bases/next/pages-router/ts/public/vercel.svg +1 -0
  85. package/templates/bases/next/pages-router/ts/public/window.svg +1 -0
  86. package/templates/bases/next/pages-router/ts/src/pages/404.tsx +35 -0
  87. package/templates/bases/next/pages-router/ts/src/pages/500.tsx +35 -0
  88. package/templates/bases/next/pages-router/ts/src/pages/_app.tsx +21 -0
  89. package/templates/bases/next/pages-router/ts/src/pages/_document.tsx +15 -0
  90. package/templates/bases/next/pages-router/ts/src/pages/api/hello.ts +13 -0
  91. package/templates/bases/next/pages-router/ts/src/pages/blog/[slug].tsx +46 -0
  92. package/templates/bases/next/pages-router/ts/src/pages/index.tsx +77 -0
  93. package/templates/bases/next/pages-router/ts/src/styles/Home.module.css +149 -0
  94. package/templates/bases/next/pages-router/ts/src/styles/globals.css +42 -0
  95. package/templates/bases/next/pages-router/ts/tsconfig.json +29 -0
  96. package/templates/conditional/database/prisma/db.js +14 -0
  97. package/templates/conditional/database/prisma/db.ts +16 -0
  98. package/templates/conditional/database/prisma/schema.prisma +9 -0
  99. package/templates/conditional/database/prisma/seed.js +16 -0
  100. package/templates/conditional/database/prisma/seed.ts +16 -0
  101. package/templates/conditional/docker/.dockerignore +10 -0
  102. package/templates/conditional/docker/Dockerfile +57 -0
  103. package/templates/conditional/docker/docker-compose.yml +35 -0
  104. package/templates/conditional/linting/biome/biome.json +31 -0
  105. package/templates/conditional/next/config/cloudflare/next.config.mjs +6 -0
  106. package/templates/conditional/next/config/cloudflare/next.config.ts +7 -0
  107. package/templates/conditional/next/config/node/next.config.mjs +6 -0
  108. package/templates/conditional/next/config/node/next.config.ts +7 -0
  109. package/templates/conditional/next/config/static/next.config.mjs +6 -0
  110. package/templates/conditional/next/config/static/next.config.ts +7 -0
  111. package/templates/conditional/next/config/turbopack/next.config.mjs +7 -0
  112. package/templates/conditional/next/config/turbopack/next.config.ts +8 -0
  113. package/templates/conditional/next/config/vercel/next.config.mjs +6 -0
  114. package/templates/conditional/next/config/vercel/next.config.ts +7 -0
  115. package/templates/conditional/next/config/webpack/next.config.mjs +9 -0
  116. package/templates/conditional/next/config/webpack/next.config.ts +10 -0
  117. package/templates/conditional/next/font/BUILD_SIZE_NOTE.md +17 -0
  118. package/templates/conditional/next/font/app-router/src/app/layout.js +25 -0
  119. package/templates/conditional/next/font/app-router/src/app/layout.tsx +30 -0
  120. package/templates/conditional/next/font/pages-router/src/pages/_app.js +20 -0
  121. package/templates/conditional/next/font/pages-router/src/pages/_app.tsx +21 -0
  122. package/templates/conditional/next/font/pages-router/src/pages/_document.js +18 -0
  123. package/templates/conditional/next/font/pages-router/src/pages/_document.tsx +18 -0
  124. package/templates/conditional/next/font/src/app/layout.js +25 -0
  125. package/templates/conditional/next/font/src/app/layout.tsx +30 -0
  126. package/templates/conditional/next/font/src/lib/fonts.js +11 -0
  127. package/templates/conditional/next/font/src/lib/fonts.ts +11 -0
  128. package/templates/conditional/next/font/src/pages/_app.js +20 -0
  129. package/templates/conditional/next/font/src/pages/_app.tsx +21 -0
  130. package/templates/conditional/next/font/src/pages/_document.js +18 -0
  131. package/templates/conditional/next/font/src/pages/_document.tsx +18 -0
  132. package/templates/conditional/next/image/BUILD_SIZE_NOTE.md +15 -0
  133. package/templates/conditional/next/image/app-router/src/components/ImageExample.jsx +34 -0
  134. package/templates/conditional/next/image/app-router/src/components/ImageExample.tsx +44 -0
  135. package/templates/conditional/next/image/pages-router/src/components/ImageExample.jsx +34 -0
  136. package/templates/conditional/next/image/pages-router/src/components/ImageExample.tsx +44 -0
  137. package/templates/conditional/next/image/src/components/ImageExample.jsx +44 -0
  138. package/templates/conditional/next/image/src/components/ImageExample.tsx +54 -0
  139. package/templates/conditional/next/image/src/components/image/index.js +1 -0
  140. package/templates/conditional/next/image/src/components/image/index.ts +2 -0
  141. package/templates/conditional/next/route-groups/js/src/app/(admin)/layout.jsx +23 -0
  142. package/templates/conditional/next/route-groups/js/src/app/(auth)/layout.jsx +17 -0
  143. package/templates/conditional/next/route-groups/js/src/app/(private)/layout.jsx +27 -0
  144. package/templates/conditional/next/route-groups/js/src/app/(public)/layout.jsx +28 -0
  145. package/templates/conditional/next/route-groups/js/src/app/(public)/page.jsx +38 -0
  146. package/templates/conditional/next/route-groups/js/src/middleware.js +48 -0
  147. package/templates/conditional/next/route-groups/ts/src/app/(admin)/layout.tsx +28 -0
  148. package/templates/conditional/next/route-groups/ts/src/app/(auth)/layout.tsx +22 -0
  149. package/templates/conditional/next/route-groups/ts/src/app/(private)/layout.tsx +32 -0
  150. package/templates/conditional/next/route-groups/ts/src/app/(public)/layout.tsx +33 -0
  151. package/templates/conditional/next/route-groups/ts/src/app/(public)/page.tsx +38 -0
  152. package/templates/conditional/next/route-groups/ts/src/middleware.ts +49 -0
  153. package/templates/conditional/next/server-components/README.md +13 -0
  154. package/templates/conditional/next/server-components/eslint.config.mjs +47 -0
  155. package/templates/conditional/next/server-components/rules/no-server-imports-in-client.js +89 -0
  156. package/templates/conditional/next/server-components/rules/no-server-imports-in-client.mjs +88 -0
  157. package/templates/conditional/next/server-components/src/components/boundaries/ClientCounter.jsx +48 -0
  158. package/templates/conditional/next/server-components/src/components/boundaries/ClientCounter.tsx +53 -0
  159. package/templates/conditional/next/server-components/src/components/boundaries/ServerCard.jsx +41 -0
  160. package/templates/conditional/next/server-components/src/components/boundaries/ServerCard.tsx +46 -0
  161. package/templates/conditional/next/server-components/src/components/boundaries/index.js +2 -0
  162. package/templates/conditional/next/server-components/src/components/boundaries/index.ts +4 -0
  163. package/templates/conditional/testing/jest/next/app-router/src/__tests__/page.test.jsx +10 -0
  164. package/templates/conditional/testing/jest/next/app-router/src/__tests__/page.test.tsx +10 -0
  165. package/templates/conditional/testing/jest/next/jest.config.mjs +20 -0
  166. package/templates/conditional/testing/jest/next/jest.config.ts +20 -0
  167. package/templates/conditional/testing/jest/next/pages-router/src/__tests__/index.test.jsx +10 -0
  168. package/templates/conditional/testing/jest/next/pages-router/src/__tests__/index.test.tsx +10 -0
  169. package/templates/conditional/testing/vitest/next/app-router/src/__tests__/page.test.jsx +11 -0
  170. package/templates/conditional/testing/vitest/next/app-router/src/__tests__/page.test.tsx +11 -0
  171. package/templates/conditional/testing/vitest/next/pages-router/src/__tests__/index.test.jsx +11 -0
  172. package/templates/conditional/testing/vitest/next/pages-router/src/__tests__/index.test.tsx +11 -0
  173. package/templates/conditional/testing/vitest/next/vitest.config.js +16 -0
  174. package/templates/conditional/testing/vitest/next/vitest.config.ts +16 -0
@@ -0,0 +1,57 @@
1
+ FROM node:22-alpine AS base
2
+
3
+ # Install dependencies only when needed
4
+ FROM base AS deps
5
+ # Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
6
+ RUN apk add --no-cache libc6-compat
7
+ WORKDIR /app
8
+
9
+ # Install dependencies based on the preferred package manager
10
+ COPY package.json package-lock.json* yarn.lock* pnpm-lock.yaml* bun.lockb* bun.lock* ./
11
+ RUN \
12
+ if [ -f yarn.lock ]; then yarn --frozen-lockfile; \
13
+ elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm i --frozen-lockfile; \
14
+ elif [ -f package-lock.json ]; then npm ci; \
15
+ elif [ -f bun.lockb ] || [ -f bun.lock ]; then corepack enable bun && bun install --frozen-lockfile; \
16
+ else npm i; \
17
+ fi
18
+
19
+ # Rebuild the source code only when needed
20
+ FROM base AS builder
21
+ WORKDIR /app
22
+ COPY --from=deps /app/node_modules ./node_modules
23
+ COPY . .
24
+
25
+ # Next.js collects completely anonymous telemetry data about general usage.
26
+ # Learn more here: https://nextjs.org/telemetry
27
+ # Uncomment the following line in case you want to disable telemetry during the build.
28
+ ENV NEXT_TELEMETRY_DISABLED=1
29
+
30
+ RUN npm run build
31
+
32
+ # Production image, copy all the files and run next
33
+ FROM base AS runner
34
+ WORKDIR /app
35
+
36
+ ENV NODE_ENV=production
37
+ # Uncomment the following line in case you want to disable telemetry during runtime.
38
+ ENV NEXT_TELEMETRY_DISABLED=1
39
+
40
+ RUN addgroup --system --gid 1001 nodejs
41
+ RUN adduser --system --uid 1001 nextjs
42
+
43
+ COPY --chown=nextjs:nodejs public ./public
44
+
45
+ # Automatically leverage output traces to reduce image size
46
+ # https://nextjs.org/docs/advanced-features/output-file-tracing
47
+ COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
48
+ COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
49
+
50
+ USER nextjs
51
+
52
+ EXPOSE 3000
53
+
54
+ ENV PORT=3000
55
+ ENV HOSTNAME="0.0.0.0"
56
+
57
+ CMD ["node", "server.js"]
@@ -0,0 +1,35 @@
1
+ services:
2
+ app:
3
+ build:
4
+ context: .
5
+ dockerfile: Dockerfile
6
+ restart: always
7
+ ports:
8
+ - "3000:3000"
9
+ environment:
10
+ - NODE_ENV=production
11
+ - PORT=3000
12
+ - DATABASE_URL=postgresql://postgres:postgres@db:5432/app?schema=public
13
+ depends_on:
14
+ db:
15
+ condition: service_healthy
16
+
17
+ db:
18
+ image: postgres:16-alpine
19
+ restart: always
20
+ environment:
21
+ POSTGRES_USER: postgres
22
+ POSTGRES_PASSWORD: postgres
23
+ POSTGRES_DB: app
24
+ ports:
25
+ - "5432:5432"
26
+ volumes:
27
+ - postgres_data:/var/lib/postgresql/data
28
+ healthcheck:
29
+ test: ["CMD-SHELL", "pg_isready -U postgres -d app"]
30
+ interval: 5s
31
+ timeout: 5s
32
+ retries: 5
33
+
34
+ volumes:
35
+ postgres_data:
@@ -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
+ }
@@ -0,0 +1,20 @@
1
+ import "@/styles/globals.css";
2
+ import { Geist, Geist_Mono } from "next/font/google";
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 default function App({ Component, pageProps }) {
15
+ return (
16
+ <div className={`${geistSans.variable} ${geistMono.variable}`}>
17
+ <Component {...pageProps} />
18
+ </div>
19
+ );
20
+ }
@@ -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,18 @@
1
+ import { Html, Head, Main, NextScript } from "next/document";
2
+
3
+ /**
4
+ * Pages Router Custom Document.
5
+ * Note: Per Next.js compiler specifications, next/font loaders are configured
6
+ * in pages/_app to avoid the 'Cannot be used within pages/_document' compile error.
7
+ */
8
+ export default function Document() {
9
+ return (
10
+ <Html lang="en">
11
+ <Head />
12
+ <body className="antialiased">
13
+ <Main />
14
+ <NextScript />
15
+ </body>
16
+ </Html>
17
+ );
18
+ }
@@ -0,0 +1,18 @@
1
+ import { Html, Head, Main, NextScript } from "next/document";
2
+
3
+ /**
4
+ * Pages Router Custom Document.
5
+ * Note: Per Next.js compiler specifications, next/font loaders are configured
6
+ * in pages/_app to avoid the 'Cannot be used within pages/_document' compile error.
7
+ */
8
+ export default function Document() {
9
+ return (
10
+ <Html lang="en">
11
+ <Head />
12
+ <body className="antialiased">
13
+ <Main />
14
+ <NextScript />
15
+ </body>
16
+ </Html>
17
+ );
18
+ }
@@ -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
+ }
@@ -0,0 +1,11 @@
1
+ import { Geist, Geist_Mono } from "next/font/google";
2
+
3
+ export const geistSans = Geist({
4
+ variable: "--font-geist-sans",
5
+ subsets: ["latin"],
6
+ });
7
+
8
+ export const geistMono = Geist_Mono({
9
+ variable: "--font-geist-mono",
10
+ subsets: ["latin"],
11
+ });
@@ -0,0 +1,11 @@
1
+ import { Geist, Geist_Mono } from "next/font/google";
2
+
3
+ export const geistSans = Geist({
4
+ variable: "--font-geist-sans",
5
+ subsets: ["latin"],
6
+ });
7
+
8
+ export const geistMono = Geist_Mono({
9
+ variable: "--font-geist-mono",
10
+ subsets: ["latin"],
11
+ });
@@ -0,0 +1,20 @@
1
+ import "@/styles/globals.css";
2
+ import { Geist, Geist_Mono } from "next/font/google";
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 default function App({ Component, pageProps }) {
15
+ return (
16
+ <div className={`${geistSans.variable} ${geistMono.variable}`}>
17
+ <Component {...pageProps} />
18
+ </div>
19
+ );
20
+ }
@@ -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,18 @@
1
+ import { Html, Head, Main, NextScript } from "next/document";
2
+
3
+ /**
4
+ * Pages Router Custom Document.
5
+ * Note: Per Next.js compiler specifications, next/font loaders are configured
6
+ * in pages/_app to avoid the 'Cannot be used within pages/_document' compile error.
7
+ */
8
+ export default function Document() {
9
+ return (
10
+ <Html lang="en">
11
+ <Head />
12
+ <body className="antialiased">
13
+ <Main />
14
+ <NextScript />
15
+ </body>
16
+ </Html>
17
+ );
18
+ }
@@ -0,0 +1,18 @@
1
+ import { Html, Head, Main, NextScript } from "next/document";
2
+
3
+ /**
4
+ * Pages Router Custom Document.
5
+ * Note: Per Next.js compiler specifications, next/font loaders are configured
6
+ * in pages/_app to avoid the 'Cannot be used within pages/_document' compile error.
7
+ */
8
+ export default function Document() {
9
+ return (
10
+ <Html lang="en">
11
+ <Head />
12
+ <body className="antialiased">
13
+ <Main />
14
+ <NextScript />
15
+ </body>
16
+ </Html>
17
+ );
18
+ }
@@ -0,0 +1,15 @@
1
+ # next/image Build Size and Performance Impact
2
+
3
+ ## Built-In Optimization
4
+ `next/image` extends standard HTML `<img>` elements with automatic visual stability and performance optimizations:
5
+ 1. **Zero Cumulative Layout Shift (CLS)**: Enforces explicit `width` and `height` dimensions or fills the parent container with `fill`, reserving geometric space before the bitmap payload loads.
6
+ 2. **Modern Format Negotiation**: Serves WebP and AVIF modern formats dynamically when supported by the requesting browser, yielding 30–50% bandwidth reduction compared to legacy JPEG/PNG.
7
+ 3. **Native Lazy Loading**: Viewport-aware on-demand loading so off-screen images do not delay initial page interactivity. The `priority` property allows opting into preloading for Largest Contentful Paint (LCP) elements.
8
+
9
+ ## Bundle Footprint
10
+ - **Runtime JavaScript Overhead**: ~5 KB gzipped client-side runtime handling IntersectionObserver and responsive `srcSet` generation.
11
+ - **Build Impact**: Zero additional build time overhead during static compilation when referencing local SVGs or remote URLs; image transformations are handled on-demand by the Next.js server image optimizer.
12
+
13
+ ## Router Parity
14
+ - **App Router**: Fully compatible with both Server Components (static rendering) and Client Components (`"use client"`).
15
+ - **Pages Router**: Fully compatible with all page and component hierarchies.
@@ -0,0 +1,34 @@
1
+ import React from "react";
2
+ import Image from "next/image";
3
+
4
+ export function ImageExample({
5
+ src = "/next.svg",
6
+ alt = "Next.js logo",
7
+ width = 180,
8
+ height = 37,
9
+ priority = false,
10
+ className = "",
11
+ caption = "Optimized with next/image",
12
+ }) {
13
+ return (
14
+ <figure className={`inline-flex flex-col items-center gap-2 p-4 rounded-xl border border-gray-200 dark:border-gray-800 bg-white/50 dark:bg-black/20 ${className}`}>
15
+ <div className="relative flex items-center justify-center p-2">
16
+ <Image
17
+ src={src}
18
+ alt={alt}
19
+ width={width}
20
+ height={height}
21
+ priority={priority}
22
+ className="dark:invert transition-transform hover:scale-105"
23
+ />
24
+ </div>
25
+ {caption && (
26
+ <figcaption className="text-xs text-gray-500 dark:text-gray-400 text-center font-mono">
27
+ {caption}
28
+ </figcaption>
29
+ )}
30
+ </figure>
31
+ );
32
+ }
33
+
34
+ export default ImageExample;
@@ -0,0 +1,44 @@
1
+ import React from "react";
2
+ import Image from "next/image";
3
+
4
+ export interface ImageExampleProps {
5
+ src?: string;
6
+ alt?: string;
7
+ width?: number;
8
+ height?: number;
9
+ priority?: boolean;
10
+ className?: string;
11
+ caption?: string;
12
+ }
13
+
14
+ export function ImageExample({
15
+ src = "/next.svg",
16
+ alt = "Next.js logo",
17
+ width = 180,
18
+ height = 37,
19
+ priority = false,
20
+ className = "",
21
+ caption = "Optimized with next/image",
22
+ }: ImageExampleProps) {
23
+ return (
24
+ <figure className={`inline-flex flex-col items-center gap-2 p-4 rounded-xl border border-gray-200 dark:border-gray-800 bg-white/50 dark:bg-black/20 ${className}`}>
25
+ <div className="relative flex items-center justify-center p-2">
26
+ <Image
27
+ src={src}
28
+ alt={alt}
29
+ width={width}
30
+ height={height}
31
+ priority={priority}
32
+ className="dark:invert transition-transform hover:scale-105"
33
+ />
34
+ </div>
35
+ {caption && (
36
+ <figcaption className="text-xs text-gray-500 dark:text-gray-400 text-center font-mono">
37
+ {caption}
38
+ </figcaption>
39
+ )}
40
+ </figure>
41
+ );
42
+ }
43
+
44
+ export default ImageExample;