Skip to content

fix: apply configureVite hook in dev mode#14

Merged
childrentime merged 4 commits into
mainfrom
fix/configure-vite-dev-mode
Apr 8, 2026
Merged

fix: apply configureVite hook in dev mode#14
childrentime merged 4 commits into
mainfrom
fix/configure-vite-dev-mode

Conversation

@childrentime

Copy link
Copy Markdown
Owner

Summary

  • configureVite was only applied during pareto build (via createClientConfig / createServerConfig) but completely skipped in pareto dev, where createViteServer received a hardcoded config
  • This caused user Vite plugins, aliases, and SSR config overrides to silently not work during development
  • Fix: extract the base config into a variable and pipe it through config.configureVite(baseConfig, { isServer: false }) before passing to createViteServer

Closes #13

Test plan

  • Unit test (dev-configure-vite.test.ts): mocks all deps, verifies configureVite is called with { isServer: false } and that the transformed config reaches createViteServer
  • E2E test (configure-vite.spec.ts): adds a pareto.config.js that injects a define global via configureVite, then a test page renders that value — confirms the hook is applied end-to-end in dev mode
  • All 202 unit tests pass
  • All 90 existing e2e tests pass (no regressions)

🤖 Generated with Claude Code

@netlify

netlify Bot commented Apr 8, 2026

Copy link
Copy Markdown

Deploy Preview for paretojs canceled.

Name Link
🔨 Latest commit e4ee2e9
🔍 Latest deploy log https://app.netlify.com/projects/paretojs/deploys/69d5f344b262ce0008762696

@github-actions

github-actions Bot commented Apr 8, 2026

Copy link
Copy Markdown

SSR Framework Benchmark Results

1 runs | 30s duration | 100 connections | 10 pipelining
Node v22.22.2 | linux x64 | 4 CPUs
2026-04-08T06:51:07.417Z

Requests/sec (median, higher is better)

Scenario Pareto Next.js React Router TanStack Start
Static SSR 2,139/s CV 0.0% 3,321/s CV 0.0% 981/s CV 0.0% 2,061/s CV 0.0%
Data Loading 2,656/s CV 0.0% 291/s CV 0.0% 966/s CV 0.0% 1,375/s CV 0.0%
Streaming SSR 247/s CV 0.0% 235/s CV 0.0% 247/s CV 0.0% 247/s CV 0.0%
API / JSON 3,562/s CV 0.0% 2,237/s CV 0.0% 1,908/s CV 0.0%

Latency p50 / p99 (median, lower is better)

Scenario Pareto Next.js React Router TanStack Start
Static SSR 450.0ms / 1.49s 244.0ms / 321.0ms 705.0ms / 7.43s 283.0ms / 309.0ms
Data Loading 358.0ms / 693.0ms 1.38s / 7.79s 755.0ms / 7.22s 361.0ms / 1.19s
Streaming SSR 201.0ms / 207.0ms 202.0ms / 221.0ms 201.0ms / 227.0ms 201.0ms / 208.0ms
API / JSON 275.0ms / 325.0ms 280.0ms / 346.0ms 493.0ms / 2.30s

Solo TTFB (1 connection, median, lower is better)

Scenario Pareto Next.js React Router TanStack Start
Static SSR 0.0ms / 2.0ms 0.0ms / 1.0ms 1.0ms / 2.0ms 0.0ms / 1.0ms
Data Loading 10.0ms / 11.0ms 12.0ms / 14.0ms 11.0ms / 13.0ms 11.0ms / 12.0ms
Streaming SSR 200.0ms / 297.0ms 202.0ms / 204.0ms 201.0ms / 278.0ms 200.0ms / 202.0ms
API / JSON 0.0ms / 0.0ms 0.0ms / 2.0ms 0.0ms / 2.0ms

Avg Response Size (lower is better)

Scenario Pareto Next.js React Router TanStack Start
Static SSR 6.9KB 25.5KB 9.5KB 7.7KB
Data Loading 4.0KB 8.6KB 7.5KB 4.8KB
Streaming SSR 3.4KB 7.3KB 6.1KB 4.2KB
API / JSON 3.2KB 2.9KB 2.8KB

Max Sustainable QPS (Ramp-up Load Test)

Criteria: p99 ≤ 500ms, error rate ≤ 1%
Steps: 1, 10, 50, 100, 200, 500, 1000 connections | 8s per step
Node v22.22.2 | linux x64

Summary

Scenario Pareto Next.js React Router TanStack Start
Static SSR 2,237/s 2,166/s 1,067/s 1,507/s
Data Loading 2,675/s 325/s 1,035/s 1,465/s
Streaming SSR 1,937/s 309/s 798/s 963/s
API / JSON 3,396/s 1,410/s 1,871/s

Static SSR — Detail

Connections Pareto QPS Pareto p99 Next.js QPS Next.js p99 React Router QPS React Router p99 TanStack Start QPS TanStack Start p99
1 1,788/s 2.0ms 1,753/s 1.0ms 855/s 2.0ms 1,266/s 1.0ms
10 2,175/s 7.0ms 2,134/s 9.0ms 1,033/s 14.0ms 1,507/s 13.0ms
50 2,213/s 46.0ms 2,143/s 44.0ms 1,050/s 62.0ms 1,469/s 55.0ms
100 2,190/s 52.0ms 2,136/s 64.0ms 1,061/s 121.0ms 1,477/s 76.0ms
200 2,213/s 268.0ms 2,107/s 113.0ms 1,067/s 214.0ms 1,474/s 150.0ms
500 2,185/s 423.0ms 2,166/s 142.0ms 1,044/s 483.0ms 1,470/s 201.0ms
1000 2,237/s 466.0ms 2,145/s 472.0ms 1,037/s 928.0ms 1,470/s 567.0ms

Data Loading — Detail

Connections Pareto QPS Pareto p99 Next.js QPS Next.js p99 React Router QPS React Router p99 TanStack Start QPS TanStack Start p99
1 96/s 13.0ms 78/s 14.0ms 87/s 13.0ms 90/s 12.0ms
10 743/s 18.0ms 325/s 42.0ms 544/s 23.0ms 802/s 15.0ms
50 1,863/s 31.0ms 325/s 185.0ms 1,035/s 79.0ms 1,465/s 47.0ms
100 2,329/s 79.0ms 316/s 342.0ms 1,009/s 136.0ms 1,331/s 103.0ms
200 2,659/s 91.0ms 309/s 750.0ms 1,015/s 240.0ms 1,285/s 253.0ms
500 2,675/s 412.0ms 313/s 1.69s 1,000/s 533.0ms 1,324/s 696.0ms
1000 2,559/s 622.0ms 982/s 1.05s 1,308/s 1.46s

Streaming SSR — Detail

Connections Pareto QPS Pareto p99 Next.js QPS Next.js p99 React Router QPS React Router p99 TanStack Start QPS TanStack Start p99
1 5/s 203.0ms 5/s 205.0ms 5/s 202.0ms 5/s 202.0ms
10 48/s 364.0ms 49/s 218.0ms 49/s 208.0ms 49/s 208.0ms
50 244/s 228.0ms 241/s 279.0ms 242/s 274.0ms 244/s 240.0ms
100 488/s 234.0ms 309/s 438.0ms 481/s 276.0ms 488/s 252.0ms
200 967/s 267.0ms 286/s 4.33s 798/s 367.0ms 963/s 306.0ms
500 1,937/s 416.0ms 774/s 1.09s 1,111/s 613.0ms
1000 2,024/s 639.0ms 728/s 1.61s 1,053/s 1.29s

API / JSON — Detail

Connections Pareto QPS Pareto p99 Next.js QPS Next.js p99 React Router QPS React Router p99 TanStack Start QPS TanStack Start p99
1 2,526/s 0.0ms 1,347/s 1.0ms 1,549/s 3.0ms
10 3,213/s 4.0ms 1,393/s 9.0ms 1,820/s 9.0ms
50 3,289/s 21.0ms 1,410/s 53.0ms 1,748/s 32.0ms
100 3,383/s 36.0ms 1,379/s 83.0ms 1,779/s 136.0ms
200 3,396/s 72.0ms 1,366/s 168.0ms 1,871/s 158.0ms
500 3,273/s 186.0ms 1,370/s 414.0ms 1,853/s 365.0ms
1000 3,217/s 354.0ms 1,373/s 1.16s 1,791/s 674.0ms
Build Size

> pareto-benchmarks@1.0.0 bench:size /home/runner/work/pareto/pareto/benchmarks
> tsx build-size.ts -- --skip-build --files

══════════════════════════════════════════════════════════════════════
  Build Artifact Size Comparison
══════════════════════════════════════════════════════════════════════

  Client JavaScript (sent to browser)

  Framework                    Raw            Gzip   Files
  ────────────────────────────────────────────────────────
  Pareto                   191.8KB          62.1KB       4
  Next.js                  757.5KB         232.9KB      17
  React Router             305.3KB          99.7KB       8
  TanStack Start           312.8KB         100.8KB       4

  Server Bundle

  Framework                    Raw            Gzip   Files
  ────────────────────────────────────────────────────────
  Pareto                    39.5KB           9.5KB       1
  Next.js                  631.6KB         176.4KB      22
  React Router              11.1KB           2.7KB       1
  TanStack Start           808.8KB         171.7KB      33

  Total (Client JS + CSS + Server)

  Framework              Raw Total      Gzip Total
  ────────────────────────────────────────────────
  Pareto                   231.3KB          71.6KB
  Next.js                    1.4MB         409.3KB
  React Router             316.4KB         102.4KB
  TanStack Start             1.1MB         272.5KB

  Pareto — Top Client JS Files

       189.6KB      60.8KB gzip  assets/js/client-entry.Bb6figk-.js
         1.1KB        608B gzip  assets/js/page.YrlBNOSR.js
          679B        455B gzip  assets/js/page.D4JrsU9a.js
          448B        304B gzip  assets/js/page.BTvb20MR.js

  Next.js — Top Client JS Files

       177.3KB      56.0KB gzip  chunks/framework-7ed0980919c40f0f.js
       169.0KB      53.1KB gzip  chunks/eff09a2a-4b5bcb2fe2a15130.js
       168.5KB      44.7KB gzip  chunks/164-eabaf2fe39aa1717.js
       124.7KB      36.2KB gzip  chunks/main-55a5b5a60eb4100d.js
       110.0KB      38.7KB gzip  chunks/polyfills-42372ed130431b0a.js
         3.2KB       1.6KB gzip  chunks/webpack-078f6dfb37dff419.js
         2.6KB        989B gzip  chunks/app/_not-found/page-0276c6de51078862.js
          620B        318B gzip  J23FW3OKXQGwzjIkmyV1m/_buildManifest.js
          555B        225B gzip  chunks/main-app-f85bade4b2f58de6.js
          235B        192B gzip  chunks/pages/_app-ea0fdd68be97fe36.js
    ... and 7 more files

  React Router — Top Client JS Files

       178.0KB      56.6KB gzip  assets/entry.client-Cj0j7gvK.js
       123.8KB      41.5KB gzip  assets/chunk-UVKPFVEO-u7LSJVe_.js
         1.7KB        407B gzip  assets/manifest-33bb6f1e.js
          567B        333B gzip  assets/stream-0JCzCtpA.js
          440B        283B gzip  assets/root-B3w8JxCz.js
          419B        286B gzip  assets/home-DL0lnQtw.js
          389B        279B gzip  assets/data-CYj-QIiD.js
            1B         21B gzip  assets/api-data-l0sNRNKZ.js

  TanStack Start — Top Client JS Files

       311.5KB      99.9KB gzip  assets/main-Dt0Lbs88.js
          556B        324B gzip  assets/stream-BVgHFqPg.js
          400B        266B gzip  assets/index-PjyfSO68.js
          383B        265B gzip  assets/data-DvwBUFyq.js

══════════════════════════════════════════════════════════════════════
  Use --files to see per-file breakdown
  Use --skip-build to skip the build step


Commit: 79038e3 | Workflow run

Replace the framework-specific configureVite hook with standard Vite
config. Users now customize Vite via vite.config.ts in their project
root, which Vite natively loads and merges in both dev and build modes.

This aligns with the Vite ecosystem convention (TanStack Start, Vike,
etc.) where frameworks do not expose custom config hooks — users write
standard vite.config.ts and the framework is either a Vite plugin or
passes its internal config as inline config to createServer/build.

Changes:
- Remove configureVite from ParetoConfig type and defaults
- Remove configureVite calls from createClientConfig/createServerConfig
- Add ssr.noExternal to dev server config (was missing, only in build)
- Add vite to peerDependencies so users can write vite.config.ts
- Add vite.config.ts e2e tests in both examples
- Convert examples to ESM (type: module, export default)
- Fix flaky stream e2e test (use waitUntil: commit for streaming pages)

Closes #13

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@childrentime childrentime force-pushed the fix/configure-vite-dev-mode branch from 8fec5ae to c5471d1 Compare April 8, 2026 04:18
- Bump @paretojs/core and create-pareto to 5.0.0
- Add CHANGELOG entry documenting the configureVite removal and
  migration to standard vite.config.ts
- Update config docs (en + zh, website + core) to replace the
  configureVite section with a vite.config.ts guide
- Update resource-routes doc cross-references

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
childrentime and others added 2 commits April 8, 2026 14:17
Set envPrefix: 'PARETO_' on the dev Vite instance (was previously only
on the build config). This ensures dev and build behave identically:
only PARETO_-prefixed env vars are inlined into client code via
import.meta.env, while unprefixed vars stay server-only via process.env.

Add e2e tests that verify the isolation end-to-end:
- Server loader can read both prefixed and unprefixed vars via process.env
- Client reads PARETO_ vars via import.meta.env
- Client cannot access unprefixed server-only vars like API_SECRET

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@childrentime childrentime merged commit 3e60033 into main Apr 8, 2026
7 checks passed
@childrentime childrentime deleted the fix/configure-vite-dev-mode branch April 8, 2026 06:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

configureVite is not applied in dev mode

1 participant