Sandbox limits — Claude artifacts¶
Cheatsheet completo de restricciones del runtime de artifacts en Claude.ai. Cárgalo on-demand cuando vayas a generar contenido para application/vnd.ant.react, text/html, image/svg+xml o application/vnd.ant.mermaid.
Arquitectura¶
- iframe
sandboxcon CSP estricta. - Scripts solo desde
https://cdnjs.cloudflare.com. fetchaapi.anthropic.comse proxy-ea porhttps://claude.ai/api/organizations/{org}/proxy/v1/messagescon credenciales del visitante (Claudeception).fetcha otros dominios → bloqueado, salvo MCP servers declarados en el campomcp_servers(ejecutados server-side por Anthropic).- No
window.parent, nopostMessageal host.
Tipos MIME con render especial¶
| MIME | Uso | Notas |
|---|---|---|
application/vnd.ant.react |
JSX/TSX interactivo | Default export obligatorio. Sin required props. |
text/html |
Standalone HTML+CSS+JS | Único que puede <script src> desde cdnjs. |
image/svg+xml |
Vectorial estático | Usar viewBox, NO width/height hard-coded. |
application/vnd.ant.mermaid |
Diagrama | SIN code fences. 23 tipos soportados (v11.x). |
text/markdown |
Texto largo | Render automático con GFM. |
| Código display | Cualquier lenguaje | Sin ejecución. |
Storage¶
Permitido¶
useState/useReducer/useRef(in-memory).window.storage(solo en artifacts publicados):get(key, shared?)— throws si no existe, envuelve en try/catch.set(key, value, shared?)— solo strings/JSON.delete(key, shared?).list(prefix?, shared?).- Límites: 20 MB / artifact, keys < 200 chars sin
//"/espacios. shared: true→ visible a todos; primera write dispara diálogo de consentimiento.shared: false(default) → per-usuario.- Batch en UN blob JSON (rate-limited las multiple calls).
Prohibido¶
localStorage→ bloquea el iframe.sessionStorage→ bloquea el iframe.indexedDB→ bloquea el iframe.- Cookies → no accesibles.
Tailwind¶
Permitido¶
- Clases predefinidas del stylesheet base (
bg-stone-900,text-lg,grid-cols-3,hover:bg-stone-800,md:flex, etc.). - Plugin shadcn (
bg-background,text-foreground, etc.) en artifacts React.
Prohibido¶
- Arbitrary values:
top-[117px],bg-[#1da1f2],grid-cols-[200px_1fr]→ se ignoran silenciosamente. tailwind.config.js extend→ no aplicable.@apply,@theme,@layercustom.
Workaround para valores fuera de escala¶
// MAL (se ignora)
<div className="top-[117px] bg-[#1da1f2]" />
// BIEN (pierdes hover:/sm: pero el valor llega)
<div style={{ top: 117, backgroundColor: '#1da1f2' }} />
React específicos¶
- Default export obligatorio en el componente raíz.
- Sin required props en el root component.
<form>ROTO — usa<div>+onClick/onKeyDown="Enter".<input>,<textarea>,<select>funcionan normal.fetchcon AbortController funciona.- Sin Server Components, sin Next.js features.
Librerías¶
React artifacts — whitelist¶
| Librería | Versión aprox. | Uso |
|---|---|---|
| react | 18.x | core |
| react-dom | 18.x | core |
| lucide-react | 0.383.0 | iconos |
| recharts | 2.x | charts |
| mathjs | 12.x | math |
| lodash | 4.x | utilities |
| d3 | 7.x | viz custom |
| plotly | 2.x | scientific viz |
| three | r128 | 3D (gotchas abajo) |
| papaparse | 5.x | CSV |
| xlsx | 0.18.x | Excel parse/write |
| mammoth | 1.x | DOCX → HTML |
| @tensorflow/tfjs | 4.x | ML browser |
| chart.js | 4.x | canvas charts |
| tone | 14.x | audio synth |
| @/components/ui/* | shadcn subset | Button, Card, Input, Tabs, etc. |
React artifacts — NO disponibles¶
- framer-motion ❌
- react-three-fiber / @react-three/drei ❌
- lottie-react ❌
- react-spring ❌
- @tanstack/react-query ❌
- react-router ❌
HTML artifacts¶
Cualquier script desde https://cdnjs.cloudflare.com/ajax/libs/<lib>/<version>/<file> vía <script src>.
Three.js r128 — gotchas¶
// MAL — CapsuleGeometry no existe en r128 (vino en r142)
const capsule = new THREE.CapsuleGeometry(0.5, 1, 4, 8); // undefined
// BIEN — combina Cylinder + 2 Spheres
const body = new THREE.CylinderGeometry(0.5, 0.5, 1, 16);
const top = new THREE.SphereGeometry(0.5, 16, 16);
top.translate(0, 0.5, 0);
const bot = new THREE.SphereGeometry(0.5, 16, 16);
bot.translate(0, -0.5, 0);
// MAL — OrbitControls no importable
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
// BIEN — controles manuales
let isDragging = false, prevX = 0, prevY = 0;
renderer.domElement.addEventListener('pointerdown', e => {
isDragging = true; prevX = e.clientX; prevY = e.clientY;
});
renderer.domElement.addEventListener('pointermove', e => {
if (!isDragging) return;
camera.rotation.y -= (e.clientX - prevX) * 0.01;
camera.rotation.x -= (e.clientY - prevY) * 0.01;
prevX = e.clientX; prevY = e.clientY;
});
renderer.domElement.addEventListener('pointerup', () => { isDragging = false; });
CDN exacto: https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js.
Audio (tone.js)¶
- Requiere user gesture:
Tone.start()dentro deonClick, NO enuseEffect.
Cuándo migrar a Claude Code (fuera del sandbox)¶
Migra si necesitas:
- Backend / autenticación real.
- Multi-archivo (más de un módulo).
- SEO server-side / SSR.
- APIs externas no-MCP (Stripe, Twilio, OpenAI directo).
- Tests automatizados / CI.
- localStorage / IndexedDB para offline.
- Service workers / PWA.
- Más de 800 líneas (fidelidad de generación cae).