Skip to content

Commit 9bc50a8

Browse files
feedthejimclaude
andcommitted
perf(cli): single-process dev server with Rust CLI wrapper
Replace fork-based architecture with single Node.js process: - Add Rust CLI wrapper (`crates/next-cli/`) that handles: - NODE_OPTIONS (memory limits, source maps, inspect) - WATCHPACK_WATCHER_LIMIT for large projects - Restart loop (exit code 77) without Node.js overhead - Simplify next-dev.ts: remove fork(), IPC, child process management - Simplify start-server.ts: remove NEXT_PRIVATE_WORKER handling - Add shell entry points (bin/next, bin/next.cmd) that: - Use native binary when available (~10ms overhead) - Fall back to Node.js entry point - Add lazy loading for heavy modules: - tar (download-swc) - only needed for fallback download - edge-runtime sandbox - only needed for edge functions - MCP SDK - only needed when clients connect - Set up cross-platform release pipeline: - Build @next/cli-* for 8 platforms in CI - Publish as optional dependencies - Update install-native.mjs for development Saves ~35-50ms on dev server startup by eliminating parent Node.js process and fork overhead. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 2258256 commit 9bc50a8

File tree

25 files changed

+656
-246
lines changed

25 files changed

+656
-246
lines changed

.github/workflows/build_and_deploy.yml

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,18 @@ jobs:
430430
name: next-swc-binaries-${{ matrix.settings.target }}
431431
path: packages/next-swc/native/next-swc.*.node
432432

433+
# Build next-cli native binary (simple Rust CLI wrapper)
434+
- name: Build next-cli
435+
if: ${{ steps.check-did-build.outputs.DID_BUILD == 'true' }}
436+
run: cargo build --release --target ${{ matrix.settings.target }} -p next-cli
437+
438+
- name: Upload next-cli artifact
439+
if: ${{ steps.check-did-build.outputs.DID_BUILD == 'true' }}
440+
uses: actions/upload-artifact@v4
441+
with:
442+
name: next-cli-${{ matrix.settings.target }}
443+
path: target/${{ matrix.settings.target }}/release/next${{ matrix.settings.target == 'x86_64-pc-windows-msvc' && '.exe' || matrix.settings.target == 'aarch64-pc-windows-msvc' && '.exe' || '' }}
444+
433445
- name: Upload turbo summary artifact
434446
uses: actions/upload-artifact@v4
435447
with:
@@ -539,6 +551,28 @@ jobs:
539551
merge-multiple: true
540552
path: crates/wasm
541553

554+
- uses: actions/download-artifact@v4
555+
with:
556+
pattern: next-cli-*
557+
merge-multiple: false
558+
path: packages/next/bin
559+
560+
# Rename next-cli binaries to include platform in filename
561+
- name: Organize next-cli binaries
562+
run: |
563+
cd packages/next/bin
564+
for dir in next-cli-*/; do
565+
platform="${dir#next-cli-}"
566+
platform="${platform%/}"
567+
if [[ "$platform" == *"win32"* ]]; then
568+
mv "$dir/next.exe" "next-cli-${platform}.exe" 2>/dev/null || true
569+
else
570+
mv "$dir/next" "next-cli-${platform}" 2>/dev/null || true
571+
fi
572+
rmdir "$dir" 2>/dev/null || true
573+
done
574+
ls -la
575+
542576
- name: Create tarballs
543577
# github.event.after is available on push and pull_request#synchronize events.
544578
# For workflow_dispatch events, github.sha is the head commit.
@@ -604,6 +638,28 @@ jobs:
604638
merge-multiple: true
605639
path: crates/wasm
606640

641+
- uses: actions/download-artifact@v4
642+
with:
643+
pattern: next-cli-*
644+
merge-multiple: false
645+
path: packages/next/bin
646+
647+
# Rename next-cli binaries to include platform in filename
648+
- name: Organize next-cli binaries
649+
run: |
650+
cd packages/next/bin
651+
for dir in next-cli-*/; do
652+
platform="${dir#next-cli-}"
653+
platform="${platform%/}"
654+
if [[ "$platform" == *"win32"* ]]; then
655+
mv "$dir/next.exe" "next-cli-${platform}.exe" 2>/dev/null || true
656+
else
657+
mv "$dir/next" "next-cli-${platform}" 2>/dev/null || true
658+
fi
659+
rmdir "$dir" 2>/dev/null || true
660+
done
661+
ls -la
662+
607663
- run: npm i -g npm@10.4.0 # need latest version for provenance (pinning to avoid bugs)
608664
- run: echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> ~/.npmrc
609665
- run: ./scripts/publish-native.js

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,3 +63,7 @@ test-timings.json
6363

6464
# Storybook
6565
*storybook.log
66+
# Native CLI binaries (shell scripts next and next.cmd are committed)
67+
packages/next/bin/next-native
68+
packages/next/bin/next-native.exe
69+
packages/next/bin/next-cli-*

Cargo.lock

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ members = [
88
"crates/next-api",
99
"crates/next-build-test",
1010
"crates/next-build",
11+
"crates/next-cli",
1112
"crates/next-core",
1213
"crates/next-custom-transforms",
1314
"crates/next-taskless",

crates/next-cli/Cargo.toml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
[package]
2+
name = "next-cli"
3+
version = "0.1.0"
4+
edition = "2021"
5+
description = "Ultra-fast CLI wrapper for Next.js"
6+
license = "MIT"
7+
8+
[[bin]]
9+
name = "next"
10+
path = "src/main.rs"
11+
12+
[dependencies]
13+
# No dependencies - keeps binary tiny and compile fast
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"name": "@next/cli-darwin-arm64",
3+
"version": "0.0.0",
4+
"description": "Next.js CLI binary for darwin-arm64",
5+
"repository": {
6+
"type": "git",
7+
"url": "https://github.com/vercel/next.js",
8+
"directory": "crates/next-cli"
9+
},
10+
"os": [
11+
"darwin"
12+
],
13+
"cpu": [
14+
"arm64"
15+
],
16+
"bin": {
17+
"next-native": "next"
18+
},
19+
"files": [
20+
"next"
21+
],
22+
"license": "MIT",
23+
"engines": {
24+
"node": ">= 20"
25+
}
26+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"name": "@next/cli-darwin-x64",
3+
"version": "0.0.0",
4+
"description": "Next.js CLI binary for darwin-x64",
5+
"repository": {
6+
"type": "git",
7+
"url": "https://github.com/vercel/next.js",
8+
"directory": "crates/next-cli"
9+
},
10+
"os": [
11+
"darwin"
12+
],
13+
"cpu": [
14+
"x64"
15+
],
16+
"bin": {
17+
"next-native": "next"
18+
},
19+
"files": [
20+
"next"
21+
],
22+
"license": "MIT",
23+
"engines": {
24+
"node": ">= 20"
25+
}
26+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"name": "@next/cli-linux-arm64-gnu",
3+
"version": "0.0.0",
4+
"description": "Next.js CLI binary for linux-arm64-gnu",
5+
"repository": {
6+
"type": "git",
7+
"url": "https://github.com/vercel/next.js",
8+
"directory": "crates/next-cli"
9+
},
10+
"os": [
11+
"linux"
12+
],
13+
"cpu": [
14+
"arm64"
15+
],
16+
"bin": {
17+
"next-native": "next"
18+
},
19+
"files": [
20+
"next"
21+
],
22+
"license": "MIT",
23+
"engines": {
24+
"node": ">= 20"
25+
}
26+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"name": "@next/cli-linux-arm64-musl",
3+
"version": "0.0.0",
4+
"description": "Next.js CLI binary for linux-arm64-musl",
5+
"repository": {
6+
"type": "git",
7+
"url": "https://github.com/vercel/next.js",
8+
"directory": "crates/next-cli"
9+
},
10+
"os": [
11+
"linux"
12+
],
13+
"cpu": [
14+
"arm64"
15+
],
16+
"bin": {
17+
"next-native": "next"
18+
},
19+
"files": [
20+
"next"
21+
],
22+
"license": "MIT",
23+
"engines": {
24+
"node": ">= 20"
25+
}
26+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"name": "@next/cli-linux-x64-gnu",
3+
"version": "0.0.0",
4+
"description": "Next.js CLI binary for linux-x64-gnu",
5+
"repository": {
6+
"type": "git",
7+
"url": "https://github.com/vercel/next.js",
8+
"directory": "crates/next-cli"
9+
},
10+
"os": [
11+
"linux"
12+
],
13+
"cpu": [
14+
"x64"
15+
],
16+
"bin": {
17+
"next-native": "next"
18+
},
19+
"files": [
20+
"next"
21+
],
22+
"license": "MIT",
23+
"engines": {
24+
"node": ">= 20"
25+
}
26+
}

0 commit comments

Comments
 (0)