@vercel/next-browser 0.1.7 → 0.2.0
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 +148 -48
- package/dist/browser.js +362 -71
- package/dist/cli.js +108 -12
- package/dist/daemon.js +19 -3
- package/dist/paths.js +3 -1
- package/dist/suspense.js +502 -73
- package/package.json +12 -9
- package/dist/cloud-client.js +0 -72
- package/dist/cloud-daemon.js +0 -87
- package/dist/cloud-paths.js +0 -7
- package/dist/cloud.js +0 -230
package/README.md
CHANGED
|
@@ -1,81 +1,181 @@
|
|
|
1
1
|
# @vercel/next-browser
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
structured text.
|
|
3
|
+
React DevTools and the Next.js dev overlay as shell commands — component
|
|
4
|
+
trees, props, hooks, PPR shells, errors, network, accessibility snapshots —
|
|
5
|
+
structured text that agents can parse and act on.
|
|
7
6
|
|
|
8
|
-
|
|
9
|
-
`next-browser
|
|
7
|
+
An LLM can't click through a DevTools panel, but it can run
|
|
8
|
+
`next-browser snapshot`, read the output, `click e3`, and keep going. Each
|
|
10
9
|
command is a stateless one-shot against a long-lived browser daemon, so an
|
|
11
10
|
agent loop can fire them off without managing browser lifecycle.
|
|
12
11
|
|
|
13
12
|
## Getting started
|
|
14
13
|
|
|
15
|
-
|
|
14
|
+
**As a skill** (recommended) — from your Next.js repo:
|
|
16
15
|
|
|
17
|
-
|
|
16
|
+
```bash
|
|
17
|
+
npx skills add vercel-labs/next-browser
|
|
18
|
+
```
|
|
18
19
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
Works with Claude Code, Cursor, Cline, and [others](https://skills.sh).
|
|
21
|
+
Start your agent in the project and type `/next-browser` to invoke the
|
|
22
|
+
skill. It installs the CLI and Chromium if needed, asks for your dev server
|
|
23
|
+
URL, and from there it's pair programming — tell it what you're debugging
|
|
24
|
+
and it drives the browser for you.
|
|
22
25
|
|
|
23
|
-
|
|
26
|
+
**Manual install:**
|
|
24
27
|
|
|
25
|
-
|
|
28
|
+
```bash
|
|
29
|
+
pnpm add -g @vercel/next-browser # or npm, yarn
|
|
30
|
+
playwright install chromium
|
|
31
|
+
```
|
|
26
32
|
|
|
27
|
-
|
|
33
|
+
Requires Node >= 20.
|
|
28
34
|
|
|
29
|
-
|
|
30
|
-
globally** if it's missing (plus `playwright install chromium`).
|
|
35
|
+
## Commands
|
|
31
36
|
|
|
32
|
-
|
|
33
|
-
browser, and from there it's **pair programming** — tell it what you're
|
|
34
|
-
debugging and it drives the tree, navigates pages, inspects components,
|
|
35
|
-
and reads errors for you.
|
|
37
|
+
### Browser lifecycle
|
|
36
38
|
|
|
37
|
-
|
|
39
|
+
| Command | Description |
|
|
40
|
+
| ------------------------------------ | -------------------------------------------------- |
|
|
41
|
+
| `open <url> [--cookies-json <file>]` | Launch browser and navigate (with optional cookies) |
|
|
42
|
+
| `close` | Close browser and kill daemon |
|
|
38
43
|
|
|
39
|
-
|
|
40
|
-
scripting it yourself.
|
|
44
|
+
### Navigation
|
|
41
45
|
|
|
42
|
-
|
|
46
|
+
| Command | Description |
|
|
47
|
+
| ------------------ | --------------------------------------------------------- |
|
|
48
|
+
| `goto <url>` | Full-page navigation (new document load) |
|
|
49
|
+
| `ssr-goto <url>` | Navigate blocking external scripts (inspect SSR shell) |
|
|
50
|
+
| `push [path]` | Client-side navigation (interactive picker if no path) |
|
|
51
|
+
| `back` | Go back in history |
|
|
52
|
+
| `reload` | Reload current page |
|
|
53
|
+
| `restart-server` | Restart the Next.js dev server (clears caches) |
|
|
43
54
|
|
|
44
|
-
|
|
55
|
+
### Inspection
|
|
45
56
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
57
|
+
| Command | Description |
|
|
58
|
+
| ----------------- | ------------------------------------------------------------- |
|
|
59
|
+
| `tree` | Full React component tree (hierarchy, IDs, keys) |
|
|
60
|
+
| `tree <id>` | Inspect one component (props, hooks, state, source location) |
|
|
61
|
+
| `snapshot` | Accessibility tree with `[ref=eN]` markers on interactive elements |
|
|
62
|
+
| `errors` | Build and runtime errors for the current page |
|
|
63
|
+
| `logs` | Recent dev server log output |
|
|
64
|
+
| `network [idx]` | List network requests, or inspect one (headers, body) |
|
|
65
|
+
| `screenshot` | Full-page PNG to a temp file |
|
|
49
66
|
|
|
50
|
-
|
|
67
|
+
### Interaction
|
|
51
68
|
|
|
52
|
-
|
|
69
|
+
| Command | Description |
|
|
70
|
+
| ---------------------------- | ---------------------------------------------------------- |
|
|
71
|
+
| `click <ref\|text\|selector>` | Click via real pointer events (works with Radix, Headless UI) |
|
|
72
|
+
| `fill <ref\|selector> <value>` | Fill a text input or textarea |
|
|
73
|
+
| `eval [ref] <script>` | Run JS in page context (supports `--file` and stdin) |
|
|
74
|
+
| `viewport [WxH]` | Show or set viewport size |
|
|
75
|
+
|
|
76
|
+
### Performance & PPR
|
|
77
|
+
|
|
78
|
+
| Command | Description |
|
|
79
|
+
| -------------- | ------------------------------------------------------------ |
|
|
80
|
+
| `perf [url]` | Core Web Vitals + React hydration timing in one pass |
|
|
81
|
+
| `ppr lock` | Freeze dynamic content to inspect the static shell |
|
|
82
|
+
| `ppr unlock` | Resume dynamic content and print shell analysis |
|
|
83
|
+
|
|
84
|
+
### Next.js MCP
|
|
85
|
+
|
|
86
|
+
| Command | Description |
|
|
87
|
+
| -------------- | ----------------------------------------------- |
|
|
88
|
+
| `page` | Route segments for the current URL |
|
|
89
|
+
| `project` | Project root and dev server URL |
|
|
90
|
+
| `routes` | All app router routes |
|
|
91
|
+
| `action <id>` | Inspect a server action by ID |
|
|
53
92
|
|
|
93
|
+
## Examples
|
|
94
|
+
|
|
95
|
+
**Inspect what's on the page and interact with it:**
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
$ next-browser open http://localhost:3000
|
|
99
|
+
$ next-browser snapshot
|
|
100
|
+
- navigation "Main"
|
|
101
|
+
- link "Home" [ref=e0]
|
|
102
|
+
- link "Dashboard" [ref=e1]
|
|
103
|
+
- main
|
|
104
|
+
- heading "Settings"
|
|
105
|
+
- tablist
|
|
106
|
+
- tab "General" [ref=e2] (selected)
|
|
107
|
+
- tab "Security" [ref=e3]
|
|
108
|
+
|
|
109
|
+
$ next-browser click e3
|
|
110
|
+
clicked
|
|
111
|
+
|
|
112
|
+
$ next-browser snapshot
|
|
113
|
+
- tablist
|
|
114
|
+
- tab "General" [ref=e0]
|
|
115
|
+
- tab "Security" [ref=e1] (selected)
|
|
54
116
|
```
|
|
55
|
-
open <url> [--cookies-json <file>] launch browser and navigate
|
|
56
|
-
close close browser and daemon
|
|
57
117
|
|
|
58
|
-
|
|
59
|
-
push [path] client-side navigation (interactive picker if no path)
|
|
60
|
-
back go back in history
|
|
61
|
-
reload reload current page
|
|
62
|
-
capture-goto [url] capture loading sequence (PPR shell → hydration → data)
|
|
63
|
-
restart-server restart the Next.js dev server (clears fs cache)
|
|
118
|
+
**Profile page load performance:**
|
|
64
119
|
|
|
65
|
-
|
|
66
|
-
|
|
120
|
+
```
|
|
121
|
+
$ next-browser perf http://localhost:3000/dashboard
|
|
122
|
+
# Page Load Profile — http://localhost:3000/dashboard
|
|
123
|
+
|
|
124
|
+
## Core Web Vitals
|
|
125
|
+
TTFB 42ms
|
|
126
|
+
LCP 1205.3ms (img: /_next/image?url=...)
|
|
127
|
+
CLS 0.03
|
|
128
|
+
|
|
129
|
+
## React Hydration — 65.5ms (466.2ms → 531.7ms)
|
|
130
|
+
Hydrated 65.5ms (466.2 → 531.7)
|
|
131
|
+
Commit 2.0ms (531.7 → 533.7)
|
|
132
|
+
...
|
|
133
|
+
```
|
|
67
134
|
|
|
68
|
-
|
|
69
|
-
tree <id> inspect component (props, hooks, state, source)
|
|
135
|
+
**Debug the PPR shell:**
|
|
70
136
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
137
|
+
```
|
|
138
|
+
$ next-browser ppr lock
|
|
139
|
+
locked
|
|
140
|
+
$ next-browser goto http://localhost:3000/dashboard
|
|
141
|
+
$ next-browser screenshot
|
|
142
|
+
/var/folders/.../next-browser-screenshot.png
|
|
143
|
+
$ next-browser ppr unlock
|
|
144
|
+
# PPR Shell Analysis — 131 boundaries: 3 dynamic holes, 128 static
|
|
145
|
+
|
|
146
|
+
## Quick Reference
|
|
147
|
+
| Boundary | Type | Primary blocker | Source |
|
|
148
|
+
| --- | --- | --- | --- |
|
|
149
|
+
| TrackedSuspense | component | usePathname (client-hook) | tracked-suspense.js |
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
**Inspect a React component:**
|
|
74
153
|
|
|
75
|
-
errors show build/runtime errors
|
|
76
|
-
logs show recent dev server log output
|
|
77
|
-
network [idx] list network requests, or inspect one
|
|
78
154
|
```
|
|
155
|
+
$ next-browser tree
|
|
156
|
+
0 38167 - Root
|
|
157
|
+
1 38168 38167 HeadManagerContext.Provider
|
|
158
|
+
2 38169 38168 Root
|
|
159
|
+
...
|
|
160
|
+
224 46375 46374 DeploymentsProvider
|
|
161
|
+
|
|
162
|
+
$ next-browser tree 46375
|
|
163
|
+
path: Root > ... > DeploymentsProvider
|
|
164
|
+
DeploymentsProvider #46375
|
|
165
|
+
props:
|
|
166
|
+
children: [<Lazy />, <Lazy />, <span />, <Lazy />, <Lazy />]
|
|
167
|
+
hooks:
|
|
168
|
+
IsMobile: undefined (1 sub)
|
|
169
|
+
Router: undefined (2 sub)
|
|
170
|
+
source: app/.../deployments/_parts/context.tsx:180:10
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
## How it works
|
|
174
|
+
|
|
175
|
+
A daemon process launches Chromium with the React DevTools extension
|
|
176
|
+
pre-loaded and listens on a Unix domain socket (named pipe on Windows).
|
|
177
|
+
CLI commands send JSON-RPC messages to the daemon and print the response.
|
|
178
|
+
The browser stays open across commands — no per-command startup cost.
|
|
79
179
|
|
|
80
180
|
## License
|
|
81
181
|
|