The Web Framework
Built for AI Agents.

MCP DevTools. Structured errors. Runtime guardrails. Your AI writes better code with What Framework.

$ npx create-what my-app Click to copy
Counter.jsx
import { mount, signal, computed } from 'what-framework'

function Counter() {
  const count = signal(0)
  const doubled = computed(() => count() * 2)

  return (
    <div>
      <button onClick={() => count(c => c + 1)}>
        Count: {count()}
      </button>
      <p>Doubled: {doubled()}</p>
    </div>
  )
}

mount(<Counter />, '#app')
The Problem

Every framework was designed
before AI wrote code.

AI agents generate more frontend code every month. But existing frameworks give them nothing to work with.

Cryptic Errors

Stack traces full of minified internals. "Cannot read property of undefined" with no hint where the signal, effect, or component went wrong. Agents guess, retry, break more things.

No State Inspection

When an agent builds a component, it cannot see signal values, dependency graphs, or effect states at runtime. Debugging is blind.

Silent Failures

Forgot to clean up an effect? Created an infinite reactive loop? Passed wrong props? Other frameworks stay quiet. The bug ships.

APIs Built for Text Editors

Autocomplete, hover docs, and inline hints help humans in IDEs. AI agents need structured, machine-readable contracts they can query programmatically.

The Solution

Built for AI agents
from the ground up.

Every layer of What Framework gives AI agents the context they need to write correct code, catch errors, and ship faster.

MCP DevTools

AI agents inspect every signal, effect, and component in a running app via the Model Context Protocol. Live state, dependency graphs, performance data -- all queryable.

// Agent calls MCP tool:
what_signals({ filter: "count" })
// Returns:
{ "summary": "6 signals total. 1 match
    filter 'count'. Values: count=5",
  "count": 1,
  "signals": [{ "id": 3, "name": "count",
    "value": 5, "componentId": 2 }] }

Structured Errors

A catalogue of ten ERR_ codes, each with a human message, a suggestion, and a code example an agent can query offline. Every error object serializes to JSON, so agents parse, understand, and fix it in a single pass.

{ "code": "ERR_SIGNAL_WRITE_IN_RENDER",
  "message": "Signal \"count\" written during render
    of component \"Counter\". This triggers re-execution.",
  "suggestion": "Move signal writes into event handlers,
    effects, or onMount(). The component body should only
    read signals, not write them.",
  "component": "Counter", "signal": "count" }

Agent Guardrails

In dev mode the runtime catches infinite effect loops and refuses raw-string innerHTML outright. With what-devtools installed (the scaffold adds it), it also warns on signal misuse. Lint rules catch the rest before they hit production.

// Runtime catches this automatically:
effect(() => {
  count(count() + 1) // Infinite loop
})
// [what] Possible infinite effect loop detected
// (25 iterations). Likely cause: an effect writes to
// a signal it also reads, creating a cycle. Use
// untrack() to read signals without subscribing.

Compiler Intelligence

Write normal JSX. The compiler transforms it into fine-grained reactive DOM operations. No virtual DOM diff. Components run once. Agents write familiar code, the compiler optimizes it.

// You write:
<p>{count()}</p>
// Compiler outputs: direct DOM text node update
// No re-renders. No VDOM. No reconciliation.
// Buildless (no compiler)? No JSX either, so write it with h():
h('p', {}, () => count())

Small & Fast

A small reactive core (signal, computed, effect, batch) plus opt-in modules. ~8KB typical-app runtime, zero third-party code in the shipped bundle, tree-shakeable. Agents generate less code, ship smaller bundles, and reason about a smaller API surface.

// The full API an agent needs to learn:
import { signal, computed, effect,
  mount, Show, For, createStore } from 'what-framework'
// ~8KB gzipped. That's it.
MCP in Action

Your component code.
What your agent sees.

The left panel is what you write. The right is what an AI agent can query via MCP DevTools at runtime.

TodoApp.jsx
import { signal, computed, mount, For } from 'what-framework'

function TodoApp() {
  const todos = signal([], 'todos')
  const filter = signal('all', 'filter')

  const visible = computed(() => {
    if (filter() === 'all') return todos()
    const done = filter() === 'done'
    return todos().filter(t => t.done === done)
  })

  const remaining = computed(() =>
    todos().filter(t => !t.done).length
  )

  return (
    <main>
      <h1>Todos ({remaining()})</h1>
      <ul>
        <For each={visible}>
          {todo => <li>{todo.text}</li>}
        </For>
      </ul>
    </main>
  )
}
MCP DevTools Response
// what_explain({ componentId: 1 }) on TodoApp (abridged)
{
  "summary": "TodoApp: 2 signals (todos=[{\"text\":\"Ship v1\"...,
    filter=\"all\"), 4 effects (effect_1 (ran 1x), ...)",
  "component": { "id": 1, "name": "TodoApp", "parentId": null },
  "signals": [
    { "id": 3, "name": "todos", "componentId": 1, "value": [
        { "text": "Ship v1", "done": false },
        { "text": "Write tests", "done": true } ] },
    { "id": 4, "name": "filter", "value": "all", "componentId": 1 }
  ],
  "effects": [
    { "id": 1, "name": "effect_1", "runCount": 1,
      "depSignalIds": [4, 3], "depSignalNames": ["filter", "todos"] },
    { "id": 2, "name": "effect_2", "runCount": 1,
      "depSignalIds": [3], "depSignalNames": ["todos"] },
    { "id": 3, "name": "effect_3", "runCount": 0, "depSignalIds": [] },
    { "id": 4, "name": "effect_4", "runCount": 0, "depSignalIds": [] }
  ],
  "errors": [],
  "counts": { "signals": 2, "effects": 4, "errors": 0 }
}
Getting Started

Set up MCP in two minutes.

Connect your AI agent to a running What app. Works with Claude Code, Cursor, and any MCP-compatible client. create-what writes both files below for you and installs the browser bridge. On an existing project add it yourself: npm i -D what-devtools what-devtools-mcp, then put whatDevTools() from what-devtools-mcp/vite-plugin in your Vite plugins. Without that bridge only the five offline tools answer (what_connection_status, what_lint, what_validate, what_scaffold, what_fix); the other 24 need a live page.

Claude Code

Add the What DevTools MCP server to your project's Claude Code config.

// .mcp.json (project root)
{
  "mcpServers": {
    "what-devtools-mcp": {
      "command": "npx",
      "args": ["what-devtools-mcp"]
    }
  }
}

Cursor

Add the MCP server to your Cursor workspace settings.

// .cursor/mcp.json
{
  "mcpServers": {
    "what-devtools-mcp": {
      "command": "npx",
      "args": ["what-devtools-mcp"]
    }
  }
}
Comparison

How What compares.

A factual look at AI-agent capabilities across frameworks.

What React Solid Svelte
MCP DevTools Built in No No No
Structured Errors JSON + suggestion Stack trace Stack trace Warnings
Runtime Guardrails Loops, XSS, signal misuse StrictMode Minimal Minimal
Reactivity Fine-grained signals VDOM diff Fine-grained signals Compiler runes
JSX Yes Yes Yes Custom syntax
SSR / Islands Built in Via Next.js SolidStart SvelteKit
React Library Compat Via what-react Native No No
Runtime Size* ~8KB ~61KB ~3.5KB ~11KB

* Gzipped JS from a Vite production build of the same minimal counter app, measured 2026-08-11: What 0.13.4 7.97KB, React 19.2 + react-dom 60.7KB, Solid 1.9 3.6KB, Svelte 5.56 11.7KB. Real-world app bundles vary by features used and differ between frameworks at app scale, so these figures don't imply byte-for-byte parity. Solid ships the smallest runtime here; What is not the smallest.

By the Numbers

Small framework.
Big capabilities.

~8KB
Gzipped runtime
4
Core primitives
1,900+
Tests passing
29
MCP devtools

Let your AI agent build with confidence.

MCP DevTools. Structured errors. Runtime guardrails. One command to start.

$ npx create-what my-app Click to copy