Qstash JS
upstash/qstash-js
Work with the QStash JavaScript/TypeScript SDK for serverless messaging, scheduling.
V8 JIT optimization patterns for writing high-performance JavaScript in Next.js server internals.
$ npx skills add vercel/next.js --skill v8-jit -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install vercel/next.js v8-jit --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/vercel/next.js.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/v8-jit .claude/skills/v8-jit && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "v8-jit" agent skill from https://github.com/vercel/next.js/tree/canary/.agents/skills/v8-jit into .claude/skills/v8-jit/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "v8-jit", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/vercel/next.js/tree/canary/.agents/skills/v8-jitType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add vercel/next.js --skill v8-jit -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install vercel/next.js v8-jit --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/vercel/next.js.git skills-src && mkdir -p .agents/skills && cp -r skills-src/.agents/skills/v8-jit .agents/skills/v8-jit && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "v8-jit" agent skill from https://github.com/vercel/next.js/tree/canary/.agents/skills/v8-jit into .agents/skills/v8-jit/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "v8-jit", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add vercel/next.js --skill v8-jit -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install vercel/next.js v8-jit --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/vercel/next.js.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/.agents/skills/v8-jit .cursor/skills/v8-jit && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "v8-jit" agent skill from https://github.com/vercel/next.js/tree/canary/.agents/skills/v8-jit into .cursor/skills/v8-jit/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "v8-jit", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/vercel/next.js.git --path .agents/skills/v8-jit--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add vercel/next.js --skill v8-jit -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install vercel/next.js v8-jit --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/vercel/next.js.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/.agents/skills/v8-jit .gemini/skills/v8-jit && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "v8-jit" agent skill from https://github.com/vercel/next.js/tree/canary/.agents/skills/v8-jit into .gemini/skills/v8-jit/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "v8-jit", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install vercel/next.js v8-jitInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add vercel/next.js --skill v8-jit -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/vercel/next.js.git skills-src && mkdir -p .github/skills && cp -r skills-src/.agents/skills/v8-jit .github/skills/v8-jit && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "v8-jit" agent skill from https://github.com/vercel/next.js/tree/canary/.agents/skills/v8-jit into .github/skills/v8-jit/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "v8-jit", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add vercel/next.js --skill v8-jit -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install vercel/next.js v8-jit --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/vercel/next.js.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/.agents/skills/v8-jit .opencode/skills/v8-jit && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "v8-jit" agent skill from https://github.com/vercel/next.js/tree/canary/.agents/skills/v8-jit into .opencode/skills/v8-jit/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "v8-jit", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
v8-jitV8 JIT optimization patterns for writing high-performance JavaScript in Next.js server internals.
V8 Jit is an agent skill from vercel/next.js, published by the product's own GitHub organization. V8 JIT optimization patterns for writing high-performance JavaScript in Next.js server internals. Use when writing or reviewing hot-path code in app-render, stream-utils, routing, caching, or any per-request code path. Covers hidden classes / shapes, monomorphic call sites, inline caches, megamorphic deopt, closure allocation, array packing, and profiling with --trace-opt / --trace-deopt.
Its SKILL.md is about 3.6k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.
It sits in Backend & APIs, covering Caching. It works with Next.js and JavaScript. The licence is MIT.
4 steps, taken from the first numbered list in SKILL.md.
Read from SKILL.md and the folder at commit a32ddfd. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Shell commands in SKILL.md call:
nodeFrom the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
V8 Jit loads about 3.6k tokens when it runs. Until then it costs about 100 tokens; SKILL.md has 1,061 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from vercel/next.js at commit a32ddfd, republished under its MIT licence (© vercel). 1,061 words, ~3,620 tokens.
.claude/skills/v8-jit/SKILL.md (or your agent's skills folder).Use this skill when writing or optimizing performance-critical code paths in Next.js server internals — especially per-request hot paths like rendering, streaming, routing, and caching.
V8 compiles JavaScript through multiple tiers:
Code starts in Ignition and is promoted to higher tiers based on execution frequency and collected type feedback. Turbofan produces the fastest machine code but bails out (deopts) when assumptions are violated at runtime.
The key principle: help V8 make correct speculative assumptions by keeping types, shapes, and control flow predictable.
Every JavaScript object has an internal "hidden class" (V8 calls it a Map, the spec calls it a Shape). Objects that share the same property names, added in the same order, share the same hidden class. This enables fast property access via inline caches.
// GOOD — consistent shape, single hidden class transition chain
class RequestContext {
url: string
method: string
headers: Record<string, string>
startTime: number
cached: boolean
constructor(url: string, method: string, headers: Record<string, string>) {
this.url = url
this.method = method
this.headers = headers
this.startTime = performance.now()
this.cached = false // always initialize, even defaults
}
}// BAD — conditional property addition creates multiple hidden classes
class RequestContext {
constructor(url, method, headers, options) {
this.url = url
this.method = method
if (options.timing) {
this.startTime = performance.now() // shape fork!
}
if (options.cache) {
this.cached = false // another shape fork!
}
this.headers = headers
}
}Rules:
null / undefined / false as default values rather than
omitting the property.delete a property on a hot object — it forces a transition to
dictionary mode (slow properties).obj.newProp = x) on objects
used in hot paths.// GOOD — same key order, shares hidden class
const a = { type: 'static', value: 1 }
const b = { type: 'dynamic', value: 2 }
// BAD — different key order, different hidden classes
const a = { type: 'static', value: 1 }
const b = { value: 2, type: 'dynamic' }Span in src/trace/trace.ts initializes all fields in the constructor in a
fixed order — name, parentId, attrs, status, id, _start, now.
This ensures all Span instances share one hidden class.
V8's inline caches (ICs) track the types/shapes seen at each call site or property access:
| IC State | Shapes Seen | Speed |
|---|---|---|
| Monomorphic | 1 | Fastest — single direct check |
| Polymorphic | 2–4 | Fast — linear search through cases |
| Megamorphic | 5+ | Slow — hash-table lookup, no inlining |
Once an IC goes megamorphic it does NOT recover (until the function is re-compiled). Megamorphic ICs also prevent Turbofan from inlining the function.
// GOOD — always called with the same argument shape
function processChunk(chunk: Uint8Array): void {
// chunk is always Uint8Array → monomorphic
}
// BAD — called with different types at the same call site
function processChunk(chunk: Uint8Array | Buffer | string): void {
// IC becomes polymorphic/megamorphic
}Practical strategies:
Buffer → Uint8Array
once) and keep internal functions monomorphic.null and undefined for the same parameter — pick one
sentinel value.// Entry point dispatches once
function handleStream(stream: ReadableStream | Readable) {
if (stream instanceof ReadableStream) {
return handleWebStream(stream) // monomorphic call
}
return handleNodeStream(stream) // monomorphic call
}This is the pattern used in stream-ops.ts and throughout the stream-utils
code (Node.js vs Web stream split via compile-time switcher).
Every closure captures its enclosing scope. Creating closures in hot loops or per-request paths generates GC pressure and can prevent escape analysis.
// BAD — closure allocated for every request
function handleRequest(req) {
stream.on('data', (chunk) => processChunk(chunk, req.id))
}
// GOOD — shared listener, request context looked up by stream
const requestIdByStream = new WeakMap()
function onData(chunk) {
const id = requestIdByStream.get(this)
if (id !== undefined) processChunk(chunk, id)
}
function processChunk(chunk, id) {
/* ... */
}
function handleRequest(req) {
requestIdByStream.set(stream, req.id)
stream.on('data', onData)
}// BEST — pre-allocate the callback as a method on a context object
class StreamProcessor {
id: string
constructor(id: string) {
this.id = id
}
handleChunk(chunk: Uint8Array) {
processChunk(chunk, this.id)
}
}// BAD — allocates a new object per iteration
for (const item of items) {
doSomething({ key: item.key, value: item.value })
}
// GOOD — reuse a mutable scratch object
const scratch = { key: '', value: '' }
for (const item of items) {
scratch.key = item.key
scratch.value = item.value
doSomething(scratch)
}node-stream-helpers.ts hoists encoder, BUFFER_TAGS, and tag constants to
module scope to avoid re-creating them on every request. The bufferIndexOf
helper uses Buffer.indexOf (C++ native) instead of a per-call JS loop,
eliminating per-chunk allocation.
V8 tracks array "element kinds" — an internal type tag that determines how elements are stored in memory:
| Element Kind | Description | Speed |
|---|---|---|
PACKED_SMI | Small integers only, no holes | Fastest |
PACKED_DOUBLE | Numbers only, no holes | Fast |
PACKED_ELEMENTS | Mixed/objects, no holes | Moderate |
HOLEY_* | Any of above with holes | Slower (extra bounds check) |
Transitions are one-way — once an array becomes HOLEY or PACKED_ELEMENTS,
it never goes back.
new Array(n) creates a holey array.
Prefer [] and push(), or use Array.from({ length: n }, initFn).arr[100] = x on an empty array creates 100 holes.[1, 'two', {}] immediately becomes PACKED_ELEMENTS.// GOOD — packed SMI array
const indices: number[] = []
for (let i = 0; i < n; i++) {
indices.push(i)
}
// BAD — holey from the start
const indices = new Array(n)
for (let i = 0; i < n; i++) {
indices[i] = i
}accumulateStreamChunks in app-render.tsx uses const staticChunks: Array<Uint8Array> = [] with push() — keeping a packed array of a single type
throughout its lifetime.
arguments object: using arguments in non-trivial ways (e.g.
arguments[i] with variable i, leaking arguments). Use rest params
instead.eval / with: prevents optimization entirely.for...in on hot objects; prefer
Object.keys() / Object.entries() when possible.// GOOD — predictable: always returns same type
function getStatus(code: number): string {
if (code === 200) return 'ok'
if (code === 404) return 'not found'
return 'error'
}
// BAD — returns different types
function getStatus(code: number): string | null | undefined {
if (code === 200) return 'ok'
if (code === 404) return null
// implicitly returns undefined
}switch Dispatch// WATCH OUT — `node.type` IC can go megamorphic if many shapes hit one site
function render(node) {
switch (node.type) {
case 'div':
return { tag: 'div', children: node.children }
case 'span':
return { tag: 'span', text: node.text }
case 'img':
return { src: node.src, alt: node.alt }
// Many distinct node layouts can make this dispatch site polymorphic
}
}This pattern is not always bad. Often the main pressure is at the shared
dispatch site (node.type), while properties used only in one branch stay
monomorphic within that branch. Reach for normalization/splitting only when
profiles show this site is hot and polymorphic.
Buffer.concat().string.indexOf() > regex for simple substring checks.new RegExp() inside a hot
function — hoist it to module scope.// GOOD — regex hoisted to module scope
const ROUTE_PATTERN = /^\/api\//
function isApiRoute(path: string): boolean {
return ROUTE_PATTERN.test(path)
}
// BAD — regex recreated on every call
function isApiRoute(path: string): boolean {
return /^\/api\//.test(path) // V8 may or may not cache this
}Map and Set vs Plain ObjectsMap is faster than plain objects for frequent additions/deletions
(avoids hidden class transitions and dictionary mode).Set is faster than obj[key] = true for membership checks with
dynamic keys.Object.freeze({...}) are fine — V8 optimizes them as constant.# Trace which functions get optimized
node --trace-opt server.js 2>&1 | grep "my-function-name"
# Trace deoptimizations (critical for finding perf regressions)
node --trace-deopt server.js 2>&1 | grep "my-function-name"
# Combined: see the full opt/deopt lifecycle
node --trace-opt --trace-deopt server.js 2>&1 | tee /tmp/v8-trace.log
# Show IC state transitions (verbose)
node --trace-ic server.js 2>&1 | tee /tmp/ic-trace.log
# Print optimized code (advanced)
node --print-opt-code --code-comments server.js# Profile a production build
node --cpu-prof --cpu-prof-dir=/tmp/profiles \
node_modules/.bin/next build
# Profile the server during a benchmark
node --cpu-prof --cpu-prof-dir=/tmp/profiles \
node_modules/.bin/next start &
# ... run benchmark ...
# Analyze in Chrome DevTools: chrome://inspect → Open dedicated DevTools
# Quick trace-deopt check on a specific test
node --trace-deopt $(which jest) --runInBand test/path/to/test.ts \
2>&1 | grep -i "deopt" | head -50% Natives (Development/Testing Only)With --allow-natives-syntax:
function hotFunction(x) {
return x + 1
}
// Force optimization
%PrepareFunctionForOptimization(hotFunction)
hotFunction(1)
hotFunction(2) % OptimizeFunctionOnNextCall(hotFunction)
hotFunction(3)
// Check optimization status
// 1 = optimized, 2 = not optimized, 3 = always optimized, 6 = maglev
console.log(%GetOptimizationStatus(hotFunction))delete on hot objectsMap/Set used for dynamic key collectionsarguments object — use rest paramstry/catch at function boundary, not inside tight loopsjoin() or Buffer.concat()string | null | undefined mixes)$dce-edge — DCE-safe require patterns (compile-time dead code)$runtime-debug — runtime bundle debugging and profiling workflow© vercel, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
Just SKILL.md in .agents/skills/v8-jit of vercel/next.js.
Open the folder on GitHubat commit a32ddfd
V8 Jit next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| V8 Jit this skillvercel/next.js | 143k | — | ~3.6k | Automated safety check: Pass | MIT | |
| Qstash JSupstash/qstash-js | 269 | 1 repos | ~746 | Automated safety check: Pass | MIT | |
| Holm Webvolfpeter/holm | 132 | — | ~1.2k | Automated safety check: Pass | MIT | |
| Documentation Guidevolfpeter/holm | 132 | — | ~1.4k | Automated safety check: Pass | MIT | |
| Apollo Clientapollographql/skills | 117 | — | ~1.9k | Automated safety check: Pass | MIT | |
| Nextjs Turbopackkurealnum/dotfiles | 290 | 5 repos | ~540 | Automated safety check: Pass | None |
upstash/qstash-js
Work with the QStash JavaScript/TypeScript SDK for serverless messaging, scheduling.
volfpeter/holm
A skill your agent uses when working on web apps built with holm, or to answer questions about holm.
volfpeter/holm
A skill your agent uses when writing or modifying documentation, guides, or example READMEs.
apollographql/skills
Guide for building React applications with Apollo Client 4.x.
kurealnum/dotfiles
Next.js 16+ and Turbopack — incremental bundling, FS caching, dev speed, and when to use Turbopack vs webpack.
jorgerosal/wordpress-skills
Headless WordPress and WPGraphQL review guidance. An agent skill from jorgerosal/wordpress-skills.
vercel/next.js
Manages stacked PRs and splits multi-part work into reviewable branches with gh-stack.
vercel/next.js
Benchmark React or Next.js changes on Vercel Sandbox VMs with paired A/B statistics: react PR/commit vs base, or Next.js PR/commit vs base, measured end-to-end through the bench/render-pipeline app…
vercel/next.js
Verify Next.js runtime behavior after editing app code. An agent skill from vercel/next.js.
vercel/next.js
Draw diagrams for the Next.js docs in the style of the ones already published there: the light/dark PNGs an mdx references with <Image srcLight="/docs/light/<name.png" srcDark="/docs/dark/<name.png".
vercel/next.js
Turn on Cache Components in a Next.js app and resolve the blocking routes it surfaces.
vercel/next.js
Build local React changes in the bundle variants consumed by Next.js, sync them into a local Next.js checkout, and test the resulting integration.
Works with
Categories
V8 JIT optimization patterns for writing high-performance JavaScript in Next.js server internals. js, published by the product's own GitHub organization.js server internals.
V8 Jit fits situations like: reviewing hot-path code in app-render; any per-request code path.
Run `npx skills add vercel/next.js --skill v8-jit -a claude-code`. Or copy the skill folder (.agents/skills/v8-jit in vercel/next.js) into .claude/skills/v8-jit in your project. Claude Code loads it when a task matches its description.
Run `npx skills add vercel/next.js --skill v8-jit -a codex`. Or copy the skill folder (.agents/skills/v8-jit in vercel/next.js) into .agents/skills/v8-jit in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add vercel/next.js --skill v8-jit -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/v8-jit, .gemini/skills/v8-jit, .github/skills/v8-jit and .opencode/skills/v8-jit in your project.
Going by SKILL.md and its folder, V8 Jit needs the command-line tools its instructions call (node). Our summary lists: Node.js.
SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
V8 Jit is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 3.6k tokens (SKILL.md is roughly 14k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with V8 Jit: Qstash JS (upstash/qstash-js, 269 stars), Holm Web (volfpeter/holm, 132 stars), Documentation Guide (volfpeter/holm, 132 stars) and Apollo Client (apollographql/skills, 117 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
vercel (a GitHub organization, an official publisher) maintains it in vercel/next.js, which has 143,241 GitHub stars. The repository holds 27 skills in this directory. The repository was last updated on October 8, 2026.
Source: vercel/next.js on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.