Agent skill

AI Code Mode

by TanStack in TanStack/ai

LLM-generated TypeScript execution in sandboxed environments: createCodeModeTool() with isolate drivers (createNodeIsolateDriver, createQuickJSIsolateDriver, createQuickJSBunIsolateDriver…

MITAuto-check passedAI & LLM Engineering

Install AI Code Mode

skills CLI
$ npx skills add TanStack/ai --skill ai-code-mode -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install TanStack/ai ai-code-mode --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/TanStack/ai.git skills-src && mkdir -p .claude/skills && cp -r skills-src/packages/ai-code-mode/skills/ai-code-mode .claude/skills/ai-code-mode && rm -rf skills-src

Use ~/.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/

Facts

Skill name
ai-code-mode
GitHub stars
3.2k
Used in
1 other repo
Token cost
~5.6k tokens
SKILL.md length
921 words
Files
1
Skills in repo
24
Repo updated
First seen
Licence
MIT

At a glance

LLM-generated TypeScript execution in sandboxed environments: createCodeModeTool() with isolate drivers (createNodeIsolateDriver, createQuickJSIsolateDriver, createQuickJSBunIsolateDriver…

  • Works in 4 steps: Choosing an Isolate Driver → Adding Persistent Snippets with… → Client-Side Execution Progress Display → …
  • AI & LLM Engineering work in your project
  • SKILL.md covers Setup, Core Patterns, Common Mistakes and Cross-References
  • Reaches api.weather.com and api.stocks.com; needs CODE_MODE_WORKER_SECRET and API_KEY

What it does

AI Code Mode is an agent skill from TanStack/ai. LLM-generated TypeScript execution in sandboxed environments: createCodeModeTool() with isolate drivers (createNodeIsolateDriver, createQuickJSIsolateDriver, createQuickJSBunIsolateDriver, createCloudflareIsolateDriver), codeModeWithSnippets() for persistent snippet libraries, trust strategies, snippet storage (FileSystem, LocalStorage, InMemory, Mongo), client-side execution progress via codemode: custom events in useChat.

Its SKILL.md is about 5.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 AI & LLM Engineering. It works with TypeScript, Node.js and WebAssembly. The repository describes itself as: 🤖 Type-safe, provider-agnostic TypeScript AI SDK for streaming chat, tool calling, agents, and multimodal apps across OpenAI, Anthropic, Gemini, React, Vue, Svelte, and Solid. The licence is MIT.

When your agent uses it

  • AI & LLM Engineering work in your project

Example prompts

  • “/ai-code-mode”

Requirements

  • Node.js
  • A credential in CODE_MODE_WORKER_SECRET

Workflow steps

4 steps, taken from the step headings in SKILL.md.

  1. Choosing an Isolate Driver
  2. Adding Persistent Snippets with codeModeWithSnippets()
  3. Client-Side Execution Progress Display
  4. Lazy Tools

What it can do on your machine

Read from SKILL.md and the folder at commit 5a41239. It shows what the files ask for, not the result of running them.

  • Tool permissions

    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.

  • Runs code

    No scripts in the folder and no shell commands in SKILL.md (its code samples are typescript).

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    Hosts in commands or code, which the agent is likely to contact:

    • api.weather.com
    • api.stocks.com

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names these keys or tokens, usually read from environment variables:

    • CODE_MODE_WORKER_SECRET
    • API_KEY

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

AI Code Mode loads about 5.6k tokens when it runs. Until then it costs about 111 tokens; SKILL.md has 921 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~111
When it runs · the whole SKILL.md, loaded when a task matches
~5.6k

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.

Safety

Auto-check passed

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.

SKILL.md

The full file from TanStack/ai at commit 5a41239, republished under its MIT licence (© TanStack). 921 words, ~5,613 tokens.

Download SKILL.mdSave it as .claude/skills/ai-code-mode/SKILL.md (or your agent's skills folder).
name
ai-code-mode
description
LLM-generated TypeScript execution in sandboxed environments: createCodeModeTool() with isolate drivers (createNodeIsolateDriver, createQuickJSIsolateDriver, createQuickJSBunIsolateDriver, createCloudflareIsolateDriver), codeModeWithSnippets() for persistent snippet libraries, trust strategies, snippet storage (FileSystem, LocalStorage, InMemory, Mongo), client-side execution progress via code_mode:* custom events in useChat.
type
core
library
tanstack-ai
library_version
0.3.8
sources
TanStack/ai:docs/code-mode/code-mode.md, TanStack/ai:docs/code-mode/code-mode-isolates.md, TanStack/ai:docs/code-mode/code-mode-with-snippets.md…

Note: This skill requires familiarity with ai-core and ai-core/chat-experience. Code Mode is always used on top of a chat experience.

Setup

Complete Code Mode setup with Node.js isolate driver:

typescript
import { chat, toServerSentEventsResponse, toolDefinition } from '@tanstack/ai'
import { openaiText } from '@tanstack/ai-openai'
import { createCodeModeTool } from '@tanstack/ai-code-mode'
import { createNodeIsolateDriver } from '@tanstack/ai-isolate-node'
import { z } from 'zod'

// Define a tool that code can call
const fetchWeather = toolDefinition({
  name: 'fetchWeather',
  description: 'Get current weather for a city',
  inputSchema: z.object({ city: z.string() }),
  outputSchema: z.object({ temp: z.number(), condition: z.string() }),
}).server(async ({ city }) => {
  const res = await fetch(`https://api.weather.com/${city}`)
  return res.json()
})

// Create code mode tool with Node isolate
const codeModeTool = createCodeModeTool({
  driver: createNodeIsolateDriver({
    memoryLimit: 128,
    timeout: 30000,
  }),
  tools: [fetchWeather],
})

// Use in chat
export async function POST(request: Request) {
  const { messages } = await request.json()

  const stream = chat({
    adapter: openaiText('gpt-5.5'),
    messages,
    tools: [codeModeTool],
  })

  return toServerSentEventsResponse(stream)
}

The recommended higher-level entry point is createCodeMode(), which returns both the tool and a matching system prompt:

typescript
import { chat, toServerSentEventsResponse, toolDefinition } from '@tanstack/ai'
import { createCodeMode } from '@tanstack/ai-code-mode'
import { createNodeIsolateDriver } from '@tanstack/ai-isolate-node'
import { openaiText } from '@tanstack/ai-openai'
import { z } from 'zod'

const fetchWeather = toolDefinition({
  name: 'fetchWeather',
  description: 'Get current weather for a city',
  inputSchema: z.object({ city: z.string() }),
  outputSchema: z.object({ temp: z.number(), condition: z.string() }),
}).server(async ({ city }) => {
  const res = await fetch(`https://api.weather.com/${city}`)
  return res.json()
})

const { tool, systemPrompt } = createCodeMode({
  driver: createNodeIsolateDriver(),
  tools: [fetchWeather],
  timeout: 30_000,
})

export async function POST(request: Request) {
  const { messages } = await request.json()

  const stream = chat({
    adapter: openaiText('gpt-5.5'),
    systemPrompts: ['You are a helpful assistant.', systemPrompt],
    tools: [tool],
    messages,
  })

  return toServerSentEventsResponse(stream)
}

createCodeMode calls createCodeModeTool and createCodeModeSystemPrompt internally. The system prompt includes generated TypeScript type stubs for each tool so the LLM writes correct calls.

Core Patterns

1. Choosing an Isolate Driver

Four drivers implement the IsolateDriver interface. All are interchangeable.

Node.js (createNodeIsolateDriver) -- Full V8 with JIT. Fastest option. Requires isolated-vm native C++ addon.

typescript
import { createNodeIsolateDriver } from '@tanstack/ai-isolate-node'

const driver = createNodeIsolateDriver({
  memoryLimit: 128, // MB, default 128
  timeout: 30_000, // ms, default 30000
  // skipProbe: false -- set true only after verifying compatibility
})

QuickJS (createQuickJSIsolateDriver) -- WASM-based, no native deps. Works in Node.js, browsers, Deno, Bun, and edge runtimes. Slower (interpreted, no JIT). Limited stdlib (no File I/O).

typescript
import { createQuickJSIsolateDriver } from '@tanstack/ai-isolate-quickjs'

const driver = createQuickJSIsolateDriver({
  memoryLimit: 128, // MB, default 128
  timeout: 30_000, // ms, default 30000
  maxStackSize: 524288, // bytes, default 512 KiB
})

QuickJS Bun (createQuickJSBunIsolateDriver) -- Native QuickJS on the Bun runtime via bun:ffi. Requires Bun >= 1.3.14 (throws a descriptive error on Node.js). No native deps or build step. Each context gets a dedicated QuickJS runtime with its own memory limit, stack size, and interrupt-based timeout. Recommended QuickJS option on Bun, where the WASM driver's asyncify bridge is unreliable for async host tool calls.

typescript
import { createQuickJSBunIsolateDriver } from '@tanstack/ai-isolate-quickjs-bun'

const driver = createQuickJSBunIsolateDriver({
  memoryLimit: 128, // MB, default 128
  timeout: 30_000, // ms, default 30000
  maxStackSize: 524288, // bytes, default 512 KiB
})

Cloudflare (createCloudflareIsolateDriver) -- Edge execution via a deployed Cloudflare Worker. Requires a workerUrl pointing to your deployed worker. Network latency on each tool call.

typescript
import { createCloudflareIsolateDriver } from '@tanstack/ai-isolate-cloudflare'

const driver = createCloudflareIsolateDriver({
  workerUrl: 'https://my-code-mode-worker.my-account.workers.dev',
  authorization: process.env.CODE_MODE_WORKER_SECRET,
  timeout: 30_000, // ms, default 30000
  maxToolRounds: 10, // max tool-call/result cycles, default 10
})
DriverBest forNative depsBrowser supportPerformance
NodeServer-side Node.jsYes (C++ addon)NoFast (V8 JIT)
QuickJSBrowsers, edge, portabilityNone (WASM)YesSlower (interpreted)
QuickJS BunBun serversNoneNoFast (native QuickJS)
CloudflareEdge deploymentsNoneN/AFast (V8 on edge)
2. Adding Persistent Snippets with codeModeWithSnippets()

Snippets let the LLM save reusable code snippets. On future requests, relevant snippets are loaded and exposed as callable tools.

typescript
import {
  chat,
  maxIterations,
  toServerSentEventsResponse,
  toolDefinition,
} from '@tanstack/ai'
import { createNodeIsolateDriver } from '@tanstack/ai-isolate-node'
import {
  codeModeWithSnippets,
  createDefaultTrustStrategy,
} from '@tanstack/ai-code-mode-snippets'
import { createFileSnippetStorage } from '@tanstack/ai-code-mode-snippets/storage'
import { openaiText } from '@tanstack/ai-openai'
import { z } from 'zod'

const fetchWeather = toolDefinition({
  name: 'fetchWeather',
  description: 'Get current weather for a city',
  inputSchema: z.object({ city: z.string() }),
  outputSchema: z.object({ temp: z.number(), condition: z.string() }),
}).server(async ({ city }) => {
  const res = await fetch(`https://api.weather.com/${city}`)
  return res.json()
})

// Trust strategies control how snippets earn trust through executions
// Default (createDefaultTrustStrategy): untrusted -> provisional (10+ runs, >=90%) -> trusted (100+ runs, >=95%)
// Relaxed (createRelaxedTrustStrategy): untrusted -> provisional (3+ runs, >=80%) -> trusted (10+ runs, >=90%)
// Always trusted (createAlwaysTrustedStrategy): immediately trusted (dev/testing)
// Custom (createCustomTrustStrategy): configurable thresholds
const trustStrategy = createDefaultTrustStrategy()

// Storage options: file system (production) or memory (testing)
const storage = createFileSnippetStorage({
  directory: './.snippets',
  trustStrategy,
})

const driver = createNodeIsolateDriver()

export async function POST(request: Request) {
  const { messages } = await request.json()

  // High-level API: automatic LLM-based snippet selection
  const { toolsRegistry, systemPrompt } = await codeModeWithSnippets({
    config: {
      driver,
      tools: [fetchWeather],
      timeout: 60_000,
      memoryLimit: 128,
    },
    adapter: openaiText('gpt-5-mini'), // cheap model for snippet selection
    snippets: {
      storage,
      maxSnippetsInContext: 5,
    },
    messages,
  })

  const stream = chat({
    adapter: openaiText('gpt-5.5'),
    tools: toolsRegistry.getTools(),
    messages,
    systemPrompts: ['You are a helpful assistant.', systemPrompt],
    agentLoopStrategy: maxIterations(15),
  })

  return toServerSentEventsResponse(stream)
}

The registry includes: execute_typescript, search_snippets, get_snippet, register_snippet, and one tool per selected snippet.

Custom trust strategy example:

typescript
import { createCustomTrustStrategy } from '@tanstack/ai-code-mode-snippets'

const strategy = createCustomTrustStrategy({
  initialLevel: 'untrusted',
  provisionalThreshold: { executions: 5, successRate: 0.85 },
  trustedThreshold: { executions: 50, successRate: 0.95 },
})

Storage implementations:

typescript
// File storage (production) -- persists snippets as files on disk
import { createFileSnippetStorage } from '@tanstack/ai-code-mode-snippets/storage'
const fileStorage = createFileSnippetStorage({ directory: './.snippets' })

// Memory storage (testing) -- in-memory, lost on restart
import { createMemorySnippetStorage } from '@tanstack/ai-code-mode-snippets/storage'
const memStorage = createMemorySnippetStorage()
3. Client-Side Execution Progress Display

Code Mode emits custom events during sandbox execution. Handle them in useChat via onCustomEvent.

Events emitted:

EventWhenKey fields
code_mode:execution_startedSandbox beginstimestamp, codeLength
code_mode:consoleEach console.log/error/warn/infolevel, message, timestamp
code_mode:external_callBefore an external_* function runsfunction, args, timestamp
code_mode:external_resultAfter successful external_* callfunction, result, duration
code_mode:external_errorWhen external_* call failsfunction, error, duration
tsx
import { useCallback, useRef, useState } from 'react'
import { useChat, fetchServerSentEvents } from '@tanstack/ai-react'

interface VMEvent {
  id: string
  eventType: string
  data: unknown
  timestamp: number
}

export function CodeModeChat() {
  const [toolCallEvents, setToolCallEvents] = useState<
    Map<string, Array<VMEvent>>
  >(new Map())
  const eventIdCounter = useRef(0)

  const handleCustomEvent = useCallback(
    (eventType: string, data: unknown, context: { toolCallId?: string }) => {
      const { toolCallId } = context
      if (!toolCallId) return

      const event: VMEvent = {
        id: `event-${eventIdCounter.current++}`,
        eventType,
        data,
        timestamp: Date.now(),
      }

      setToolCallEvents((prev) => {
        const next = new Map(prev)
        const events = next.get(toolCallId) || []
        next.set(toolCallId, [...events, event])
        return next
      })
    },
    [],
  )

  const { messages, sendMessage, isLoading } = useChat({
    connection: fetchServerSentEvents('/api/chat'),
    onCustomEvent: handleCustomEvent,
  })

  return (
    <div>
      {messages.map((message) => (
        <div key={message.id}>
          {message.parts.map((part, index) => {
            if (part.type === 'text') {
              return <p key={index}>{part.content}</p>
            }
            if (
              part.type === 'tool-call' &&
              part.name === 'execute_typescript'
            ) {
              const events = toolCallEvents.get(part.id) || []
              return (
                <div key={part.id}>
                  <pre>{JSON.parse(part.arguments)?.typescriptCode}</pre>
                  {events.map((evt) => (
                    <div key={evt.id}>
                      {evt.eventType}: {JSON.stringify(evt.data)}
                    </div>
                  ))}
                  {part.output && (
                    <pre>{JSON.stringify(part.output, null, 2)}</pre>
                  )}
                </div>
              )
            }
            return null
          })}
        </div>
      ))}
    </div>
  )
}

The onCustomEvent callback signature is identical across all framework integrations (@tanstack/ai-react, @tanstack/ai-solid, @tanstack/ai-vue, @tanstack/ai-svelte):

typescript
type OnCustomEvent = (
  eventType: string,
  data: unknown,
  context: { toolCallId?: string },
) => void

Snippet-specific events (when using codeModeWithSnippets):

EventWhenKey fields
code_mode:snippet_callSnippet tool invokedsnippet, input, timestamp
code_mode:snippet_resultSnippet completedsnippet, result, duration
code_mode:snippet_errorSnippet failedsnippet, error, duration
snippet:registeredNew snippet savedid, name, description
4. Lazy Tools

When a large tool catalog would bloat the execute_typescript system prompt, mark low-priority tools lazy: true. Lazy tools are kept out of the full type-stub documentation and listed in a compact "Discoverable APIs" catalog instead. All sandbox bindings are always injected — lazy defers documentation, not callability.

Marking a tool lazy:

typescript
import { toolDefinition } from '@tanstack/ai'
import { z } from 'zod'

const eagerTool = toolDefinition({
  name: 'fetchWeather',
  description: 'Get current weather for a city',
  inputSchema: z.object({ city: z.string() }),
  outputSchema: z.object({ temp: z.number(), condition: z.string() }),
}).server(async ({ city }) => {
  const res = await fetch(`https://api.weather.com/${city}`)
  return res.json()
})

const rarelyUsedTool = toolDefinition({
  name: 'fetchStocks',
  description: 'Get stock prices for a ticker. Returns a price quote.',
  inputSchema: z.object({ ticker: z.string() }),
  outputSchema: z.object({ price: z.number() }),
  lazy: true, // <-- opt out of full system-prompt documentation
}).server(async ({ ticker }) => {
  const res = await fetch(`https://api.stocks.com/${ticker}`)
  return res.json()
})

createCodeMode return shape:

createCodeMode() returns { tool, discoveryTool, tools, systemPrompt }. When lazy tools are present discoveryTool is a discover_tools server tool; otherwise it is null. Always spread tools (not just tool) into chat() so the discovery tool is registered:

typescript
import { chat, toServerSentEventsResponse } from '@tanstack/ai'
import { createCodeMode } from '@tanstack/ai-code-mode'
import { createNodeIsolateDriver } from '@tanstack/ai-isolate-node'
import { openaiText } from '@tanstack/ai-openai'

const { tools, systemPrompt } = createCodeMode({
  driver: createNodeIsolateDriver(),
  tools: [eagerTool, rarelyUsedTool], // rarelyUsedTool has lazy: true
})

export async function POST(request: Request) {
  const { messages } = await request.json()

  const stream = chat({
    adapter: openaiText('gpt-5.5'),
    systemPrompts: ['You are a helpful assistant.', systemPrompt],
    tools: [...tools], // spread tools, not just tool
    messages,
  })

  return toServerSentEventsResponse(stream)
}

tools equals [tool] when there are no lazy tools (backward compatible) and [tool, discoveryTool] when lazy tools exist.

discover_tools flow:

When the model encounters a lazy tool it has not seen before, it calls discover_tools with the bare name (no external_ prefix). The tool returns each requested tool's TypeScript type stub and description. The model then writes correctly-typed external_<name> calls inside execute_typescript.

text
Model sees: "Discoverable APIs: external_fetchStocks"
Model calls: discover_tools({ toolNames: ["fetchStocks"] })
Response:    { tools: [{ name: "external_fetchStocks", description: "...", typeStub: "declare function external_fetchStocks(...)" }] }
Model writes inside execute_typescript: const result = await external_fetchStocks({ ticker: "AAPL" })

lazyToolsConfig.includeDescription:

Control how much of each lazy tool's description appears in the Discoverable APIs catalog (the pre-discovery list):

ValueCatalog entry
'none'external_fetchStocks (name only — default)
'first-sentence'external_fetchStocks — Get stock prices.
'full'external_fetchStocks — Get stock prices. Returns a price quote.
typescript
import { createCodeMode } from '@tanstack/ai-code-mode'
import { createNodeIsolateDriver } from '@tanstack/ai-isolate-node'
import { eagerTool, rarelyUsedTool } from './tools'

const { tools, systemPrompt } = createCodeMode({
  driver: createNodeIsolateDriver(),
  tools: [eagerTool, rarelyUsedTool],
  lazyToolsConfig: { includeDescription: 'first-sentence' },
})

The same lazyToolsConfig option is accepted by plain chat() for its own lazy-tool discovery catalog (see ai-core/tool-calling/SKILL.md).

Show full SKILL.md (305 more words)Show less

Common Mistakes

CRITICAL: Passing API keys or secrets to the sandbox environment

Code Mode executes LLM-generated code. Any secrets available in the sandbox context are accessible to generated code, which could exfiltrate them via tool calls. Never pass API keys, database credentials, or tokens into the sandbox. Keep secrets in your tool server implementations, which run in the host process outside the sandbox.

Wrong:

typescript
import { toolDefinition } from '@tanstack/ai'
import { createCodeModeTool } from '@tanstack/ai-code-mode'
import { createNodeIsolateDriver } from '@tanstack/ai-isolate-node'
import { z } from 'zod'

const codeModeTool = createCodeModeTool({
  driver: createNodeIsolateDriver(),
  tools: [
    toolDefinition({
      name: 'callApi',
      description: 'Call an HTTP API',
      inputSchema: z.object({ url: z.string(), apiKey: z.string() }),
      outputSchema: z.any(),
    }).server(async ({ url, apiKey }) =>
      fetch(url, {
        headers: { Authorization: apiKey },
      }),
    ),
  ],
})

Right:

typescript
import { toolDefinition } from '@tanstack/ai'
import { createCodeModeTool } from '@tanstack/ai-code-mode'
import { createNodeIsolateDriver } from '@tanstack/ai-isolate-node'
import { z } from 'zod'

const codeModeTool = createCodeModeTool({
  driver: createNodeIsolateDriver(),
  tools: [
    toolDefinition({
      name: 'callApi',
      description: 'Call an HTTP API',
      inputSchema: z.object({ url: z.string() }),
      outputSchema: z.any(),
    }).server(async ({ url }) =>
      fetch(url, {
        headers: { Authorization: `Bearer ${process.env.API_KEY}` }, // secret stays in host
      }),
    ),
  ],
})

Source: docs/code-mode/code-mode.md

HIGH: Not setting timeout for code execution

LLM-generated code may contain infinite loops. The default timeout is 30s, but developers may override to 0 (no timeout). Always set an explicit, finite timeout.

Wrong:

typescript
import { createNodeIsolateDriver } from '@tanstack/ai-isolate-node'

const driver = createNodeIsolateDriver({ timeout: 0 })

Right:

typescript
import { createNodeIsolateDriver } from '@tanstack/ai-isolate-node'

const driver = createNodeIsolateDriver({ timeout: 30_000 })

Source: ai-code-mode source (default timeout in CodeModeToolConfig)

HIGH: Using Node isolated-vm driver without checking platform compatibility

isolated-vm requires native module compilation. An incompatible build (wrong Node.js version, missing build tools) causes segfaults that no JS error handling can catch. The driver runs a subprocess probe by default. Never set skipProbe: true unless you have independently verified compatibility. Use probeIsolatedVm() to check before creating the driver.

typescript
import {
  createNodeIsolateDriver,
  probeIsolatedVm,
} from '@tanstack/ai-isolate-node'

const probe = probeIsolatedVm()
if (!probe.compatible) {
  console.error('isolated-vm not compatible:', probe.error)
  // Fall back to QuickJS
}

// Never do this unless you verified compatibility yourself:
// const driver = createNodeIsolateDriver({ skipProbe: true })

Source: ai-isolate-node source (probeIsolatedVm implementation)

MEDIUM: Expecting identical behavior across isolate drivers

The four drivers have different capabilities. Same code may work in Node but fail elsewhere.

  • Node: Full V8 support, JIT compilation, configurable memory limit
  • QuickJS: Interpreted, limited stdlib (no File I/O), configurable stack size, asyncified execution (serialized through global queue)
  • QuickJS Bun: Bun runtime only (throws on Node.js), native QuickJS via bun:ffi, dedicated runtime per context with per-context memory/stack limits and normalized MemoryLimitError/StackOverflowError/TimeoutError
  • Cloudflare: Network latency per tool call round-trip, maxToolRounds limit (default 10), requires deployed worker with UNSAFE_EVAL or eval unsafe binding

Test generated code against your target driver. If you need portability, target QuickJS's subset.

Source: docs/code-mode/code-mode-isolates.md

Cross-References

  • See also: ai-core/tool-calling/SKILL.md -- Code Mode is an alternative to standard tool calling for complex multi-step operations
  • See also: ai-core/chat-experience/SKILL.md -- Code Mode requires handling custom events in useChat

© TanStack, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in packages/ai-code-mode/skills/ai-code-mode of TanStack/ai.

Open the folder on GitHubat commit 5a41239

Used in 1 other repository

We found 1 copy of this SKILL.md (exact, near-identical or edited) in other folders, from 1 other GitHub owner. This page covers the copy in TanStack/ai, which our catalogue first saw on October 7, 2026.

Compare with similar skills

AI Code Mode 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.

AI Code Mode compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
AI Code Mode this skillTanStack/ai3.2k1 repos~5.6kAutomated safety check: PassMIT
Compromise NLP Libraryspencermountain/compromise12k—~2kAutomated safety check: PassMIT
Agent Squad for TypeScript2FastLabs/agent-squad7.8k—~4.3kAutomated safety check: PassApache-2.0
Transformers.jshuggingface/skills11k1 repos~6.2kAutomated safety check: PassApache-2.0
Transformers JSwaybarrios/opencode-power-pack533—~1.9kAutomated safety check: PassApache-2.0
Golem Add npm Packagegolemcloud/golem1.5k—~902Automated safety check: PassCustom licence

Similar skills

  • Compromise NLP Library

    spencermountain/compromise

    Helps write and debug JavaScript or TypeScript that uses the compromise English NLP library for matching, entity extraction, tagging and sentence transforms.

    12k GitHub stars~2k tokensUpdated yesterday
    AI & LLM EngineeringAuto-check passed
  • Agent Squad for TypeScript

    2FastLabs/agent-squad

    Guide to building Node.js and TypeScript apps on the agent-squad package: orchestrator, agent types, classifier routing, storage, retrievers and MCP tools.

    7.8k GitHub stars~4.3k tokensUpdated yesterday
    AI & LLM EngineeringAuto-check passed
  • Transformers.js

    huggingface/skills

    Official

    Runs pre-trained Hugging Face models in JavaScript or TypeScript with Transformers.js, in browsers or Node.js, Bun and Deno, for text, vision, audio and multimodal tasks.

    11k GitHub starsUsed in 1 repo~6.2k tokens
    AI & LLM EngineeringAuto-check passed
  • Transformers JS

    waybarrios/opencode-power-pack

    Run Hugging Face models in JavaScript or TypeScript with Transformers.js, WebGPU, or WASM across browser, Node.js, Bun, and Deno.

    533 GitHub stars~1.9k tokensUpdated yesterday
    AI & LLM EngineeringAuto-check passed
  • Golem Add npm Package

    golemcloud/golem

    Add a new npm package dependency to a TypeScript Golem project.

    1.5k GitHub stars~902 tokensUpdated today
    Auto-check passed
  • Golem JS Runtime

    golemcloud/golem

    JavaScript runtime environment for TypeScript and Scala Golem agents.

    1.5k GitHub stars~1.7k tokensUpdated today
    Auto-check passed

More from TanStack/ai

All 24 skills in this repo
  • I Have Adhd

    TanStack/ai

    A skill your agent uses when the user invokes /i-have-adhd, says they have ADHD, or asks for ADHD-friendly output.

    3.2k GitHub starsUsed in 5 repos~1.8k tokens
    Auto-check passed
  • PR Sweep

    TanStack/ai

    Sweep open (or listed) PRs with up to 100 parallel agents: security-scan outside contributors, rebase onto main when behind (push --force-with-lease), approve pending first-time-contributor CI when…

    3.2k GitHub stars~4.6k tokensUpdated today
    Auto-check passed
  • A skill your agent uses when wiring honcho() from @tanstack/ai-memory/honcho — a hosted memory adapter where recall is a dialectic answer over the user's representation (no discrete fragments).

    3.2k GitHub starsUsed in 1 repo~457 tokens
    Auto-check passed
  • A skill your agent uses when wiring inMemory() from @tanstack/ai-memory/in-memory — explains setup, options (embedder, extract, topK/minScore), when to pick it (dev/tests/single-process demos), and…

    3.2k GitHub starsUsed in 1 repo~448 tokens
    Auto-check passed
  • A skill your agent uses when wiring redis() from @tanstack/ai-memory/redis in production — covers client setup (ioredis or node-redis via fromNodeRedis), the storage model, client-side ranking…

    3.2k GitHub starsUsed in 1 repo~840 tokens
    Auto-check passed
  • A skill your agent uses when adding a public teaching example or a docs tutorial.

    3.2k GitHub stars~1.4k tokensUpdated today
    Auto-check passed

Questions about AI Code Mode

What does AI Code Mode do?

LLM-generated TypeScript execution in sandboxed environments: createCodeModeTool() with isolate drivers (createNodeIsolateDriver, createQuickJSIsolateDriver, createQuickJSBunIsolateDriver…. AI Code Mode is an agent skill from TanStack/ai. LLM-generated TypeScript execution in sandboxed environments: createCodeModeTool() with isolate drivers (createNodeIsolateDriver, createQuickJSIsolateDriver, createQuickJSBunIsolateDriver, createCloudflareIsolateDriver), codeModeWithSnippets() for persistent snippet libraries, trust strategies, snippet storage (FileSystem, LocalStorage, InMemory, Mongo), client-side execution progress via codemode: custom events in useChat.

When should I use AI Code Mode?

AI Code Mode fits situations like: AI & LLM Engineering work in your project.

How do I install AI Code Mode in Claude Code?

Run `npx skills add TanStack/ai --skill ai-code-mode -a claude-code`. Or copy the skill folder (packages/ai-code-mode/skills/ai-code-mode in TanStack/ai) into .claude/skills/ai-code-mode in your project. Claude Code loads it when a task matches its description.

How do I install AI Code Mode in Codex?

Run `npx skills add TanStack/ai --skill ai-code-mode -a codex`. Or copy the skill folder (packages/ai-code-mode/skills/ai-code-mode in TanStack/ai) into .agents/skills/ai-code-mode in your project. Codex loads it when a task matches its description.

Can I use AI Code Mode in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add TanStack/ai --skill ai-code-mode -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/ai-code-mode, .gemini/skills/ai-code-mode, .github/skills/ai-code-mode and .opencode/skills/ai-code-mode in your project.

What does AI Code Mode need to run?

Going by SKILL.md and its folder, AI Code Mode needs credentials named CODE_MODE_WORKER_SECRET and API_KEY. Our summary lists: Node.js; A credential in CODE_MODE_WORKER_SECRET.

Does AI Code Mode access the network?

SKILL.md names 2 domains. In commands or code: api.weather.com and api.stocks.com; the agent is likely to contact these when it follows the instructions. This is read from the text; nothing was executed.

Is AI Code Mode safe to install?

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.

What licence does AI Code Mode use?

AI Code Mode is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does AI Code Mode use?

About 5.6k tokens (SKILL.md is roughly 22k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to AI Code Mode?

Skills that share tags, products or a category with AI Code Mode: Compromise NLP Library (spencermountain/compromise, 12k stars), Agent Squad for TypeScript (2FastLabs/agent-squad, 7.8k stars), Transformers.js (huggingface/skills, 11k stars) and Transformers JS (waybarrios/opencode-power-pack, 533 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains AI Code Mode?

TanStack (a GitHub organization) maintains it in TanStack/ai, which has 3,169 GitHub stars. The repository holds 24 skills in this directory. The repository was last updated on October 7, 2026.

Source: TanStack/ai on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.