@wular/pnext 0.0.4 → 0.0.7

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 (395) hide show
  1. package/README.md +22 -16
  2. package/bin/pnext +6 -1
  3. package/config/lint/base.js +7 -7
  4. package/config/ts/base.json +2 -4
  5. package/config/ts/react.json +2 -6
  6. package/package.json +23 -2
  7. package/reference/compat.md +87 -22
  8. package/reference/config.md +40 -93
  9. package/reference/css.md +42 -33
  10. package/reference/dev.md +26 -33
  11. package/reference/env.md +18 -20
  12. package/reference/getting-started.md +132 -0
  13. package/reference/metadata.md +31 -46
  14. package/reference/navigation.md +65 -105
  15. package/reference/performance.md +21 -142
  16. package/reference/rendering.md +78 -75
  17. package/reference/routing.md +97 -107
  18. package/reference/typegen.md +27 -29
  19. package/src/api/cache.ts +36 -37
  20. package/src/api/client-cache.ts +2 -2
  21. package/src/api/client-navigation.ts +121 -114
  22. package/src/api/dynamic.tsx +58 -55
  23. package/src/api/link.tsx +52 -53
  24. package/src/api/navigation.ts +59 -58
  25. package/src/api/server.ts +152 -144
  26. package/src/api/suspense.ts +4 -4
  27. package/src/cli/adapters/vercel-warm.ts +126 -121
  28. package/src/cli/adapters/vercel.ts +437 -443
  29. package/src/cli/analyze.ts +333 -144
  30. package/src/cli/{named-bin.ts → boot/named-bin.ts} +37 -37
  31. package/src/cli/{boot-trace.ts → boot/trace.ts} +10 -10
  32. package/src/cli/build.ts +976 -978
  33. package/src/cli/create.ts +72 -64
  34. package/src/cli/dev.ts +116 -116
  35. package/src/cli/index.ts +94 -85
  36. package/src/cli/migrate/package-json.ts +73 -71
  37. package/src/cli/migrate/report.ts +32 -33
  38. package/src/cli/migrate/{index.ts → run.ts} +48 -49
  39. package/src/cli/migrate/scan.ts +46 -46
  40. package/src/cli/migrate/spinner.ts +9 -9
  41. package/src/cli/migrate/tsconfig.ts +35 -35
  42. package/src/cli/{server-entry.ts → serve/entry.ts} +57 -57
  43. package/src/cli/{request-pipeline.ts → serve/pipeline.ts} +386 -394
  44. package/src/cli/{serve-ui.ts → serve/ui.ts} +47 -47
  45. package/src/cli/start.ts +65 -66
  46. package/src/{typegen.ts → cli/typegen.ts} +59 -59
  47. package/src/client/build.ts +802 -768
  48. package/src/client/chunk-fold.ts +245 -240
  49. package/src/client/{paths.ts → chunk-name.ts} +6 -6
  50. package/src/client/entry.ts +162 -147
  51. package/src/client/prebuilt.ts +231 -223
  52. package/src/client/profile.ts +29 -29
  53. package/src/client/react-compiler.ts +20 -15
  54. package/src/client/{compat-surface.ts → react-tier.ts} +64 -64
  55. package/src/client/reference-stub.ts +51 -51
  56. package/src/client/reference.ts +19 -19
  57. package/src/{api → client}/router/events.ts +32 -17
  58. package/src/{api → client}/router/history.ts +16 -16
  59. package/src/{api → client}/router/hub.ts +52 -53
  60. package/src/{api/router.ts → client/router/index.ts} +61 -60
  61. package/src/{api → client}/router/policies.ts +24 -24
  62. package/src/{api → client}/router/runtime.ts +2022 -1995
  63. package/src/{api → client}/router/types.ts +98 -98
  64. package/src/compat/actions/client-plugin.ts +42 -43
  65. package/src/compat/actions/client-stub.ts +14 -14
  66. package/src/compat/actions/{action-client.ts → client.ts} +194 -193
  67. package/src/compat/actions/config.ts +63 -64
  68. package/src/compat/actions/detect.ts +68 -68
  69. package/src/compat/actions/discovery.ts +105 -105
  70. package/src/compat/actions/{action-dispatch.ts → dispatch.ts} +277 -274
  71. package/src/compat/actions/early-submit.ts +1 -1
  72. package/src/compat/actions/endpoint.ts +198 -198
  73. package/src/compat/actions/extensions.ts +811 -0
  74. package/src/compat/actions/flight.ts +23 -23
  75. package/src/compat/actions/form-state.ts +34 -34
  76. package/src/compat/actions/hoist.ts +382 -236
  77. package/src/compat/actions/ids.ts +7 -12
  78. package/src/compat/actions/index.ts +8 -8
  79. package/src/compat/actions/instances.ts +46 -46
  80. package/src/compat/actions/origin.ts +47 -48
  81. package/src/compat/actions/protocol.ts +22 -22
  82. package/src/compat/actions/registry.ts +19 -19
  83. package/src/compat/{misc/action-return.ts → actions/return.ts} +60 -57
  84. package/src/compat/actions/rewrite.ts +125 -125
  85. package/src/compat/actions/{action-router.ts → router.ts} +10 -10
  86. package/src/compat/actions/serve.ts +132 -136
  87. package/src/compat/actions/server-tag.ts +4 -4
  88. package/src/compat/actions/{action-shared.ts → shared.ts} +34 -34
  89. package/src/compat/actions/unrecognized-error.ts +4 -4
  90. package/src/compat/{index.ts → aliases.ts} +112 -109
  91. package/src/compat/bundler/bun-externals.ts +18 -18
  92. package/src/compat/bundler/cjs-exports.ts +271 -223
  93. package/src/compat/bundler/config.ts +116 -111
  94. package/src/compat/bundler/externals.ts +12 -12
  95. package/src/compat/bundler/import-meta-url.ts +19 -19
  96. package/src/compat/bundler/modularize-imports.ts +36 -33
  97. package/src/compat/bundler/new-url-asset.ts +22 -24
  98. package/src/compat/bundler/optimize-package-imports.ts +111 -107
  99. package/src/compat/bundler/polyfill.ts +28 -28
  100. package/src/compat/bundler/react-compiler.ts +35 -29
  101. package/src/compat/bundler/react-profiler.tsx +11 -11
  102. package/src/compat/bundler/relay-transform.ts +48 -47
  103. package/src/compat/bundler/require-context.ts +119 -113
  104. package/src/compat/bundler/resolve-extensions.ts +19 -19
  105. package/src/compat/bundler/source-cache.ts +25 -25
  106. package/src/compat/bundler/static-imports.ts +7 -7
  107. package/src/compat/bundler/symlink-imports.ts +46 -46
  108. package/src/compat/bundler/tsconfig-paths.ts +13 -15
  109. package/src/compat/bundler/wasm.ts +58 -60
  110. package/src/compat/bundler/webpack-loaders.ts +254 -241
  111. package/src/compat/bundler/worker.ts +101 -104
  112. package/src/compat/cache/build-flags.ts +29 -29
  113. package/src/compat/cache/build-prerender-errors.ts +40 -44
  114. package/src/compat/cache/custom-handler.ts +60 -53
  115. package/src/compat/cache/fetch-patch.ts +240 -240
  116. package/src/compat/cache/handler.ts +27 -31
  117. package/src/compat/cache/modern-handler.ts +148 -126
  118. package/src/compat/cache/resume-data-cache.ts +47 -45
  119. package/src/compat/cache/revalidate.ts +233 -232
  120. package/src/compat/cache/runtime-error.ts +35 -35
  121. package/src/compat/cache/use-cache-transform.ts +442 -417
  122. package/src/compat/cache/use-cache.ts +650 -614
  123. package/src/compat/cache-control.ts +140 -142
  124. package/src/compat/client/base-path.ts +21 -20
  125. package/src/compat/client/css-order.ts +18 -18
  126. package/src/compat/client/errors/bare-boundary.ts +11 -11
  127. package/src/compat/client/errors/control-flow.ts +23 -23
  128. package/src/compat/client/errors/error-boundary.ts +61 -61
  129. package/src/compat/client/errors/global-error.ts +101 -91
  130. package/src/compat/client/errors/install.ts +71 -72
  131. package/src/compat/client/errors/lazy.ts +23 -23
  132. package/src/compat/client/errors/primitive-throw.ts +47 -45
  133. package/src/compat/client/errors/soft-refresh.ts +4 -4
  134. package/src/compat/client/link-status.ts +33 -33
  135. package/src/compat/client/{nav-compat-runtime.ts → nav-runtime.ts} +20 -20
  136. package/src/compat/client/{nav-compat.ts → nav.ts} +12 -13
  137. package/src/compat/client/navigation-scroll.ts +63 -63
  138. package/src/compat/client/optimistic-routing.ts +93 -88
  139. package/src/compat/client/prefetch-cache.ts +23 -24
  140. package/src/compat/client/route-announcer.ts +35 -35
  141. package/src/compat/client/segment-cache-policy.ts +20 -20
  142. package/src/compat/client/segment-cache.ts +309 -315
  143. package/src/compat/client/segment-prefetch.ts +127 -132
  144. package/src/compat/client/trailing-slash.ts +5 -4
  145. package/src/compat/css/chunking.ts +113 -116
  146. package/src/compat/css/inline-css.ts +21 -21
  147. package/src/compat/css/lightningcss.ts +37 -38
  148. package/src/compat/css/modules.ts +161 -175
  149. package/src/compat/css/nonce.ts +7 -7
  150. package/src/compat/css/sass-plugin.ts +18 -21
  151. package/src/compat/css/sass.ts +150 -152
  152. package/src/compat/css/styled-jsx-runtime.ts +27 -27
  153. package/src/compat/css/styled-jsx.ts +21 -21
  154. package/src/compat/edge-runtime.ts +27 -27
  155. package/src/compat/{adapter → export}/build-complete.ts +72 -75
  156. package/src/compat/export/client.ts +29 -31
  157. package/src/compat/export/{index.ts → emit.ts} +111 -110
  158. package/src/compat/export/standalone.ts +62 -54
  159. package/src/compat/image-optimizer/cache.ts +51 -49
  160. package/src/compat/image-optimizer/detect.ts +52 -52
  161. package/src/compat/image-optimizer/{index.ts → optimize.ts} +189 -194
  162. package/src/compat/image-optimizer/source.ts +77 -80
  163. package/src/compat/lifecycle/after-scope.ts +26 -26
  164. package/src/compat/lifecycle/after.ts +48 -45
  165. package/src/compat/lifecycle/error-funnel.ts +98 -102
  166. package/src/compat/lifecycle/error-serialize.ts +30 -26
  167. package/src/compat/lifecycle/error-ui.ts +67 -32
  168. package/src/compat/lifecycle/instrumentation-client.ts +36 -38
  169. package/src/compat/lifecycle/instrumentation.ts +85 -85
  170. package/src/compat/lifecycle/node-console.ts +11 -11
  171. package/src/compat/lifecycle/testmode.ts +160 -132
  172. package/src/compat/mdx/compile.ts +60 -57
  173. package/src/compat/mdx/plugin.ts +11 -11
  174. package/src/compat/mdx/{next-mdx-stub.ts → stub.ts} +5 -5
  175. package/src/compat/{metadata-route-artifacts.ts → metadata-artifacts.ts} +195 -191
  176. package/src/compat/metadata.ts +75 -81
  177. package/src/compat/next/cache.ts +68 -69
  178. package/src/compat/next/canonical-url.ts +9 -9
  179. package/src/compat/next/client-cache.ts +19 -19
  180. package/src/compat/next/client-navigation.ts +112 -116
  181. package/src/compat/next/client-only.ts +1 -1
  182. package/src/compat/next/client-script.tsx +99 -93
  183. package/src/compat/next/client-server.ts +10 -10
  184. package/src/compat/next/config-loader.ts +176 -173
  185. package/src/compat/next/config.ts +7 -7
  186. package/src/compat/next/constants.cjs +6 -6
  187. package/src/compat/next/constants.ts +6 -6
  188. package/src/compat/next/custom-server.ts +26 -24
  189. package/src/compat/next/dist/client/components/app-router-headers.ts +21 -21
  190. package/src/compat/next/dist/server/app-render/work-unit-async-storage.external.cjs +3 -4
  191. package/src/compat/next/dist/server/web/spec-extension/revalidate.ts +1 -1
  192. package/src/compat/next/dist/server/web/spec-extension/unstable-cache.ts +1 -1
  193. package/src/compat/next/dist/server/web/spec-extension/unstable-no-store.ts +1 -1
  194. package/src/compat/next/dynamic.tsx +21 -18
  195. package/src/compat/next/error.tsx +52 -52
  196. package/src/compat/next/font/cache.ts +74 -74
  197. package/src/compat/next/font/google.ts +2 -2
  198. package/src/compat/next/font/index.ts +1 -1
  199. package/src/compat/next/font/local.ts +3 -3
  200. package/src/compat/next/font/runtime-client.ts +17 -15
  201. package/src/compat/next/font/runtime.ts +443 -408
  202. package/src/compat/next/font/shared.ts +120 -108
  203. package/src/compat/next/form.tsx +63 -63
  204. package/src/compat/next/head.tsx +2 -2
  205. package/src/compat/next/headers.ts +103 -95
  206. package/src/compat/next/image/client.tsx +220 -0
  207. package/src/compat/next/image/config.ts +56 -58
  208. package/src/compat/next/image/optimizer.ts +40 -36
  209. package/src/compat/next/image/patterns.ts +37 -40
  210. package/src/compat/next/{image-props.ts → image/props.ts} +208 -202
  211. package/src/compat/next/image/shared.ts +65 -57
  212. package/src/compat/next/image/static-metadata.ts +98 -107
  213. package/src/compat/next/image/validate.ts +79 -88
  214. package/src/compat/next/image.tsx +19 -23
  215. package/src/compat/next/index.ts +1 -1
  216. package/src/compat/next/legacy-image.tsx +59 -60
  217. package/src/compat/next/{link-validation-transform.ts → link-transform.ts} +95 -96
  218. package/src/compat/next/link.tsx +158 -158
  219. package/src/compat/next/navigation.cjs +12 -3
  220. package/src/compat/next/navigation.ts +48 -50
  221. package/src/compat/next/offline.ts +27 -27
  222. package/src/compat/next/og.ts +121 -124
  223. package/src/compat/next/preferred-region.ts +13 -14
  224. package/src/compat/next/redirects.ts +58 -56
  225. package/src/compat/next/resource-hints.ts +73 -76
  226. package/src/compat/next/rewrites.ts +130 -133
  227. package/src/compat/next/root-params.ts +45 -45
  228. package/src/compat/next/{optimistic-route-state.ts → route-state.ts} +52 -52
  229. package/src/compat/next/router.cjs +4 -2
  230. package/src/compat/next/router.ts +58 -61
  231. package/src/compat/next/script.tsx +108 -108
  232. package/src/compat/next/server-only.ts +1 -1
  233. package/src/compat/next/server.ts +19 -19
  234. package/src/compat/next/svgr.ts +18 -17
  235. package/src/compat/next/telemetry.ts +24 -24
  236. package/src/compat/next/{image-usage.ts → usage.ts} +70 -39
  237. package/src/compat/next/user-agent.ts +53 -49
  238. package/src/compat/next/web-vitals.ts +22 -24
  239. package/src/compat/otel/api.ts +41 -41
  240. package/src/compat/otel/client-trace-metadata.ts +25 -27
  241. package/src/compat/otel/fetch-span.ts +29 -29
  242. package/src/compat/otel/tracer.ts +331 -331
  243. package/src/compat/pages/api.ts +456 -0
  244. package/src/compat/pages/client-plugin.ts +36 -36
  245. package/src/compat/pages/router-state.ts +34 -34
  246. package/src/compat/pages/{index.ts → router.ts} +130 -135
  247. package/src/compat/ppr/io.ts +12 -12
  248. package/src/compat/ppr/missing-root-params.ts +34 -38
  249. package/src/compat/ppr/root-params-scan.ts +66 -66
  250. package/src/compat/ppr/root-params-transform.ts +24 -26
  251. package/src/compat/ppr/root-params.ts +30 -30
  252. package/src/compat/ppr/segment-config-incompat.ts +6 -7
  253. package/src/compat/protocol.ts +71 -70
  254. package/src/compat/react/action-state.ts +47 -48
  255. package/src/compat/react/client-lite.ts +15 -15
  256. package/src/compat/react/client.ts +4 -4
  257. package/src/compat/react/compiler-runtime.ts +11 -11
  258. package/src/compat/react/dom-client.ts +44 -44
  259. package/src/compat/react/dom-react-server.ts +10 -16
  260. package/src/compat/react/dom-server.ts +10 -10
  261. package/src/compat/react/dom.ts +52 -52
  262. package/src/compat/react/hooks-extra.ts +34 -35
  263. package/src/compat/react/parity.ts +64 -61
  264. package/src/compat/react/preact.ts +81 -82
  265. package/src/compat/react/react-server.ts +28 -28
  266. package/src/compat/react/router-shim.ts +1 -1
  267. package/src/compat/react/server-component-use.ts +8 -8
  268. package/src/compat/react/server-inserted-html.ts +30 -31
  269. package/src/compat/react/server.ts +53 -55
  270. package/src/compat/react/use.ts +32 -32
  271. package/src/compat/react/view-transition.ts +20 -20
  272. package/src/compat/register/actions.ts +35 -824
  273. package/src/compat/register/boot.ts +41 -41
  274. package/src/compat/register/build-tier.ts +5 -5
  275. package/src/compat/register/build.ts +74 -70
  276. package/src/compat/register/bundler.ts +161 -156
  277. package/src/compat/register/cache.ts +20 -20
  278. package/src/compat/register/client-errors.ts +3 -3
  279. package/src/compat/register/config.ts +6 -6
  280. package/src/compat/register/css-extras.ts +30 -34
  281. package/src/compat/register/edge-runtime.ts +3 -3
  282. package/src/compat/register/errors.ts +10 -12
  283. package/src/compat/register/export.ts +16 -16
  284. package/src/compat/register/font.ts +11 -11
  285. package/src/compat/register/hooks.ts +2 -2
  286. package/src/compat/register/image.ts +40 -40
  287. package/src/compat/register/index.ts +59 -62
  288. package/src/compat/register/instrumentation-client.ts +10 -10
  289. package/src/compat/register/lifecycle.ts +25 -28
  290. package/src/compat/register/mdx.ts +10 -10
  291. package/src/compat/register/middleware.ts +226 -16
  292. package/src/compat/register/otel.ts +80 -88
  293. package/src/compat/register/pages-api.ts +10 -463
  294. package/src/compat/register/ppr.ts +16 -16
  295. package/src/compat/register/protocol.ts +17 -18
  296. package/src/compat/register/proxy.ts +49 -51
  297. package/src/compat/register/render.ts +79 -76
  298. package/src/compat/register/routing.ts +162 -159
  299. package/src/compat/register/segment.ts +24 -1897
  300. package/src/compat/register/static-image.ts +3 -3
  301. package/src/compat/register/{misc.ts → taint.ts} +9 -9
  302. package/src/compat/register/typed-routes.ts +14 -14
  303. package/src/compat/register/{usecache.ts → use-cache.ts} +39 -39
  304. package/src/compat/register/validation.ts +18 -18
  305. package/src/compat/segment/loading-boundary.ts +43 -45
  306. package/src/compat/segment/page-slot.ts +69 -69
  307. package/src/compat/segment/serve.ts +1884 -0
  308. package/src/compat/segment/tree.ts +113 -112
  309. package/src/compat/segment/vary-key.ts +38 -38
  310. package/src/compat/segment/vary-params.ts +138 -142
  311. package/src/compat/static-params.ts +14 -12
  312. package/src/compat/tsconfig-defaults.ts +87 -91
  313. package/src/compat/typecheck/{index.ts → check.ts} +234 -212
  314. package/src/compat/typecheck/worker.ts +15 -12
  315. package/src/compat/typed-routes/{index.ts → generate.ts} +36 -36
  316. package/src/compat/typed-routes/manifest.ts +174 -170
  317. package/src/compat/typed-routes/typegen.ts +127 -110
  318. package/src/compat/validation/errors.ts +16 -19
  319. package/src/compat/validation/prerender-diagnostics.ts +521 -504
  320. package/src/compat/validation/{index.ts → validate.ts} +647 -648
  321. package/src/compat-bootstrap.ts +16 -16
  322. package/src/config.ts +86 -69
  323. package/src/css/build.ts +230 -227
  324. package/src/css/postcss.ts +79 -80
  325. package/src/css/worker.ts +14 -15
  326. package/src/dev/client-actions.ts +10 -10
  327. package/src/dev/client-chunk-store.ts +27 -27
  328. package/src/dev/{client-key-cache.ts → restart/client-key.ts} +76 -76
  329. package/src/dev/{restart-cache.ts → restart/enabled.ts} +1 -1
  330. package/src/dev/{global-css-cache.ts → restart/global-css.ts} +91 -83
  331. package/src/dev/{node-module-bundle-cache.ts → restart/node-modules.ts} +24 -24
  332. package/src/dev/{route-bundle-key-cache.ts → restart/route-bundle-key.ts} +53 -53
  333. package/src/dev/{route-facts-cache.ts → restart/route-facts.ts} +82 -82
  334. package/src/dev/server.ts +804 -820
  335. package/src/env.ts +46 -43
  336. package/src/extensions.ts +491 -478
  337. package/src/index.ts +8 -8
  338. package/src/internal.ts +20 -23
  339. package/src/{islands → render}/boundary-error.ts +3 -3
  340. package/src/render/hooks.ts +71 -71
  341. package/src/render/island-context.ts +14 -14
  342. package/src/render/metadata.ts +310 -310
  343. package/src/{ppr-postpone.ts → render/postpone.ts} +5 -5
  344. package/src/{ppr.ts → render/ppr.ts} +244 -245
  345. package/src/render/renderer.ts +2087 -2082
  346. package/src/render/resource-hints.ts +16 -17
  347. package/src/render/slots.tsx +224 -235
  348. package/src/{islands → render}/static-children.ts +9 -12
  349. package/src/{islands → render}/static-slots.ts +37 -37
  350. package/src/{cache/context.ts → request/cache.ts} +20 -20
  351. package/src/request/context.ts +107 -107
  352. package/src/{dynamic/source.ts → resolve/dynamic.ts} +139 -139
  353. package/src/resolve/engine.ts +90 -77
  354. package/src/resolve/imports.ts +475 -463
  355. package/src/resolve/scan-facts.ts +318 -296
  356. package/src/resolve/source-text.ts +37 -37
  357. package/src/{dynamic → resolve}/tree-shake.ts +132 -128
  358. package/src/routing/forwarded.ts +19 -19
  359. package/src/routing/handler.ts +84 -91
  360. package/src/routing/href.ts +87 -70
  361. package/src/routing/{metadata.ts → metadata-files.ts} +403 -401
  362. package/src/{proxy.ts → routing/proxy.ts} +306 -312
  363. package/src/routing/{request-runtime.ts → request-environment.ts} +10 -10
  364. package/src/routing/routes.ts +827 -815
  365. package/src/routing/slots.ts +164 -160
  366. package/src/runtime/loader.ts +954 -0
  367. package/src/{dev → runtime}/module-cache.ts +309 -287
  368. package/src/{dev → runtime}/module-generations.ts +9 -9
  369. package/src/{dev → runtime}/module-transform.ts +81 -72
  370. package/src/{dev/imports.ts → runtime/modules.ts} +934 -847
  371. package/src/runtime/{server.ts → vendor-build.ts} +848 -1696
  372. package/src/runtime/vendor.ts +428 -406
  373. package/src/styles.d.ts +9 -0
  374. package/src/types.ts +324 -335
  375. package/src/utils/ansi.ts +5 -5
  376. package/src/utils/{source.ts → code.ts} +15 -12
  377. package/src/utils/content-type.ts +3 -3
  378. package/src/utils/decode.ts +2 -2
  379. package/src/utils/dev-profile.ts +13 -13
  380. package/src/utils/error-log.ts +6 -6
  381. package/src/utils/esbuild.ts +18 -18
  382. package/src/utils/fs-cache.ts +13 -13
  383. package/src/utils/fs.ts +57 -49
  384. package/src/utils/html.ts +20 -24
  385. package/src/utils/native-require.ts +8 -8
  386. package/src/utils/serialize.ts +139 -146
  387. package/src/utils/verbose.ts +18 -18
  388. package/reference/overview.md +0 -35
  389. package/src/cli/analyze-print.ts +0 -181
  390. package/src/compat/middleware/manifest.ts +0 -210
  391. package/src/compat/next/image-client.tsx +0 -215
  392. package/src/compat/next/link-usage.ts +0 -29
  393. package/src/css/index.ts +0 -2
  394. package/src/render/index.ts +0 -1
  395. package/src/style-modules.d.ts +0 -9
package/README.md CHANGED
@@ -8,6 +8,8 @@
8
8
 
9
9
  ## Getting started
10
10
 
11
+ > pnext requires [Bun](https://bun.sh/get) - make sure it is installed first.
12
+
11
13
  A new app:
12
14
 
13
15
  ```sh
@@ -22,11 +24,13 @@ bunx @wular/pnext migrate
22
24
 
23
25
  Or by hand: `bun add -d @wular/pnext`, then `pnext dev`.
24
26
 
27
+ [Getting Started](./reference/getting-started.md) walks through all of it, from first page to build.
28
+
25
29
  ## Incremental by design
26
30
 
27
- Server-rendered pages ship **0 KB** of JavaScript, or **~1 KB gzip** if you want client-side navigation and prefetching. Interactive pages hydrate on Preact for **~7.5 KB** of framework, **~12.5 KB** with React compatibility. And everything is instant: the first page in dev renders **1113.5× faster** than Next's on **3.4–3.8× less memory**, and production builds run **7–10.5× faster**. See [Performance](./reference/performance.md).
31
+ Server-rendered pages ship **0 KB** of JavaScript, or **~1 KB gzip** if you want client-side navigation and prefetching. Interactive pages hydrate on Preact for **~7.5 KB** of framework, **~12.5 KB** with React compatibility. Everything is instant, the first page in dev renders **1012× faster** than Next.js on **3.5–4× less memory**, and production builds run **7–9× faster**. See [Performance](./reference/performance.md).
28
32
 
29
- Core pnext is pure Preact. `compat.react` runs React components and libraries on it, and `compat.next` runs a whole Next.js App Router app unchanged. Start anywhere on that ladder and move when it suits you. The App Router compatibility is validated against Next's own test suite (4,400+ assertions passing). The `pages/` folder is not supported, and neither are private internal utilities of Next.js or React. See [Compatibility](./reference/compat.md).
33
+ Core pnext is pure Preact. `compat.react` runs React components and libraries on it, and `compat.next` runs a whole Next.js App Router app unchanged. Start anywhere on that ladder and move when it suits you. The App Router compatibility is validated against Next's own test suite (4,400+ assertions passing). The `pages/` folder or private internal utilities of Next.js or React are mostly not supported. See [Compatibility](./reference/compat.md).
30
34
 
31
35
  ## A quick tour
32
36
 
@@ -36,17 +40,17 @@ Routes live in `app/`. A `page.tsx` is a Server Component by default. It runs on
36
40
 
37
41
  ```tsx
38
42
  // app/posts/[id]/page.tsx
39
- import type { PageProps } from "#gen/app/posts/[id]/page";
43
+ import type { PageProps } from '#gen/app/posts/[id]/page'
40
44
 
41
45
  export default async function Page({ params }: PageProps) {
42
- const { id } = await params;
43
- const post = await db.post.findUnique({ where: { id } });
46
+ const { id } = await params
47
+ const post = await db.post.findUnique({ where: { id } })
44
48
  return (
45
49
  <article>
46
50
  <h1>{post.title}</h1>
47
51
  <p>{post.body}</p>
48
52
  </article>
49
- );
53
+ )
50
54
  }
51
55
  ```
52
56
 
@@ -58,12 +62,14 @@ Mark a component with `"use client"` where you need state, effects, or event han
58
62
 
59
63
  ```tsx
60
64
  // app/counter.tsx
61
- "use client";
62
- import { useState } from "preact/hooks";
65
+ 'use client'
66
+ import { useState } from 'preact/hooks'
63
67
 
64
68
  export function Counter({ initial }: { initial: number }) {
65
- const [count, setCount] = useState(initial);
66
- return <button onClick={() => setCount(count + 1)}>Count {count}</button>;
69
+ const [count, setCount] = useState(initial)
70
+ return (
71
+ <button onClick={() => setCount(count + 1)}>Count {count}</button>
72
+ )
67
73
  }
68
74
  ```
69
75
 
@@ -74,14 +80,14 @@ Client Components hydrate on Preact for ~7.5 KB of framework, or ~12.5 KB with [
74
80
  Wrap slow server work in `<Suspense>`. The shell streams immediately and the content follows when it's ready:
75
81
 
76
82
  ```tsx
77
- import { Suspense } from "@wular/pnext";
83
+ import { Suspense } from '@wular/pnext'
78
84
 
79
85
  export default function Page() {
80
86
  return (
81
87
  <Suspense fallback={<p>Loading comments…</p>}>
82
88
  <Comments />
83
89
  </Suspense>
84
- );
90
+ )
85
91
  }
86
92
  ```
87
93
 
@@ -92,20 +98,20 @@ A `route.ts` file is an HTTP handler:
92
98
  ```ts
93
99
  // app/api/users/route.ts
94
100
  export async function GET(request: NextRequest) {
95
- return Response.json(await listUsers());
101
+ return Response.json(await listUsers())
96
102
  }
97
103
  ```
98
104
 
99
105
  - `proxy.ts` runs before route matching.
100
106
  - `loading.tsx`, `error.tsx`, and `not-found.tsx` define per-segment fallbacks.
101
- - `pnext build` emits static HTML for routes that never read the request, and a server for the ones that do. `pnext start` serves it.
107
+ - `pnext build` makes the production build and `pnext start` serves it. Routes that never read the request are prerendered to static HTML.
102
108
 
103
109
  ## Learn more
104
110
 
105
111
  Apps are file-routed from `app/`: `page.tsx` and `layout.tsx` are Server Components, `route.ts` files are HTTP handlers, `public/` is served from `/`. The reference covers the rest:
106
112
 
107
- - [Overview](./reference/overview.md)
108
- - [Dev server](./reference/dev.md)
113
+ - [Getting Started](./reference/getting-started.md)
114
+ - [Development](./reference/dev.md)
109
115
  - [Routing](./reference/routing.md)
110
116
  - [Navigation](./reference/navigation.md)
111
117
  - [Rendering](./reference/rendering.md)
package/bin/pnext CHANGED
@@ -1,5 +1,10 @@
1
1
  #!/bin/sh
2
2
 
3
+ if ! command -v bun >/dev/null 2>&1; then
4
+ echo "pnext requires Bun. Install it from https://bun.sh/get" >&2
5
+ exit 1
6
+ fi
7
+
3
8
  script=$0
4
9
 
5
10
  # `dirname` is an external binary and `$(...)` forks a subshell, so spelling this
@@ -47,7 +52,7 @@ fi
47
52
  # instead of showing "bun". The kernel takes the process name from the exec'd
48
53
  # file's basename; argv0 tricks like `exec -a` never reach it.
49
54
  #
50
- # The cached names are hardlinks of a bun binary (see src/cli/named-bin.ts), so
55
+ # The cached names are hardlinks of a bun binary (see src/cli/boot/named-bin.ts), so
51
56
  # `-ef` — same device and inode — proves a candidate is *this* bun and never
52
57
  # execs a stale one left by an earlier version. Resolving it here in sh instead
53
58
  # of asking named-bin.ts saves a whole bun process per command; on a miss we run
@@ -1,10 +1,10 @@
1
- import * as path from 'node:path';
2
- import { includeIgnoreFile } from '@eslint/compat';
1
+ import * as path from 'node:path'
2
+ import { includeIgnoreFile } from '@eslint/compat'
3
3
  // @ts-ignore
4
- import eslint from '@eslint/js';
5
- import importPlugin from 'eslint-plugin-import';
6
- import turboPlugin from 'eslint-plugin-turbo';
7
- import tseslint from 'typescript-eslint';
4
+ import eslint from '@eslint/js'
5
+ import importPlugin from 'eslint-plugin-import'
6
+ import turboPlugin from 'eslint-plugin-turbo'
7
+ import tseslint from 'typescript-eslint'
8
8
 
9
9
  export default tseslint.config(
10
10
  includeIgnoreFile(path.join(import.meta.dirname, '../../.gitignore')),
@@ -45,4 +45,4 @@ export default tseslint.config(
45
45
  linterOptions: { reportUnusedDisableDirectives: true },
46
46
  languageOptions: { parserOptions: { projectService: true } },
47
47
  },
48
- );
48
+ )
@@ -6,9 +6,7 @@
6
6
  "esModuleInterop": true,
7
7
  "incremental": false,
8
8
  "isolatedModules": true,
9
- "lib": [
10
- "ESNext"
11
- ],
9
+ "lib": ["ESNext"],
12
10
  "module": "ESNext",
13
11
  "moduleResolution": "Bundler",
14
12
  "moduleDetection": "force",
@@ -23,4 +21,4 @@
23
21
  "allowJs": true,
24
22
  "noEmit": true
25
23
  }
26
- }
24
+ }
@@ -3,11 +3,7 @@
3
3
  "display": "React Library",
4
4
  "extends": "./base.json",
5
5
  "compilerOptions": {
6
- "lib": [
7
- "DOM",
8
- "DOM.Iterable",
9
- "ESNext"
10
- ],
6
+ "lib": ["DOM", "DOM.Iterable", "ESNext"],
11
7
  "jsx": "react-jsx"
12
8
  }
13
- }
9
+ }
package/package.json CHANGED
@@ -1,10 +1,28 @@
1
1
  {
2
2
  "name": "@wular/pnext",
3
- "version": "0.0.4",
3
+ "version": "0.0.7",
4
+ "description": "A fast little framework for server-first React apps, fully compatible with Next.js",
4
5
  "type": "module",
5
6
  "bin": {
6
7
  "pnext": "bin/pnext"
7
8
  },
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "https://github.com/muzam1l/pnext.git"
12
+ },
13
+ "homepage": "https://github.com/muzam1l/pnext",
14
+ "bugs": {
15
+ "url": "https://github.com/muzam1l/pnext/issues"
16
+ },
17
+ "keywords": [
18
+ "react",
19
+ "preact",
20
+ "framework",
21
+ "ssr",
22
+ "server-components",
23
+ "bun",
24
+ "nextjs"
25
+ ],
8
26
  "files": [
9
27
  "bin",
10
28
  "config",
@@ -27,7 +45,8 @@
27
45
  "./config/*": "./config/*"
28
46
  },
29
47
  "scripts": {
30
- "lint": "bun scripts/check-compat-boundary.ts && eslint . --max-warnings 0 && tsc --noEmit",
48
+ "lint": "bun scripts/check-compat-boundary.ts && prettier --check . && eslint . --max-warnings 0 && tsc --noEmit",
49
+ "format": "prettier --write .",
31
50
  "bench": "bun bench/run.ts",
32
51
  "clean": "rm -rf .turbo .pnext node_modules",
33
52
  "prepublishOnly": "bun run lint",
@@ -53,8 +72,10 @@
53
72
  "@eslint/js": "^9.38.0",
54
73
  "@types/bun": "^1.3.0",
55
74
  "eslint": "^9.38.0",
75
+ "eslint-config-prettier": "^10.1.8",
56
76
  "eslint-plugin-import": "^2.32.0",
57
77
  "eslint-plugin-turbo": "^2.5.8",
78
+ "prettier": "^3.9.6",
58
79
  "typescript": "^5.9.3",
59
80
  "typescript-eslint": "^8.46.2"
60
81
  },
@@ -1,6 +1,6 @@
1
1
  # Compatibility
2
2
 
3
- pnext is Next.js-shaped. With `compat.next` on, App Router apps behave the way they do in Next: the `next/*` module surface, `next.config.js`, server actions, metadata, `proxy`/`middleware`, `'use cache'`, the `/_next/image` optimizer, and the `next/navigation` router. That is validated by running Next.js's own test suite against pnext rather than by hand-written parity claims.
3
+ pnext is Next.js-shaped. With `compat.next` on, App Router apps behave the way they do in Next: the `next/*` module surface, `next.config.js`, server actions, metadata, proxy and middleware, `'use cache'`, the `/_next/image` optimizer, and the `next/navigation` router. That is validated by running Next.js's own test suite against pnext, with 4,400+ assertions passing, rather than by hand-written parity claims.
4
4
 
5
5
  ```ts
6
6
  export default {
@@ -9,55 +9,120 @@ export default {
9
9
  next: true, // the next/* surface + next.config.js; implies react
10
10
  reactCompiler: true, // React Compiler for React-style Client Components; implies react
11
11
  },
12
- };
12
+ }
13
13
  ```
14
14
 
15
- `compat.react` aliases `react`, `react-dom`, `react-dom/client`, `react-dom/server`, `react/jsx-runtime`, `react/jsx-dev-runtime`, and `react/compiler-runtime` onto Preact-backed shims. `react`'s `cache()` maps to pnext's request cache on the server.
15
+ `compat.react` aliases `react`, `react-dom`, `react-dom/client`, `react-dom/server`, `react/jsx-runtime`, `react/jsx-dev-runtime`, and `react/compiler-runtime` onto Preact-backed shims. React's `cache()` maps to pnext's request cache on the server. Importing `next/*` or `react` without the matching mode is a build error that names the flag to enable.
16
16
 
17
- Importing `next/*` or `react` without the matching compat mode is a build error naming the flag to enable.
17
+ To turn Next compatibility on without a config file, set `PNEXT_COMPAT=next`. See [Environment Variables](./env.md).
18
18
 
19
- Everything below is a place pnext deliberately does not match Next. It is the whole list.
19
+ ## Migrating a Next.js app
20
20
 
21
- ## Preact, not React
21
+ ```sh
22
+ bunx @wular/pnext migrate --dry-run
23
+ bunx @wular/pnext migrate
24
+ ```
25
+
26
+ Migration rewrites `package.json` and `tsconfig.json`, and creates a `pnext.config.ts` with `compat.next` enabled. It reports on your app source but never edits it.
27
+
28
+ ## What differs from Next
29
+
30
+ These are the places pnext deliberately does not match Next. Read them before migrating. Together with the caveats in the feature notes below, this is the whole list.
22
31
 
23
- `react-dom/server`'s streaming renderers (`renderToReadableStream`, `renderToPipeableStream`) throw; the synchronous `renderToString`/`renderToStaticMarkup` work. Client components run on Preact's reconciler, so code reaching into React internals is out of scope.
32
+ ### Preact, not React
33
+
34
+ The streaming renderers from `react-dom/server`, `renderToReadableStream` and `renderToPipeableStream`, throw. The synchronous `renderToString` and `renderToStaticMarkup` work. Client components run on Preact's reconciler, so code reaching into React internals is out of scope.
24
35
 
25
36
  Direct Preact imports and Preact Signals need no compat and produce smaller bundles than `preact/compat`.
26
37
 
27
- ## No Flight payload
38
+ ### No Flight payload
39
+
40
+ Soft navigation and server-action responses carry HTML, not a React Flight stream. Streaming, refresh, and revalidation-driven updates all work. Consuming the RSC payload as a wire format does not.
28
41
 
29
- Soft navigation and server-action responses carry HTML, not a React Flight stream. Streaming, `refresh()`, and revalidation-driven updates all work; consuming the RSC payload as a wire format does not.
42
+ Server-rendered JSX can cross into a Client Component as `children` or through any other prop, including nested in arrays and plain objects. Both stay server-rendered static HTML and ship no code, as in Next. Elements inside `Map` and `Set` props are the one shape that throws.
30
43
 
31
- Server-rendered JSX crosses into a Client Component as `children` or through any other prop (including nested in arrays and plain objects) — both stay server-rendered static HTML and ship no code, like in Next. Elements inside `Map`/`Set` props are the one shape that throws.
44
+ ### Pages Router is emulated
32
45
 
33
- ## Pages Router is emulated
46
+ A `pages/` directory is materialized onto App Router routes, so `getStaticProps` and `getServerSideProps` pages and `pages/api` handlers run. `_app`, `_document`, and `_error` are ignored. `next/head` renders nothing, so use the metadata exports instead. `next/router` maps onto the app router where the concepts line up and no-ops elsewhere.
34
47
 
35
- A `pages/` directory is materialized onto App Router routes, so `getStaticProps`/`getServerSideProps` pages and `pages/api` handlers run. `_app`, `_document`, and `_error` are ignored. `next/head` renders nothing — use the metadata exports. `next/router` maps onto the app router where the concepts line up and no-ops elsewhere.
48
+ ### No webpack or Turbopack
36
49
 
37
- ## No webpack or Turbopack
50
+ esbuild is the only bundler. A `webpack(config)` function in `next.config.js` is not executed, and pnext warns once at config load when one is present. Loader chains from `turbopack.rules`, plus `turbopack.resolveAlias`, `transpilePackages`, `modularizeImports`, and `optimizePackageImports`, are re-implemented on esbuild directly.
38
51
 
39
- esbuild is the only bundler, and a `webpack(config)` function in `next.config.js` is not executed (pnext warns once at config load when one is present). `turbopack.rules` loader chains, `turbopack.resolveAlias`, `transpilePackages`, `modularizeImports`, and `optimizePackageImports` are re-implemented on esbuild directly.
52
+ A `webpack()` function that references `@svgr/webpack`, by far the most common custom-loader use, is auto-detected. pnext then compiles `.svg` imports to inline Preact components, matching that loader's default output. Root SVG attributes are spread first, so props such as `className`, `width`, and `height` override them. Without that reference, `.svg` imports keep the normal static-asset URL behavior.
40
53
 
41
- If `webpack()` references `@svgr/webpack` the overwhelmingly common custom-loader use — pnext auto-detects it and compiles `.svg` imports to inline Preact components (root SVG attributes spread first, so `className`/`width`/`height`/etc. props override them), matching `@svgr/webpack`'s default output. Without that reference, `.svg` imports keep the normal static-asset URL behavior.
54
+ ### Cache state is per process
42
55
 
43
- ## Optional native dependencies
56
+ `revalidatePath`, `revalidateTag`, `unstable_cache`, and `'use cache'` entries live in the server process by default, so a multi-instance deployment revalidates one instance. Configure `cacheHandler` in `next.config.js` for a shared store.
44
57
 
45
- All three ship as `optionalDependencies`, so a normal install has them — same as Next. The graceful paths below only matter when the optional install fails.
58
+ ### Optional native dependencies
59
+
60
+ All three ship as `optionalDependencies`, so a normal install has them, the same as Next. These paths only matter when the optional install fails.
46
61
 
47
62
  - `next/image`'s `/_next/image` optimizer needs `sharp`. The component, `images` config validation, and static imports work without it.
48
63
  - `next/og`'s `ImageResponse` needs `satori` and `@resvg/resvg-js`. Without them, or without a usable font, it answers with a valid placeholder PNG instead of failing the request.
49
64
  - `next/font/google` resolves the catalog through `next-font`. If it cannot, the build fails rather than falling back to a hosted font.
50
65
 
51
- ## Smaller surfaces
66
+ ### Smaller surfaces
52
67
 
53
- - `userAgent()` uses an in-house parser covering mainstream browsers, engines, CPUs, and devices not the full ua-parser-js database.
54
- - Only these `next/dist/*` paths are shimmed; any other deep import fails with an error naming this list.
68
+ - `userAgent()` uses an in-house parser covering mainstream browsers, engines, CPUs, and devices, not the full ua-parser-js database.
69
+ - React's taint functions do not exist under Preact, so pnext does not export them. What it implements is the guarantee `experimental.taint` exists for: with the flag on, `process.env` is registered as tainted, and passing that object as a client-component prop at any depth throws. Development shows the message in the nearest error boundary and production shows React's redacted error text, matching Next. Tainting your own objects or values is not available.
70
+ - `ViewTransition` and `addTransitionType` are exported from the `react` entry so pages importing them render instead of throwing, and `next/link` accepts `transitionTypes`. Support stops there: the component is a passthrough that renders no DOM, and pnext does not drive `document.startViewTransition`, so declared names and types are recorded but no browser transition is played.
71
+ - Only these `next/dist/*` paths are shimmed. Any other deep import fails with an error naming this list.
55
72
  - `next/dist/client/components/app-router-headers`
56
73
  - `next/dist/server/web/spec-extension/unstable-cache`
57
74
  - `next/dist/server/web/spec-extension/unstable-no-store`
58
75
  - `next/dist/server/web/spec-extension/revalidate`
59
76
  - `next/dist/server/app-render/work-unit-async-storage.external` (server only)
60
77
 
61
- ## Cache state is per process
78
+ ## Feature notes
79
+
80
+ The rest of the surface ships as well. Each note says where support stops short.
81
+
82
+ ### redirects and rewrites
83
+
84
+ `redirects()` and `rewrites()` in `next.config.js` are both honored. Sources support the `:param`, `:param*`, `:param+`, `:param?`, and `:param(regex)` tokens, plus `has` and `missing` conditions on host, header, query, and cookie. Named capture groups feed their values into destination parameters.
85
+
86
+ Rewrites accept the array form and the object form with `beforeFiles`, `afterFiles`, and `fallback`, and entries setting `basePath: false` match the raw path. An external `http` or `https` destination is proxied through a server-side fetch. After a rewrite fires, `usePathname()` and `useSearchParams()` still report the URL the browser asked for.
87
+
88
+ Redirects use 308 for `permanent: true`, 307 for `permanent: false`, or an explicit `statusCode`, and they keep external destinations as redirects.
89
+
90
+ One partial: fallback rewrites apply only to requests that would otherwise 404, and in development that check consults the route table alone, since there is no built output to look at.
91
+
92
+ ### after()
93
+
94
+ `after()` from `next/server` runs work once the response is fully sent. Each callback runs exactly once, when the response closes, on every path: stream end, a redirect, a not-found, a thrown error, or a client abort. Calls nested inside an `after()` task run too. When the host platform supplies the Vercel request context, each task is also handed to its `waitUntil` so a serverless invocation stays alive until the task settles. An `after()` task that throws during a build prerender fails the build rather than quietly degrading the route.
95
+
96
+ ### next/form
97
+
98
+ `Form` renders a GET form and intercepts submission into a client-side navigation, building the destination URL from the form's fields. String actions get the basePath applied and are prefetched like a link, including a re-prefetch when a revalidation invalidates them. Function actions pass straight through as React form actions with no interception. A submitter that overrides the encoding, method, or target falls back to the browser's native submit, and file inputs are not submitted with a string action. Both cases warn in development.
99
+
100
+ ### instrumentation and instrumentation-client
101
+
102
+ An `instrumentation` file at the project root or in `src/` is bundled and imported once at server start. Its `register()` is awaited before the first request is served, and its `onRequestError` export is wired into the error funnel. When the app contains any edge entity, meaning a proxy or middleware, or a route declaring an edge runtime, a second freshly loaded instance is registered with `NEXT_RUNTIME` set to `edge`, mirroring Next's separate edge boot.
103
+
104
+ An `instrumentation-client` file is bundled with any `instrumentationClientInject` entries ahead of it, in configured order, and loaded from the document head so it runs before hydration. Each module's `onRouterTransitionStart` export is called at the start of every soft navigation. Apps without such a file get no extra bundle and no extra head tag.
105
+
106
+ ### OpenTelemetry
107
+
108
+ pnext emits Next's span taxonomy through the global `@opentelemetry/api` that your instrumentation file registers: a root request span carrying `next.route` and `http.status_code`, plus child spans for rendering, route handlers, `fetch`, middleware and proxy, and Pages Router data and API handlers. Incoming `traceparent` headers are extracted, and errors caught by the request funnel mark the root span.
109
+
110
+ `@opentelemetry/api` is an optional dependency resolved from your own `node_modules`, so pnext and your SDK share one API singleton. When the package is absent, every tracing helper is inert. Keys listed in `experimental.clientTraceMetadata` are injected into the document head as meta tags.
111
+
112
+ ### MDX
113
+
114
+ `.mdx` and `.md` modules compile through `@mdx-js/mdx`, an optional dependency loaded on the first MDX compile, so an app that never imports MDX does not need it installed. `createMDX()` from `@next/mdx` is understood at config load, so the remark, rehype, and recma plugins you configure there run. MDX files become routes only when `pageExtensions` lists the extension, matching Next. An `mdx-components` file supplies the component provider, and without one MDX emits plain host elements. One caveat: MDX currently compiles in the client graph, so treat an MDX module as client code.
115
+
116
+ ### Edge runtime
117
+
118
+ A route or proxy declaring an edge runtime, and a Pages Router handler configured for `edge` or `experimental-edge`, runs with `process.env.NEXT_RUNTIME` set to `edge`, the `EdgeRuntime` global defined, and a `process` object that hides `version` and `versions` so code branching on those detects the edge environment. This is an emulation inside the same Bun process rather than a separate isolate, so the Edge API subset is not enforced: Node built-ins stay reachable, and code that only works because of that will still fail on a real edge platform.
119
+
120
+ ### Root params
121
+
122
+ `next/root-params` resolves parameters from the root dynamic segment. It works in layouts, pages, and `'use cache'` functions, and inside `generateStaticParams` when a parent `generateStaticParams` already provided the parameter. Calling it inside a server action, inside `unstable_cache`, or from a route handler throws with the same diagnostics Next produces. Reading one marks every segment of the response as varying.
123
+
124
+ ### output: 'export' and output: 'standalone'
125
+
126
+ `output: 'export'` writes a static tree to `out/`, or to `distDir` when the app configures a custom one. The tree carries the HTML and the flat per-page artifacts the client router fetches when no pnext server is present, the client runtime under `_next/static/chunks/`, the build manifests, the `public/` tree, and the not-found page. Dynamic routes without `generateStaticParams`, pages forcing dynamic rendering, and route handlers with disallowed segment config are build errors, as they are in Next.
62
127
 
63
- `revalidatePath`/`revalidateTag`, `unstable_cache`, and `'use cache'` entries live in the server process by default, so a multi-instance deployment revalidates one instance. Configure `cacheHandler` in `next.config.js` for a shared store.
128
+ `output: 'standalone'` writes `.next/standalone/` with a `server.js` that boots on `PORT` and `HOSTNAME`, along with a `.nft.json` trace beside each page entry and a middleware manifest. Because pnext's production server runs under Bun, that launcher is a thin Node script that re-executes the real pnext server pointed back at the original build directory. The folder is therefore not a self-contained bundle you can ship on its own, because the build tree has to travel with it.
@@ -1,9 +1,9 @@
1
1
  # Config
2
2
 
3
- pnext reads `pnext.config.ts` from the project root passed to the CLI. The file is optional.
3
+ An optional `pnext.config.ts` in the project root, meaning the directory passed to the CLI.
4
4
 
5
5
  ```ts
6
- import type { pnextConfig } from '@wular/pnext';
6
+ import type { PNextConfig } from '@wular/pnext'
7
7
 
8
8
  export default {
9
9
  outDir: '.pnext',
@@ -12,109 +12,56 @@ export default {
12
12
  compat: {
13
13
  next: true,
14
14
  },
15
- } satisfies pnextConfig;
15
+ } satisfies PNextConfig
16
16
  ```
17
17
 
18
- With `compat.next`, `next.config.js` is loaded too, and it wins on the options both files can set (`basePath`, `assetPrefix`, `outDir`, `trailingSlash`, `skipTrailingSlashRedirect`, `productionBrowserSourceMaps`).
18
+ This is the form `pnext create` scaffolds. With `compat.next`, pnext also loads `next.config.js`, and that file wins for the options both can set: `basePath`, `assetPrefix`, `outDir`, `trailingSlash`, `skipTrailingSlashRedirect`, and `productionBrowserSourceMaps`.
19
19
 
20
20
  ## Fields
21
21
 
22
- ### `outDir`
22
+ | Field | Default | What it does |
23
+ | ----------------------------- | ----------- | ---------------------------------------------------------------------------------------------------------- |
24
+ | `outDir` | `'.pnext'` | Build output for HTML, client assets, cache files, and `manifest.json`. |
25
+ | `basePath` | `''` | Path prefix for an app served below the domain root. |
26
+ | `assetPrefix` | `basePath` | URL prefix for emitted assets. Set it when assets come from a CDN. |
27
+ | `trailingSlash` | `false` | Canonicalizes URLs to a trailing slash and redirects the form without one. |
28
+ | `skipTrailingSlashRedirect` | `false` | Serves both slash forms with no canonical redirect, preserving authored hrefs. |
29
+ | `productionBrowserSourceMaps` | `false` | Emits external `.js.map` files next to production client chunks. |
30
+ | `prefetch` | `'visible'` | Default prefetch mode for links that set none of their own. See [Navigation](./navigation.md#prefetching). |
31
+ | `workspaceRoot` | inferred | Monorepo root for resolving and reloading local workspace package imports. |
32
+ | `htmlLimitedBots` | see below | User agents that get blocking metadata in the head. Applies with `compat.next`. |
33
+ | `adapter` | unset | Narrows what a deployment adapter packs into its server function. |
34
+ | `compat` | all `false` | Turns on the React, Next, and React Compiler compatibility layers. |
23
35
 
24
- Default: `'.pnext'`
36
+ Worth knowing:
25
37
 
26
- Build output directory for HTML, client assets, cache files, and `manifest.json`.
38
+ - Development client output is already unminified, so it never emits sourcemaps.
39
+ - `workspaceRoot` is inferred from `package.json#workspaces` or `pnpm-workspace.yaml`, otherwise the app root. It does not change the app root used for `public/`, `.pnext/`, or `pnext.config.ts`. Set it only to override the inference.
40
+ - The `htmlLimitedBots` default is a regex covering Twitterbot, Slackbot, Bingbot, Discordbot, LinkedInBot, and the Google and Lighthouse renderers. Matching user agents receive metadata blocked in the head instead of streamed into the body.
27
41
 
28
- ### `basePath`
42
+ ## Compat modes
29
43
 
30
- Default: `''`
44
+ | Flag | Effect |
45
+ | ---------------------- | -------------------------------------------------------------------------- |
46
+ | `compat.react` | Aliases the React and React DOM entry points to Preact-backed shims. |
47
+ | `compat.next` | Adds the `next/*` surface, `next.config.js`, and Next App Router behavior. |
48
+ | `compat.reactCompiler` | Experimental React Compiler support for React-style Client Components. |
31
49
 
32
- Path prefix for apps served below the domain root.
50
+ Both `compat.next` and `compat.reactCompiler` imply `compat.react`. Direct Preact imports stay smaller than any of them, so reach for compat when you are running React-style components. React Compiler is not intended for components built around Preact Signals. See [Compatibility](./compat.md).
33
51
 
34
- ### `assetPrefix`
52
+ ## Deployment adapter
35
53
 
36
- Default: `basePath`
54
+ `exclude` and `keep` are string lists that adjust which directories and file suffixes an adapter packs. The Vercel adapter consumes them.
37
55
 
38
- URL prefix for emitted assets. Set it to serve `/assets/*` from a CDN.
39
-
40
- ### `trailingSlash`
41
-
42
- Default: `false`
43
-
44
- Canonicalize URLs to a trailing slash, redirecting the unslashed form.
45
-
46
- ### `skipTrailingSlashRedirect`
47
-
48
- Default: `false`
49
-
50
- Serve both the slashed and unslashed URL without a canonical redirect, and leave
51
- `<Link>` hrefs exactly as authored.
52
-
53
- ### `productionBrowserSourceMaps`
54
-
55
- Default: `false`
56
-
57
- Emit external `.js.map` browser sourcemaps next to each production client chunk,
58
- linked by a `//# sourceMappingURL=` comment. Off by default (as in Next): maps
59
- publish your first-party source to every visitor and cost real build time.
60
- Development never emits them — dev client output is un-minified already.
61
-
62
- ### `htmlLimitedBots`
63
-
64
- Default: a regex covering Twitterbot, Slackbot, Bingbot, Discordbot, LinkedInBot,
65
- and the Google/Lighthouse renderers.
66
-
67
- User agents matched by this pattern get metadata blocked in `<head>` rather than
68
- streamed into the body. `compat.next` only.
69
-
70
- ### `adapter`
71
-
72
- Default: unset
73
-
74
- `exclude` and `keep` string lists overriding what a deployment adapter packs into
75
- the server function. Entries are directory names (`storybook-static`) or file
76
- suffixes (`.map`).
77
-
78
- ### `workspaceRoot`
79
-
80
- Default: inferred from `package.json#workspaces` or `pnpm-workspace.yaml`, otherwise the app root.
81
-
82
- Monorepo root used to resolve and reload local workspace package imports. This does not change where pnext reads `public/`, writes `.pnext/`, or loads `pnext.config.ts`.
83
-
84
- ### `compat.react`
85
-
86
- Default: `false`
87
-
88
- When `true`, pnext aliases `react`, `react-dom`, `react-dom/client`, `react-dom/server`, `react/jsx-runtime`, `react/jsx-dev-runtime`, and `react/compiler-runtime` onto Preact-backed shims.
89
-
90
- Use this when moving React-style components into a pnext app. Direct Preact imports are still smaller; `preact/compat` adds compatibility code only when your app imports React APIs.
91
-
92
- ### `compat.next`
93
-
94
- Default: `false`
95
-
96
- Enables the `next/*` module surface, `next.config.js`, and the rest of the Next App Router behaviors for existing apps and shared packages. This implies `compat.react`.
97
-
98
- See [Compatibility](./compat.md).
99
-
100
- ### `compat.reactCompiler`
101
-
102
- Default: `false`
103
-
104
- Experimental React Compiler support for React-style Client Components. This implies `compat.react`.
105
-
106
- Use this for components written with React hooks and props-heavy render paths where compiler memoization can reduce rerenders. Direct Preact code still gives the smallest bundles, and React Compiler compat is not recommended for components built around Preact Signals.
107
-
108
- ## File Conventions
109
-
110
- Routes are loaded from `app/` or `src/app/`. If both exist, `app/` wins. Under
111
- `compat.next`, a `pages/` directory is materialized onto App Router routes; a
112
- hybrid app keeps its native `app/` routes.
113
-
114
- Static assets are loaded from `public/` at the project root.
115
-
116
- ## Workspace Root
56
+ ```ts
57
+ export default {
58
+ adapter: {
59
+ exclude: ['storybook-static', '.map'],
60
+ keep: ['runtime-assets', '.wasm'],
61
+ },
62
+ } satisfies PNextConfig
63
+ ```
117
64
 
118
- pnext keeps the CLI root as the app root for `public/`, `.pnext/`, and `pnext.config.ts`.
65
+ ## Where pnext looks for files
119
66
 
120
- For monorepos, pnext also infers a workspace root by walking upward to `package.json#workspaces` or `pnpm-workspace.yaml`. Set `workspaceRoot` only when that inference should be overridden.
67
+ Routes come from `app/` or `src/app/`, and `app/` wins if both exist. Static assets come from `public/` at the project root. Under `compat.next`, a `pages/` directory is materialized onto App Router routes, and a hybrid app keeps its native `app/` routes.