@wular/pnext 0.0.4 → 0.0.6
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.
- package/README.md +11 -11
- package/bin/pnext +1 -1
- package/config/lint/base.js +7 -7
- package/config/ts/base.json +2 -4
- package/config/ts/react.json +2 -6
- package/package.json +23 -2
- package/reference/compat.md +1 -1
- package/reference/config.md +2 -2
- package/reference/css.md +13 -9
- package/reference/dev.md +1 -1
- package/reference/metadata.md +7 -7
- package/reference/navigation.md +35 -28
- package/reference/performance.md +70 -70
- package/reference/rendering.md +17 -17
- package/reference/routing.md +17 -17
- package/reference/typegen.md +12 -8
- package/src/api/cache.ts +36 -37
- package/src/api/client-cache.ts +2 -2
- package/src/api/client-navigation.ts +113 -109
- package/src/api/dynamic.tsx +58 -55
- package/src/api/link.tsx +49 -52
- package/src/api/navigation.ts +59 -58
- package/src/api/server.ts +152 -144
- package/src/api/suspense.ts +4 -4
- package/src/cli/adapters/vercel-warm.ts +126 -121
- package/src/cli/adapters/vercel.ts +437 -443
- package/src/cli/analyze.ts +333 -144
- package/src/cli/{named-bin.ts → boot/named-bin.ts} +37 -37
- package/src/cli/{boot-trace.ts → boot/trace.ts} +10 -10
- package/src/cli/build.ts +976 -978
- package/src/cli/create.ts +71 -63
- package/src/cli/dev.ts +116 -116
- package/src/cli/index.ts +88 -85
- package/src/cli/migrate/package-json.ts +73 -71
- package/src/cli/migrate/report.ts +32 -33
- package/src/cli/migrate/{index.ts → run.ts} +48 -49
- package/src/cli/migrate/scan.ts +46 -46
- package/src/cli/migrate/spinner.ts +9 -9
- package/src/cli/migrate/tsconfig.ts +35 -35
- package/src/cli/{server-entry.ts → serve/entry.ts} +57 -57
- package/src/cli/{request-pipeline.ts → serve/pipeline.ts} +386 -394
- package/src/cli/{serve-ui.ts → serve/ui.ts} +47 -47
- package/src/cli/start.ts +65 -66
- package/src/{typegen.ts → cli/typegen.ts} +59 -59
- package/src/client/build.ts +794 -768
- package/src/client/chunk-fold.ts +245 -240
- package/src/client/{paths.ts → chunk-name.ts} +6 -6
- package/src/client/entry.ts +162 -147
- package/src/client/prebuilt.ts +231 -223
- package/src/client/profile.ts +29 -29
- package/src/client/react-compiler.ts +20 -15
- package/src/client/{compat-surface.ts → react-tier.ts} +64 -64
- package/src/client/reference-stub.ts +51 -51
- package/src/client/reference.ts +19 -19
- package/src/{api → client}/router/events.ts +17 -17
- package/src/{api → client}/router/history.ts +16 -16
- package/src/{api → client}/router/hub.ts +52 -53
- package/src/{api/router.ts → client/router/index.ts} +61 -60
- package/src/{api → client}/router/policies.ts +24 -24
- package/src/{api → client}/router/runtime.ts +1988 -1992
- package/src/{api → client}/router/types.ts +93 -98
- package/src/compat/actions/client-plugin.ts +42 -43
- package/src/compat/actions/client-stub.ts +14 -14
- package/src/compat/actions/{action-client.ts → client.ts} +194 -193
- package/src/compat/actions/config.ts +63 -64
- package/src/compat/actions/detect.ts +68 -68
- package/src/compat/actions/discovery.ts +105 -105
- package/src/compat/actions/{action-dispatch.ts → dispatch.ts} +277 -274
- package/src/compat/actions/early-submit.ts +1 -1
- package/src/compat/actions/endpoint.ts +198 -198
- package/src/compat/actions/extensions.ts +811 -0
- package/src/compat/actions/flight.ts +23 -23
- package/src/compat/actions/form-state.ts +34 -34
- package/src/compat/actions/hoist.ts +382 -236
- package/src/compat/actions/ids.ts +7 -12
- package/src/compat/actions/index.ts +8 -8
- package/src/compat/actions/instances.ts +46 -46
- package/src/compat/actions/origin.ts +47 -48
- package/src/compat/actions/protocol.ts +22 -22
- package/src/compat/actions/registry.ts +19 -19
- package/src/compat/{misc/action-return.ts → actions/return.ts} +60 -57
- package/src/compat/actions/rewrite.ts +125 -125
- package/src/compat/actions/{action-router.ts → router.ts} +10 -10
- package/src/compat/actions/serve.ts +132 -136
- package/src/compat/actions/server-tag.ts +4 -4
- package/src/compat/actions/{action-shared.ts → shared.ts} +34 -34
- package/src/compat/actions/unrecognized-error.ts +4 -4
- package/src/compat/{index.ts → aliases.ts} +112 -109
- package/src/compat/bundler/bun-externals.ts +18 -18
- package/src/compat/bundler/cjs-exports.ts +271 -223
- package/src/compat/bundler/config.ts +116 -111
- package/src/compat/bundler/externals.ts +12 -12
- package/src/compat/bundler/import-meta-url.ts +19 -19
- package/src/compat/bundler/modularize-imports.ts +36 -33
- package/src/compat/bundler/new-url-asset.ts +22 -24
- package/src/compat/bundler/optimize-package-imports.ts +111 -107
- package/src/compat/bundler/polyfill.ts +28 -28
- package/src/compat/bundler/react-compiler.ts +35 -29
- package/src/compat/bundler/react-profiler.tsx +11 -11
- package/src/compat/bundler/relay-transform.ts +48 -47
- package/src/compat/bundler/require-context.ts +119 -113
- package/src/compat/bundler/resolve-extensions.ts +19 -19
- package/src/compat/bundler/source-cache.ts +25 -25
- package/src/compat/bundler/static-imports.ts +7 -7
- package/src/compat/bundler/symlink-imports.ts +46 -46
- package/src/compat/bundler/tsconfig-paths.ts +13 -15
- package/src/compat/bundler/wasm.ts +58 -60
- package/src/compat/bundler/webpack-loaders.ts +254 -241
- package/src/compat/bundler/worker.ts +101 -104
- package/src/compat/cache/build-flags.ts +29 -29
- package/src/compat/cache/build-prerender-errors.ts +40 -44
- package/src/compat/cache/custom-handler.ts +60 -53
- package/src/compat/cache/fetch-patch.ts +240 -240
- package/src/compat/cache/handler.ts +27 -31
- package/src/compat/cache/modern-handler.ts +148 -126
- package/src/compat/cache/resume-data-cache.ts +47 -45
- package/src/compat/cache/revalidate.ts +233 -232
- package/src/compat/cache/runtime-error.ts +35 -35
- package/src/compat/cache/use-cache-transform.ts +442 -417
- package/src/compat/cache/use-cache.ts +650 -614
- package/src/compat/cache-control.ts +140 -142
- package/src/compat/client/base-path.ts +21 -20
- package/src/compat/client/css-order.ts +18 -18
- package/src/compat/client/errors/bare-boundary.ts +11 -11
- package/src/compat/client/errors/control-flow.ts +23 -23
- package/src/compat/client/errors/error-boundary.ts +61 -61
- package/src/compat/client/errors/global-error.ts +101 -91
- package/src/compat/client/errors/install.ts +71 -72
- package/src/compat/client/errors/lazy.ts +23 -23
- package/src/compat/client/errors/primitive-throw.ts +47 -45
- package/src/compat/client/errors/soft-refresh.ts +4 -4
- package/src/compat/client/link-status.ts +33 -33
- package/src/compat/client/{nav-compat-runtime.ts → nav-runtime.ts} +20 -20
- package/src/compat/client/{nav-compat.ts → nav.ts} +12 -13
- package/src/compat/client/navigation-scroll.ts +63 -63
- package/src/compat/client/optimistic-routing.ts +93 -88
- package/src/compat/client/prefetch-cache.ts +23 -24
- package/src/compat/client/route-announcer.ts +35 -35
- package/src/compat/client/segment-cache-policy.ts +20 -20
- package/src/compat/client/segment-cache.ts +309 -315
- package/src/compat/client/segment-prefetch.ts +127 -132
- package/src/compat/client/trailing-slash.ts +5 -4
- package/src/compat/css/chunking.ts +113 -116
- package/src/compat/css/inline-css.ts +21 -21
- package/src/compat/css/lightningcss.ts +37 -38
- package/src/compat/css/modules.ts +161 -175
- package/src/compat/css/nonce.ts +7 -7
- package/src/compat/css/sass-plugin.ts +18 -21
- package/src/compat/css/sass.ts +150 -152
- package/src/compat/css/styled-jsx-runtime.ts +27 -27
- package/src/compat/css/styled-jsx.ts +21 -21
- package/src/compat/edge-runtime.ts +27 -27
- package/src/compat/{adapter → export}/build-complete.ts +72 -75
- package/src/compat/export/client.ts +29 -31
- package/src/compat/export/{index.ts → emit.ts} +111 -110
- package/src/compat/export/standalone.ts +62 -54
- package/src/compat/image-optimizer/cache.ts +51 -49
- package/src/compat/image-optimizer/detect.ts +52 -52
- package/src/compat/image-optimizer/{index.ts → optimize.ts} +189 -194
- package/src/compat/image-optimizer/source.ts +77 -80
- package/src/compat/lifecycle/after-scope.ts +26 -26
- package/src/compat/lifecycle/after.ts +48 -45
- package/src/compat/lifecycle/error-funnel.ts +98 -102
- package/src/compat/lifecycle/error-serialize.ts +30 -26
- package/src/compat/lifecycle/error-ui.ts +67 -32
- package/src/compat/lifecycle/instrumentation-client.ts +36 -38
- package/src/compat/lifecycle/instrumentation.ts +85 -85
- package/src/compat/lifecycle/node-console.ts +11 -11
- package/src/compat/lifecycle/testmode.ts +160 -132
- package/src/compat/mdx/compile.ts +60 -57
- package/src/compat/mdx/plugin.ts +11 -11
- package/src/compat/mdx/{next-mdx-stub.ts → stub.ts} +5 -5
- package/src/compat/{metadata-route-artifacts.ts → metadata-artifacts.ts} +195 -191
- package/src/compat/metadata.ts +75 -81
- package/src/compat/next/cache.ts +68 -69
- package/src/compat/next/canonical-url.ts +9 -9
- package/src/compat/next/client-cache.ts +19 -19
- package/src/compat/next/client-navigation.ts +112 -116
- package/src/compat/next/client-only.ts +1 -1
- package/src/compat/next/client-script.tsx +99 -93
- package/src/compat/next/client-server.ts +10 -10
- package/src/compat/next/config-loader.ts +176 -173
- package/src/compat/next/config.ts +7 -7
- package/src/compat/next/constants.cjs +6 -6
- package/src/compat/next/constants.ts +6 -6
- package/src/compat/next/custom-server.ts +26 -24
- package/src/compat/next/dist/client/components/app-router-headers.ts +21 -21
- package/src/compat/next/dist/server/app-render/work-unit-async-storage.external.cjs +3 -4
- package/src/compat/next/dist/server/web/spec-extension/revalidate.ts +1 -1
- package/src/compat/next/dist/server/web/spec-extension/unstable-cache.ts +1 -1
- package/src/compat/next/dist/server/web/spec-extension/unstable-no-store.ts +1 -1
- package/src/compat/next/dynamic.tsx +21 -18
- package/src/compat/next/error.tsx +52 -52
- package/src/compat/next/font/cache.ts +74 -74
- package/src/compat/next/font/google.ts +2 -2
- package/src/compat/next/font/index.ts +1 -1
- package/src/compat/next/font/local.ts +3 -3
- package/src/compat/next/font/runtime-client.ts +17 -15
- package/src/compat/next/font/runtime.ts +443 -408
- package/src/compat/next/font/shared.ts +120 -108
- package/src/compat/next/form.tsx +63 -63
- package/src/compat/next/head.tsx +2 -2
- package/src/compat/next/headers.ts +103 -95
- package/src/compat/next/image/client.tsx +220 -0
- package/src/compat/next/image/config.ts +56 -58
- package/src/compat/next/image/optimizer.ts +40 -36
- package/src/compat/next/image/patterns.ts +37 -40
- package/src/compat/next/{image-props.ts → image/props.ts} +208 -202
- package/src/compat/next/image/shared.ts +65 -57
- package/src/compat/next/image/static-metadata.ts +98 -107
- package/src/compat/next/image/validate.ts +79 -88
- package/src/compat/next/image.tsx +19 -23
- package/src/compat/next/index.ts +1 -1
- package/src/compat/next/legacy-image.tsx +59 -60
- package/src/compat/next/{link-validation-transform.ts → link-transform.ts} +95 -96
- package/src/compat/next/link.tsx +158 -158
- package/src/compat/next/navigation.cjs +12 -3
- package/src/compat/next/navigation.ts +48 -50
- package/src/compat/next/offline.ts +27 -27
- package/src/compat/next/og.ts +121 -124
- package/src/compat/next/preferred-region.ts +13 -14
- package/src/compat/next/redirects.ts +58 -56
- package/src/compat/next/resource-hints.ts +73 -76
- package/src/compat/next/rewrites.ts +130 -133
- package/src/compat/next/root-params.ts +45 -45
- package/src/compat/next/{optimistic-route-state.ts → route-state.ts} +52 -52
- package/src/compat/next/router.cjs +4 -2
- package/src/compat/next/router.ts +58 -61
- package/src/compat/next/script.tsx +108 -108
- package/src/compat/next/server-only.ts +1 -1
- package/src/compat/next/server.ts +19 -19
- package/src/compat/next/svgr.ts +18 -17
- package/src/compat/next/telemetry.ts +24 -24
- package/src/compat/next/{image-usage.ts → usage.ts} +70 -39
- package/src/compat/next/user-agent.ts +53 -49
- package/src/compat/next/web-vitals.ts +22 -24
- package/src/compat/otel/api.ts +41 -41
- package/src/compat/otel/client-trace-metadata.ts +25 -27
- package/src/compat/otel/fetch-span.ts +29 -29
- package/src/compat/otel/tracer.ts +331 -331
- package/src/compat/pages/api.ts +456 -0
- package/src/compat/pages/client-plugin.ts +36 -36
- package/src/compat/pages/router-state.ts +34 -34
- package/src/compat/pages/{index.ts → router.ts} +130 -135
- package/src/compat/ppr/io.ts +12 -12
- package/src/compat/ppr/missing-root-params.ts +34 -38
- package/src/compat/ppr/root-params-scan.ts +66 -66
- package/src/compat/ppr/root-params-transform.ts +24 -26
- package/src/compat/ppr/root-params.ts +30 -30
- package/src/compat/ppr/segment-config-incompat.ts +6 -7
- package/src/compat/protocol.ts +71 -70
- package/src/compat/react/action-state.ts +47 -48
- package/src/compat/react/client-lite.ts +15 -15
- package/src/compat/react/client.ts +4 -4
- package/src/compat/react/compiler-runtime.ts +11 -11
- package/src/compat/react/dom-client.ts +44 -44
- package/src/compat/react/dom-react-server.ts +10 -16
- package/src/compat/react/dom-server.ts +10 -10
- package/src/compat/react/dom.ts +52 -52
- package/src/compat/react/hooks-extra.ts +34 -35
- package/src/compat/react/parity.ts +64 -61
- package/src/compat/react/preact.ts +81 -82
- package/src/compat/react/react-server.ts +28 -28
- package/src/compat/react/router-shim.ts +1 -1
- package/src/compat/react/server-component-use.ts +8 -8
- package/src/compat/react/server-inserted-html.ts +30 -31
- package/src/compat/react/server.ts +53 -55
- package/src/compat/react/use.ts +32 -32
- package/src/compat/react/view-transition.ts +20 -20
- package/src/compat/register/actions.ts +35 -824
- package/src/compat/register/boot.ts +41 -41
- package/src/compat/register/build-tier.ts +5 -5
- package/src/compat/register/build.ts +74 -70
- package/src/compat/register/bundler.ts +161 -156
- package/src/compat/register/cache.ts +20 -20
- package/src/compat/register/client-errors.ts +3 -3
- package/src/compat/register/config.ts +6 -6
- package/src/compat/register/css-extras.ts +30 -34
- package/src/compat/register/edge-runtime.ts +3 -3
- package/src/compat/register/errors.ts +10 -12
- package/src/compat/register/export.ts +16 -16
- package/src/compat/register/font.ts +11 -11
- package/src/compat/register/hooks.ts +2 -2
- package/src/compat/register/image.ts +40 -40
- package/src/compat/register/index.ts +59 -62
- package/src/compat/register/instrumentation-client.ts +10 -10
- package/src/compat/register/lifecycle.ts +25 -28
- package/src/compat/register/mdx.ts +10 -10
- package/src/compat/register/middleware.ts +226 -16
- package/src/compat/register/otel.ts +80 -88
- package/src/compat/register/pages-api.ts +10 -463
- package/src/compat/register/ppr.ts +16 -16
- package/src/compat/register/protocol.ts +17 -18
- package/src/compat/register/proxy.ts +49 -51
- package/src/compat/register/render.ts +79 -76
- package/src/compat/register/routing.ts +162 -159
- package/src/compat/register/segment.ts +24 -1897
- package/src/compat/register/static-image.ts +3 -3
- package/src/compat/register/{misc.ts → taint.ts} +9 -9
- package/src/compat/register/typed-routes.ts +14 -14
- package/src/compat/register/{usecache.ts → use-cache.ts} +39 -39
- package/src/compat/register/validation.ts +18 -18
- package/src/compat/segment/loading-boundary.ts +43 -45
- package/src/compat/segment/page-slot.ts +69 -69
- package/src/compat/segment/serve.ts +1884 -0
- package/src/compat/segment/tree.ts +113 -112
- package/src/compat/segment/vary-key.ts +38 -38
- package/src/compat/segment/vary-params.ts +138 -142
- package/src/compat/static-params.ts +14 -12
- package/src/compat/tsconfig-defaults.ts +87 -91
- package/src/compat/typecheck/{index.ts → check.ts} +234 -212
- package/src/compat/typecheck/worker.ts +15 -12
- package/src/compat/typed-routes/{index.ts → generate.ts} +36 -36
- package/src/compat/typed-routes/manifest.ts +174 -170
- package/src/compat/typed-routes/typegen.ts +127 -110
- package/src/compat/validation/errors.ts +16 -19
- package/src/compat/validation/prerender-diagnostics.ts +521 -504
- package/src/compat/validation/{index.ts → validate.ts} +647 -648
- package/src/compat-bootstrap.ts +16 -16
- package/src/config.ts +69 -69
- package/src/css/build.ts +230 -227
- package/src/css/postcss.ts +79 -80
- package/src/css/worker.ts +14 -15
- package/src/dev/client-actions.ts +10 -10
- package/src/dev/client-chunk-store.ts +27 -27
- package/src/dev/{client-key-cache.ts → restart/client-key.ts} +76 -76
- package/src/dev/{restart-cache.ts → restart/enabled.ts} +1 -1
- package/src/dev/{global-css-cache.ts → restart/global-css.ts} +91 -83
- package/src/dev/{node-module-bundle-cache.ts → restart/node-modules.ts} +24 -24
- package/src/dev/{route-bundle-key-cache.ts → restart/route-bundle-key.ts} +53 -53
- package/src/dev/{route-facts-cache.ts → restart/route-facts.ts} +82 -82
- package/src/dev/server.ts +804 -820
- package/src/env.ts +46 -43
- package/src/extensions.ts +491 -478
- package/src/index.ts +8 -8
- package/src/internal.ts +20 -23
- package/src/{islands → render}/boundary-error.ts +3 -3
- package/src/render/hooks.ts +71 -71
- package/src/render/island-context.ts +14 -14
- package/src/render/metadata.ts +310 -310
- package/src/{ppr-postpone.ts → render/postpone.ts} +5 -5
- package/src/{ppr.ts → render/ppr.ts} +244 -245
- package/src/render/renderer.ts +2076 -2082
- package/src/render/resource-hints.ts +16 -17
- package/src/render/slots.tsx +224 -235
- package/src/{islands → render}/static-children.ts +9 -12
- package/src/{islands → render}/static-slots.ts +37 -37
- package/src/{cache/context.ts → request/cache.ts} +20 -20
- package/src/request/context.ts +107 -107
- package/src/{dynamic/source.ts → resolve/dynamic.ts} +139 -139
- package/src/resolve/engine.ts +90 -77
- package/src/resolve/imports.ts +475 -463
- package/src/resolve/scan-facts.ts +318 -296
- package/src/resolve/source-text.ts +37 -37
- package/src/{dynamic → resolve}/tree-shake.ts +132 -128
- package/src/routing/forwarded.ts +19 -19
- package/src/routing/handler.ts +84 -91
- package/src/routing/href.ts +69 -70
- package/src/routing/{metadata.ts → metadata-files.ts} +403 -401
- package/src/{proxy.ts → routing/proxy.ts} +306 -312
- package/src/routing/{request-runtime.ts → request-environment.ts} +10 -10
- package/src/routing/routes.ts +827 -815
- package/src/routing/slots.ts +164 -160
- package/src/runtime/loader.ts +952 -0
- package/src/{dev → runtime}/module-cache.ts +309 -287
- package/src/{dev → runtime}/module-generations.ts +9 -9
- package/src/{dev → runtime}/module-transform.ts +81 -72
- package/src/{dev/imports.ts → runtime/modules.ts} +934 -847
- package/src/runtime/{server.ts → vendor-build.ts} +848 -1696
- package/src/runtime/vendor.ts +425 -404
- package/src/styles.d.ts +9 -0
- package/src/types.ts +320 -335
- package/src/utils/ansi.ts +5 -5
- package/src/utils/{source.ts → code.ts} +15 -12
- package/src/utils/content-type.ts +3 -3
- package/src/utils/decode.ts +2 -2
- package/src/utils/dev-profile.ts +13 -13
- package/src/utils/error-log.ts +6 -6
- package/src/utils/esbuild.ts +18 -18
- package/src/utils/fs-cache.ts +13 -13
- package/src/utils/fs.ts +57 -49
- package/src/utils/html.ts +20 -24
- package/src/utils/native-require.ts +8 -8
- package/src/utils/serialize.ts +139 -146
- package/src/utils/verbose.ts +18 -18
- package/src/cli/analyze-print.ts +0 -181
- package/src/compat/middleware/manifest.ts +0 -210
- package/src/compat/next/image-client.tsx +0 -215
- package/src/compat/next/link-usage.ts +0 -29
- package/src/css/index.ts +0 -2
- package/src/render/index.ts +0 -1
- package/src/style-modules.d.ts +0 -9
package/README.md
CHANGED
|
@@ -36,17 +36,17 @@ Routes live in `app/`. A `page.tsx` is a Server Component by default. It runs on
|
|
|
36
36
|
|
|
37
37
|
```tsx
|
|
38
38
|
// app/posts/[id]/page.tsx
|
|
39
|
-
import type { PageProps } from
|
|
39
|
+
import type { PageProps } from '#gen/app/posts/[id]/page'
|
|
40
40
|
|
|
41
41
|
export default async function Page({ params }: PageProps) {
|
|
42
|
-
const { id } = await params
|
|
43
|
-
const post = await db.post.findUnique({ where: { id } })
|
|
42
|
+
const { id } = await params
|
|
43
|
+
const post = await db.post.findUnique({ where: { id } })
|
|
44
44
|
return (
|
|
45
45
|
<article>
|
|
46
46
|
<h1>{post.title}</h1>
|
|
47
47
|
<p>{post.body}</p>
|
|
48
48
|
</article>
|
|
49
|
-
)
|
|
49
|
+
)
|
|
50
50
|
}
|
|
51
51
|
```
|
|
52
52
|
|
|
@@ -58,12 +58,12 @@ Mark a component with `"use client"` where you need state, effects, or event han
|
|
|
58
58
|
|
|
59
59
|
```tsx
|
|
60
60
|
// app/counter.tsx
|
|
61
|
-
|
|
62
|
-
import { useState } from
|
|
61
|
+
'use client'
|
|
62
|
+
import { useState } from 'preact/hooks'
|
|
63
63
|
|
|
64
64
|
export function Counter({ initial }: { initial: number }) {
|
|
65
|
-
const [count, setCount] = useState(initial)
|
|
66
|
-
return <button onClick={() => setCount(count + 1)}>Count {count}</button
|
|
65
|
+
const [count, setCount] = useState(initial)
|
|
66
|
+
return <button onClick={() => setCount(count + 1)}>Count {count}</button>
|
|
67
67
|
}
|
|
68
68
|
```
|
|
69
69
|
|
|
@@ -74,14 +74,14 @@ Client Components hydrate on Preact for ~7.5 KB of framework, or ~12.5 KB with [
|
|
|
74
74
|
Wrap slow server work in `<Suspense>`. The shell streams immediately and the content follows when it's ready:
|
|
75
75
|
|
|
76
76
|
```tsx
|
|
77
|
-
import { Suspense } from
|
|
77
|
+
import { Suspense } from '@wular/pnext'
|
|
78
78
|
|
|
79
79
|
export default function Page() {
|
|
80
80
|
return (
|
|
81
81
|
<Suspense fallback={<p>Loading comments…</p>}>
|
|
82
82
|
<Comments />
|
|
83
83
|
</Suspense>
|
|
84
|
-
)
|
|
84
|
+
)
|
|
85
85
|
}
|
|
86
86
|
```
|
|
87
87
|
|
|
@@ -92,7 +92,7 @@ A `route.ts` file is an HTTP handler:
|
|
|
92
92
|
```ts
|
|
93
93
|
// app/api/users/route.ts
|
|
94
94
|
export async function GET(request: NextRequest) {
|
|
95
|
-
return Response.json(await listUsers())
|
|
95
|
+
return Response.json(await listUsers())
|
|
96
96
|
}
|
|
97
97
|
```
|
|
98
98
|
|
package/bin/pnext
CHANGED
|
@@ -47,7 +47,7 @@ fi
|
|
|
47
47
|
# instead of showing "bun". The kernel takes the process name from the exec'd
|
|
48
48
|
# file's basename; argv0 tricks like `exec -a` never reach it.
|
|
49
49
|
#
|
|
50
|
-
# The cached names are hardlinks of a bun binary (see src/cli/named-bin.ts), so
|
|
50
|
+
# The cached names are hardlinks of a bun binary (see src/cli/boot/named-bin.ts), so
|
|
51
51
|
# `-ef` — same device and inode — proves a candidate is *this* bun and never
|
|
52
52
|
# execs a stale one left by an earlier version. Resolving it here in sh instead
|
|
53
53
|
# of asking named-bin.ts saves a whole bun process per command; on a miss we run
|
package/config/lint/base.js
CHANGED
|
@@ -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
|
+
)
|
package/config/ts/base.json
CHANGED
|
@@ -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
|
+
}
|
package/config/ts/react.json
CHANGED
package/package.json
CHANGED
|
@@ -1,10 +1,28 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wular/pnext",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.6",
|
|
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
|
},
|
package/reference/compat.md
CHANGED
|
@@ -9,7 +9,7 @@ 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
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.
|
package/reference/config.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
pnext reads `pnext.config.ts` from the project root passed to the CLI. The file is optional.
|
|
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,7 +12,7 @@ export default {
|
|
|
12
12
|
compat: {
|
|
13
13
|
next: true,
|
|
14
14
|
},
|
|
15
|
-
} satisfies pnextConfig
|
|
15
|
+
} satisfies pnextConfig
|
|
16
16
|
```
|
|
17
17
|
|
|
18
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`).
|
package/reference/css.md
CHANGED
|
@@ -11,15 +11,19 @@ Global CSS can use local workspace package imports, font files, image assets, an
|
|
|
11
11
|
When the app root has a `postcss.config.{cjs,js,mjs}`, pnext runs its plugins on every emitted stylesheet, in a worker thread. Tailwind v4 (`@tailwindcss/postcss`) stays warm there, so dev rebuilds are incremental; config-file edits need a dev-server restart.
|
|
12
12
|
|
|
13
13
|
```tsx
|
|
14
|
-
import type { ComponentChildren } from 'preact'
|
|
15
|
-
import './globals.css'
|
|
16
|
-
|
|
17
|
-
export default function Layout({
|
|
14
|
+
import type { ComponentChildren } from 'preact'
|
|
15
|
+
import './globals.css'
|
|
16
|
+
|
|
17
|
+
export default function Layout({
|
|
18
|
+
children,
|
|
19
|
+
}: {
|
|
20
|
+
children: ComponentChildren
|
|
21
|
+
}) {
|
|
18
22
|
return (
|
|
19
23
|
<html>
|
|
20
24
|
<body>{children}</body>
|
|
21
25
|
</html>
|
|
22
|
-
)
|
|
26
|
+
)
|
|
23
27
|
}
|
|
24
28
|
```
|
|
25
29
|
|
|
@@ -28,10 +32,10 @@ export default function Layout({ children }: { children: ComponentChildren }) {
|
|
|
28
32
|
Import plain CSS from pages, layouts, or components:
|
|
29
33
|
|
|
30
34
|
```tsx
|
|
31
|
-
import './page.css'
|
|
35
|
+
import './page.css'
|
|
32
36
|
|
|
33
37
|
export default function Page() {
|
|
34
|
-
return <h1 className="title">Hello</h1
|
|
38
|
+
return <h1 className="title">Hello</h1>
|
|
35
39
|
}
|
|
36
40
|
```
|
|
37
41
|
|
|
@@ -48,10 +52,10 @@ Use `.module.css` for scoped classes:
|
|
|
48
52
|
```
|
|
49
53
|
|
|
50
54
|
```tsx
|
|
51
|
-
import styles from './page.module.css'
|
|
55
|
+
import styles from './page.module.css'
|
|
52
56
|
|
|
53
57
|
export default function Page() {
|
|
54
|
-
return <h1 className={styles.title}>Hello</h1
|
|
58
|
+
return <h1 className={styles.title}>Hello</h1>
|
|
55
59
|
}
|
|
56
60
|
```
|
|
57
61
|
|
package/reference/dev.md
CHANGED
package/reference/metadata.md
CHANGED
|
@@ -9,23 +9,23 @@ Use `compat.next` for Next.js request-time metadata APIs such as `generateMetada
|
|
|
9
9
|
Pages and layouts can export `metadata` as an object:
|
|
10
10
|
|
|
11
11
|
```tsx
|
|
12
|
-
import type { Metadata } from '@wular/pnext'
|
|
12
|
+
import type { Metadata } from '@wular/pnext'
|
|
13
13
|
|
|
14
14
|
export const metadata: Metadata = {
|
|
15
15
|
title: 'About',
|
|
16
16
|
description: 'About the team',
|
|
17
|
-
}
|
|
17
|
+
}
|
|
18
18
|
```
|
|
19
19
|
|
|
20
20
|
They can also export `metadata()` as a no-arg build-time function:
|
|
21
21
|
|
|
22
22
|
```tsx
|
|
23
23
|
export async function metadata() {
|
|
24
|
-
const site = await getSiteMetadata()
|
|
24
|
+
const site = await getSiteMetadata()
|
|
25
25
|
return {
|
|
26
26
|
title: site.title,
|
|
27
27
|
description: site.description,
|
|
28
|
-
}
|
|
28
|
+
}
|
|
29
29
|
}
|
|
30
30
|
```
|
|
31
31
|
|
|
@@ -38,13 +38,13 @@ pnext follows the Next.js metadata field shapes for common fields such as `title
|
|
|
38
38
|
Pages and layouts can export `viewport` as an object or a build-time function:
|
|
39
39
|
|
|
40
40
|
```tsx
|
|
41
|
-
import type { Viewport } from '@wular/pnext'
|
|
41
|
+
import type { Viewport } from '@wular/pnext'
|
|
42
42
|
|
|
43
43
|
export const viewport: Viewport = {
|
|
44
44
|
width: 'device-width',
|
|
45
45
|
initialScale: 1,
|
|
46
46
|
themeColor: '#0b0b0b',
|
|
47
|
-
}
|
|
47
|
+
}
|
|
48
48
|
```
|
|
49
49
|
|
|
50
50
|
Use `compat.next` for `generateViewport()` with route props.
|
|
@@ -79,7 +79,7 @@ Core dynamic routes use `params()` for build-time param selection:
|
|
|
79
79
|
|
|
80
80
|
```tsx
|
|
81
81
|
export function params() {
|
|
82
|
-
return [{ slug: 'intro' }]
|
|
82
|
+
return [{ slug: 'intro' }]
|
|
83
83
|
}
|
|
84
84
|
```
|
|
85
85
|
|
package/reference/navigation.md
CHANGED
|
@@ -7,12 +7,12 @@ pnext navigation APIs are split by runtime so server routes do not import browse
|
|
|
7
7
|
Use `href()` when building URLs outside JSX.
|
|
8
8
|
|
|
9
9
|
```tsx
|
|
10
|
-
import { href } from '@wular/pnext/navigation'
|
|
10
|
+
import { href } from '@wular/pnext/navigation'
|
|
11
11
|
|
|
12
12
|
const userHref = href('/users/[id]', {
|
|
13
13
|
params: { id: 'ada' },
|
|
14
14
|
search: { tab: 'runs' },
|
|
15
|
-
})
|
|
15
|
+
})
|
|
16
16
|
```
|
|
17
17
|
|
|
18
18
|
Dynamic params are checked from generated route types. Routes without params do not take a `params` object.
|
|
@@ -22,14 +22,18 @@ Dynamic params are checked from generated route types. Routes without params do
|
|
|
22
22
|
`<Link>` renders a normal anchor with typed route params and pnext prefetch metadata.
|
|
23
23
|
|
|
24
24
|
```tsx
|
|
25
|
-
import { Link } from '@wular/pnext/link'
|
|
25
|
+
import { Link } from '@wular/pnext/link'
|
|
26
26
|
|
|
27
27
|
export function Nav() {
|
|
28
28
|
return (
|
|
29
|
-
<Link
|
|
29
|
+
<Link
|
|
30
|
+
href="/users/[id]"
|
|
31
|
+
params={{ id: 'ada' }}
|
|
32
|
+
search={{ tab: 'runs' }}
|
|
33
|
+
>
|
|
30
34
|
Ada
|
|
31
35
|
</Link>
|
|
32
|
-
)
|
|
36
|
+
)
|
|
33
37
|
}
|
|
34
38
|
```
|
|
35
39
|
|
|
@@ -53,12 +57,12 @@ Use a normal `<a>` for external URLs or intentionally untyped links.
|
|
|
53
57
|
|
|
54
58
|
`prefetch` on `<Link>` warms the target page and its assets:
|
|
55
59
|
|
|
56
|
-
- `'intent'
|
|
57
|
-
- `'visible'
|
|
60
|
+
- `'intent'`: on hover, touch, or focus.
|
|
61
|
+
- `'visible'` (default): when the link enters the viewport.
|
|
58
62
|
- `'load'`: as soon as the link renders.
|
|
59
63
|
- `false`: never; pair with `router.prefetch(href)` for manual control.
|
|
60
64
|
|
|
61
|
-
Prefetched pages expire after
|
|
65
|
+
Prefetch requests ride low network priority, so they never compete with page-critical loading, and concurrency is capped at 4 in flight (12 for hover intent). Prefetched pages expire after 5 minutes and each navigation refetches on the next visit, so pages always reflect fresh server state. Prefetch is a no-op under `pnext dev`.
|
|
62
66
|
|
|
63
67
|
## Redirects
|
|
64
68
|
|
|
@@ -67,12 +71,12 @@ Use `notFound()` to render the nearest `not-found.tsx` fallback with a 404 respo
|
|
|
67
71
|
Use `redirect()` to stop server rendering and return a redirect response. In the browser it navigates directly.
|
|
68
72
|
|
|
69
73
|
```tsx
|
|
70
|
-
import { redirect } from '@wular/pnext/navigation'
|
|
74
|
+
import { redirect } from '@wular/pnext/navigation'
|
|
71
75
|
|
|
72
76
|
export default async function Page() {
|
|
73
|
-
const user = await getUser()
|
|
74
|
-
if (!user) redirect('/login')
|
|
75
|
-
return <Dashboard user={user}
|
|
77
|
+
const user = await getUser()
|
|
78
|
+
if (!user) redirect('/login')
|
|
79
|
+
return <Dashboard user={user} />
|
|
76
80
|
}
|
|
77
81
|
```
|
|
78
82
|
|
|
@@ -83,9 +87,9 @@ Client event handlers can call `redirect()` too. Keep it as the last statement,
|
|
|
83
87
|
For typed dynamic redirects, build the URL with `href()`:
|
|
84
88
|
|
|
85
89
|
```tsx
|
|
86
|
-
import { href, redirect } from '@wular/pnext/navigation'
|
|
90
|
+
import { href, redirect } from '@wular/pnext/navigation'
|
|
87
91
|
|
|
88
|
-
redirect(href('/users/[id]', { params: { id: 'ada' } }))
|
|
92
|
+
redirect(href('/users/[id]', { params: { id: 'ada' } }))
|
|
89
93
|
```
|
|
90
94
|
|
|
91
95
|
## Client Hooks
|
|
@@ -93,25 +97,25 @@ redirect(href('/users/[id]', { params: { id: 'ada' } }));
|
|
|
93
97
|
Client navigation hooks live in `@wular/pnext/navigation/client`.
|
|
94
98
|
|
|
95
99
|
```tsx
|
|
96
|
-
'use client'
|
|
100
|
+
'use client'
|
|
97
101
|
|
|
98
|
-
import { useRouter, useSearchParams } from '@wular/pnext/navigation/client'
|
|
102
|
+
import { useRouter, useSearchParams } from '@wular/pnext/navigation/client'
|
|
99
103
|
|
|
100
104
|
export function SortButton() {
|
|
101
|
-
const router = useRouter()
|
|
102
|
-
const searchParams = useSearchParams()
|
|
105
|
+
const router = useRouter()
|
|
106
|
+
const searchParams = useSearchParams()
|
|
103
107
|
|
|
104
108
|
return (
|
|
105
109
|
<button
|
|
106
110
|
onClick={() => {
|
|
107
|
-
const search = new URLSearchParams(searchParams.toString())
|
|
108
|
-
search.set('sort', 'asc')
|
|
109
|
-
router.replace('/products', { search, scroll: false })
|
|
111
|
+
const search = new URLSearchParams(searchParams.toString())
|
|
112
|
+
search.set('sort', 'asc')
|
|
113
|
+
router.replace('/products', { search, scroll: false })
|
|
110
114
|
}}
|
|
111
115
|
>
|
|
112
116
|
Sort
|
|
113
117
|
</button>
|
|
114
|
-
)
|
|
118
|
+
)
|
|
115
119
|
}
|
|
116
120
|
```
|
|
117
121
|
|
|
@@ -131,17 +135,20 @@ Available hooks:
|
|
|
131
135
|
Use `dynamic()` for lazily loaded Client Components.
|
|
132
136
|
|
|
133
137
|
```tsx
|
|
134
|
-
import { dynamic } from '@wular/pnext/dynamic'
|
|
135
|
-
|
|
136
|
-
const Chart = dynamic(
|
|
137
|
-
|
|
138
|
-
|
|
138
|
+
import { dynamic } from '@wular/pnext/dynamic'
|
|
139
|
+
|
|
140
|
+
const Chart = dynamic(
|
|
141
|
+
() => import('./chart').then(module => module.Chart),
|
|
142
|
+
{
|
|
143
|
+
load: 'visible',
|
|
144
|
+
},
|
|
145
|
+
)
|
|
139
146
|
```
|
|
140
147
|
|
|
141
148
|
For default exports, use the shorter literal form:
|
|
142
149
|
|
|
143
150
|
```tsx
|
|
144
|
-
const Chart = dynamic('./chart')
|
|
151
|
+
const Chart = dynamic('./chart')
|
|
145
152
|
```
|
|
146
153
|
|
|
147
154
|
Literal dynamic imports work from Server Components and Client Components. If the target module starts with `"use client"`, pnext renders it as a Client Component island; otherwise it renders on the server.
|
package/reference/performance.md
CHANGED
|
@@ -4,17 +4,17 @@ Measured against Next.js: the same fixture source runs under both frameworks and
|
|
|
4
4
|
|
|
5
5
|
| | pnext vs Next.js |
|
|
6
6
|
| --------------------------- | ---------------------------------: |
|
|
7
|
-
| Dev server ready |
|
|
8
|
-
| First page, cold |
|
|
9
|
-
| Warm request (dev) |
|
|
7
|
+
| Dev server ready | **3.8–4.3× faster** |
|
|
8
|
+
| First page, cold | **10–12× faster** |
|
|
9
|
+
| Warm request (dev) | **1.6–4.7× faster** |
|
|
10
10
|
| HMR save → visible | **0.3–2×** ¹ |
|
|
11
|
-
| Production build |
|
|
12
|
-
| Warm request (prod) |
|
|
13
|
-
| Prod server ready |
|
|
14
|
-
| Dev server memory |
|
|
15
|
-
| Build peak memory |
|
|
16
|
-
| Framework install size |
|
|
17
|
-
| First-page client JS (gzip) |
|
|
11
|
+
| Production build | **7.2–8.8× faster** |
|
|
12
|
+
| Warm request (prod) | **2–3.4× faster** |
|
|
13
|
+
| Prod server ready | **1.8–2.3× faster** |
|
|
14
|
+
| Dev server memory | **3.4–4.1× less** |
|
|
15
|
+
| Build peak memory | **3–3.7× less** |
|
|
16
|
+
| Framework install size | **59× smaller** (7.1 MB vs 421 MB) |
|
|
17
|
+
| First-page client JS (gzip) | **9.5–65× less** |
|
|
18
18
|
|
|
19
19
|
¹ pnext live-reloads (no client HMR runtime; state doesn't survive a save) — the metric
|
|
20
20
|
is save → fresh HTML, which both models support. Scoped invalidation fixed the small
|
|
@@ -36,83 +36,83 @@ two columns render the same app from the same source.
|
|
|
36
36
|
|
|
37
37
|
## Fixture: hello-world
|
|
38
38
|
|
|
39
|
-
| Metric
|
|
40
|
-
|
|
|
41
|
-
| Dev cold start (ready)
|
|
42
|
-
| Dev first page HTML
|
|
43
|
-
| Dev warm request (p50 of 7)
|
|
44
|
-
| Dev server RSS (ready + 7 warm)
|
|
45
|
-
| HMR save → visible
|
|
46
|
-
| Prod build (wall)
|
|
47
|
-
| Prod build peak RSS
|
|
48
|
-
| Prod start (ready)
|
|
49
|
-
| Prod warm request (p50 of 7)
|
|
50
|
-
| Prod server RSS (ready + 7 warm) | 85.2 MB
|
|
51
|
-
| Framework install size
|
|
52
|
-
| First-page client JS (raw)
|
|
53
|
-
| First-page client JS (gzip)
|
|
54
|
-
| First-page JS files
|
|
55
|
-
| Zero-island route client JS
|
|
39
|
+
| Metric | pnext | Next.js | Ratio |
|
|
40
|
+
| -------------------------------- | -------- | --------- | ------- |
|
|
41
|
+
| Dev cold start (ready) | 56.4 ms | 212.3 ms | 3.76x |
|
|
42
|
+
| Dev first page HTML | 79.9 ms | 993.5 ms | 12.44x |
|
|
43
|
+
| Dev warm request (p50 of 7) | 3.0 ms | 14.0 ms | 4.69x |
|
|
44
|
+
| Dev server RSS (ready + 7 warm) | 130.8 MB | 536.4 MB | 4.10x |
|
|
45
|
+
| HMR save → visible | 21.9 ms | 44.8 ms | 2.04x |
|
|
46
|
+
| Prod build (wall) | 291.3 ms | 2569.4 ms | 8.82x |
|
|
47
|
+
| Prod build peak RSS | 124.2 MB | 455.8 MB | 3.67x |
|
|
48
|
+
| Prod start (ready) | 60.7 ms | 110.9 ms | 1.83x |
|
|
49
|
+
| Prod warm request (p50 of 7) | 0.6 ms | 1.2 ms | 2.05x |
|
|
50
|
+
| Prod server RSS (ready + 7 warm) | 85.2 MB | 85.7 MB | 1.01x |
|
|
51
|
+
| Framework install size | 7.1 MB | 420.7 MB | 59.14x |
|
|
52
|
+
| First-page client JS (raw) | 4.43 KB | 502.47 KB | 113.36x |
|
|
53
|
+
| First-page client JS (gzip) | 2.19 KB | 141.78 KB | 64.67x |
|
|
54
|
+
| First-page JS files | 3 | 5 | 1.67x |
|
|
55
|
+
| Zero-island route client JS | 4.43 KB | 502.47 KB | 113.36x |
|
|
56
56
|
|
|
57
57
|
Ratio is Next.js / pnext, so above `1.00x` means pnext is ahead.
|
|
58
58
|
|
|
59
59
|
## Fixture: ssr
|
|
60
60
|
|
|
61
|
-
| Metric
|
|
62
|
-
|
|
|
63
|
-
| Dev cold start (ready)
|
|
64
|
-
| Dev first page HTML
|
|
65
|
-
| Dev warm request (p50 of 7)
|
|
66
|
-
| Dev server RSS (ready + 7 warm)
|
|
67
|
-
| HMR save → visible
|
|
68
|
-
| Prod build (wall)
|
|
69
|
-
| Prod build peak RSS
|
|
70
|
-
| Prod start (ready)
|
|
71
|
-
| Prod warm request (p50 of 7)
|
|
72
|
-
| Prod server RSS (ready + 7 warm) | 86.0 MB
|
|
73
|
-
| Framework install size
|
|
74
|
-
| First-page client JS (raw)
|
|
75
|
-
| First-page client JS (gzip)
|
|
76
|
-
| First-page JS files
|
|
77
|
-
| Zero-island route client JS
|
|
61
|
+
| Metric | pnext | Next.js | Ratio |
|
|
62
|
+
| -------------------------------- | -------- | --------- | ------- |
|
|
63
|
+
| Dev cold start (ready) | 56.0 ms | 212.8 ms | 3.80x |
|
|
64
|
+
| Dev first page HTML | 93.5 ms | 1043.3 ms | 11.16x |
|
|
65
|
+
| Dev warm request (p50 of 7) | 16.5 ms | 26.4 ms | 1.60x |
|
|
66
|
+
| Dev server RSS (ready + 7 warm) | 151.3 MB | 553.6 MB | 3.66x |
|
|
67
|
+
| HMR save → visible | 264.3 ms | 68.3 ms | 0.26x |
|
|
68
|
+
| Prod build (wall) | 310.5 ms | 2738.8 ms | 8.82x |
|
|
69
|
+
| Prod build peak RSS | 136.8 MB | 456.6 MB | 3.34x |
|
|
70
|
+
| Prod start (ready) | 57.1 ms | 105.5 ms | 1.85x |
|
|
71
|
+
| Prod warm request (p50 of 7) | 0.5 ms | 1.3 ms | 2.50x |
|
|
72
|
+
| Prod server RSS (ready + 7 warm) | 86.0 MB | 85.9 MB | 1.00x |
|
|
73
|
+
| Framework install size | 7.1 MB | 420.7 MB | 59.14x |
|
|
74
|
+
| First-page client JS (raw) | 27.36 KB | 502.78 KB | 18.37x |
|
|
75
|
+
| First-page client JS (gzip) | 11.39 KB | 142.03 KB | 12.47x |
|
|
76
|
+
| First-page JS files | 4 | 6 | 1.50x |
|
|
77
|
+
| Zero-island route client JS | 4.46 KB | 502.47 KB | 112.56x |
|
|
78
78
|
|
|
79
79
|
Ratio is Next.js / pnext, so above `1.00x` means pnext is ahead.
|
|
80
80
|
|
|
81
81
|
## Fixture: dashboard
|
|
82
82
|
|
|
83
|
-
| Metric
|
|
84
|
-
|
|
|
85
|
-
| Dev cold start (ready)
|
|
86
|
-
| Dev first page HTML
|
|
87
|
-
| Dev warm request (p50 of 7)
|
|
88
|
-
| Dev server RSS (ready + 7 warm)
|
|
89
|
-
| HMR save → visible
|
|
90
|
-
| Prod build (wall)
|
|
91
|
-
| Prod build peak RSS
|
|
92
|
-
| Prod start (ready)
|
|
93
|
-
| Prod warm request (p50 of 7)
|
|
94
|
-
| Prod server RSS (ready + 7 warm) | 87.3 MB
|
|
95
|
-
| Framework install size
|
|
96
|
-
| First-page client JS (raw)
|
|
97
|
-
| First-page client JS (gzip)
|
|
98
|
-
| First-page JS files
|
|
83
|
+
| Metric | pnext | Next.js | Ratio |
|
|
84
|
+
| -------------------------------- | -------- | --------- | ------ |
|
|
85
|
+
| Dev cold start (ready) | 57.1 ms | 246.4 ms | 4.31x |
|
|
86
|
+
| Dev first page HTML | 127.0 ms | 1285.8 ms | 10.12x |
|
|
87
|
+
| Dev warm request (p50 of 7) | 21.6 ms | 34.1 ms | 1.58x |
|
|
88
|
+
| Dev server RSS (ready + 7 warm) | 168.6 MB | 577.1 MB | 3.42x |
|
|
89
|
+
| HMR save → visible | 300.4 ms | 97.6 ms | 0.32x |
|
|
90
|
+
| Prod build (wall) | 637.5 ms | 4566.3 ms | 7.16x |
|
|
91
|
+
| Prod build peak RSS | 188.0 MB | 569.0 MB | 3.03x |
|
|
92
|
+
| Prod start (ready) | 55.6 ms | 128.8 ms | 2.32x |
|
|
93
|
+
| Prod warm request (p50 of 7) | 0.5 ms | 1.7 ms | 3.41x |
|
|
94
|
+
| Prod server RSS (ready + 7 warm) | 87.3 MB | 90.6 MB | 1.04x |
|
|
95
|
+
| Framework install size | 7.1 MB | 420.7 MB | 59.14x |
|
|
96
|
+
| First-page client JS (raw) | 38.51 KB | 507.42 KB | 13.18x |
|
|
97
|
+
| First-page client JS (gzip) | 15.26 KB | 144.85 KB | 9.50x |
|
|
98
|
+
| First-page JS files | 6 | 9 | 1.50x |
|
|
99
99
|
|
|
100
100
|
Ratio is Next.js / pnext, so above `1.00x` means pnext is ahead.
|
|
101
101
|
|
|
102
102
|
## Client runtime bundles
|
|
103
103
|
|
|
104
|
-
| Runtime
|
|
105
|
-
|
|
|
106
|
-
| router-prefetch-only
|
|
104
|
+
| Runtime | Raw | Gzip | Brotli |
|
|
105
|
+
| ------------------------ | -------- | ------- | ------- |
|
|
106
|
+
| router-prefetch-only | 473 B | 348 B | 283 B |
|
|
107
107
|
| combined-router-hydrator | 10.47 KB | 4.47 KB | 4.07 KB |
|
|
108
108
|
|
|
109
109
|
## Targets
|
|
110
110
|
|
|
111
|
-
| Target
|
|
112
|
-
|
|
|
113
|
-
| Dev cold start, ssr fixture (pnext)
|
|
114
|
-
| Router runtime
|
|
115
|
-
| Hydrated-route framework tax
|
|
111
|
+
| Target | Limit | Measured | Status |
|
|
112
|
+
| ------------------------------------------ | ---------------- | --------------------- | ------------- |
|
|
113
|
+
| Dev cold start, ssr fixture (pnext) | <= 100 ms | 56.0 ms | PASS |
|
|
114
|
+
| Router runtime | <= 1.00 KB gzip | 348 B gzip | PASS |
|
|
115
|
+
| Hydrated-route framework tax | <= 5.00 KB gzip | 4.47 KB gzip | PASS |
|
|
116
116
|
| Zero-island route client JS (ssr `/about`) | 0 B (core pnext) | 4.46 KB (compat.next) | not exercised |
|
|
117
117
|
|
|
118
118
|
## Notes
|
|
@@ -143,8 +143,8 @@ Ratio is Next.js / pnext, so above `1.00x` means pnext is ahead.
|
|
|
143
143
|
excludes.
|
|
144
144
|
- Framework install size is each framework's own package cost, not the fixture's total
|
|
145
145
|
`node_modules`, which both frameworks share: `next` + its platform `@next/swc-*` binary,
|
|
146
|
-
or `@wular/pnext`'s npm-publish footprint (its `package.json` "files" list, since
|
|
147
|
-
|
|
146
|
+
or `@wular/pnext`'s npm-publish footprint (its `package.json` "files" list, since the
|
|
147
|
+
repo resolves it to source rather than an installed build) + `preact`.
|
|
148
148
|
|
|
149
149
|
## Commands
|
|
150
150
|
|