# TanStack Notebook > Author, run, edit, and share browser-only JavaScript, TypeScript, JSX, and TSX projects at https://tanstack.com/notebook. ## One-file compatibility mode Existing `#code=` notebook links use this contract: - Write one client-side TSX ECMAScript module. esbuild removes TypeScript types and transforms JSX; it does not type-check. - Use static imports from the aliases below or full HTTPS ESM URLs. Remote modules and fetch requests must allow CORS. - Export a default DOM Node, value, or function. A default function receives the output element and may render into it or return a value. ### Starter TSX module ```tsx import { useState } from 'react' import { createRoot } from 'react-dom/client' const styles = ` :root { --sandbox-ui: #3aa3c4; --sandbox-framework: #39af46; --sandbox-data: #d3481b; --sandbox-performance: #ffa216; } :root.dark { --sandbox-ui: #61adbf; --sandbox-framework: #69bc75; --sandbox-data: #e06e49; --sandbox-performance: #f4d648; } * { box-sizing: border-box; } body { margin: 0; background: var(--notebook-background); color: var(--notebook-foreground); font-family: ui-sans-serif, system-ui, sans-serif; } .sandbox { display: grid; min-height: 100dvh; place-items: center; padding: 2rem; text-align: center; } .sandbox__content { width: min(100%, 34rem); } .sandbox__colors { width: 8rem; height: 0.25rem; margin: 0 auto 2rem; border-radius: 999px; background: linear-gradient( 90deg, var(--sandbox-ui) 0 25%, var(--sandbox-framework) 25% 50%, var(--sandbox-data) 50% 75%, var(--sandbox-performance) 75% ); } .sandbox__brand { margin: 0 0 0.75rem; color: color-mix( in srgb, var(--notebook-foreground) 66%, var(--notebook-background) ); font-weight: 650; } h1 { margin: 0; font-size: clamp(2.25rem, 8vw, 3rem); line-height: 1; letter-spacing: -0.04em; } .sandbox__hint { margin: 1.75rem 0 2.75rem; color: color-mix( in srgb, var(--notebook-foreground) 66%, var(--notebook-background) ); font-size: clamp(1rem, 3vw, 1.25rem); } code { color: var(--notebook-foreground); } .sandbox__button { min-width: 10.5rem; padding: 0.8rem 1.5rem; border: 1px solid color-mix( in srgb, var(--notebook-foreground) 45%, var(--notebook-background) ); border-radius: 0.625rem; background: color-mix( in srgb, var(--notebook-foreground) 8%, var(--notebook-background) ); color: var(--notebook-foreground); font: inherit; font-size: 1.125rem; font-weight: 600; cursor: pointer; transition: background 120ms ease; } .sandbox__button:hover { background: color-mix( in srgb, var(--notebook-foreground) 14%, var(--notebook-background) ); } .sandbox__button:focus-visible { outline: 2px solid var(--notebook-foreground); outline-offset: 3px; } ` function App() { const [count, setCount] = useState(0) return ( <>
) } export default function render(output: HTMLElement) { createRoot(output).render() } ``` ## Import aliases - `react`: React 19.2.3. - `react-dom/client`: React DOM root API. - `@tanstack/charts`: TanStack Charts core. - `@tanstack/charts/`: TanStack Charts subpaths. - `@tanstack/charts/react`: TanStack Charts React bindings. - `@tanstack/charts/octane`: TanStack Charts Octane bindings. - `octane`: Octane 0.1.13 runtime. - `@tanstack/charts-data/`: TanStack Charts demo data; append a module path. - `@tanstack/highlight`: TanStack Highlight. - `@tanstack/highlight/`: TanStack Highlight subpaths; append core, languages/, theme, themes/, or markdown. - `@tanstack/markdown`: TanStack Markdown. - `@tanstack/markdown/`: TanStack Markdown subpaths; append html, parser, or extensions/. - `@tanstack/markdown/react`: TanStack Markdown React renderer using the notebook React instance. - `@tanstack/pacer`: TanStack Pacer. - `@tanstack/react-pacer`: TanStack Pacer React bindings. - `@tanstack/react-query`: TanStack Query. - `@tanstack/react-router`: TanStack Router. - `@tanstack/react-table`: TanStack Table. - `d3-array`: D3 array utilities. - `d3-geo`: D3 geographic projections. - `d3-scale`: D3 scales. - `d3-shape`: D3 shape generators. Full HTTPS ESM URLs are also supported. ## Browser environment - The module runs in a fresh sandboxed iframe with browser APIs, DOM, Canvas, SVG, WebGL, fetch, timers, and ResizeObserver. - Node.js APIs, filesystem access, process, server secrets, and parent-page DOM access are unavailable. - Each run replaces the iframe, so listeners, timers, React roots, and other runtime state are discarded automatically. - console.log, info, warn, error, and debug are mirrored to the optional Console panel. ## Multi-file workspace contract - A workspace is JSON with version 1, an absolute entry path, a files object keyed by canonical absolute paths, an optional environment, and an optional imports object. - The entry module executes in the browser. esbuild-wasm transforms TypeScript and JSX; octane/compiler transforms .tsrx files first. Neither path type-checks source. - Relative imports resolve inside files. CSS and JSON imports are bundled. Browser-safe image and font imports become data URLs. - Bare dependencies in /package.json resolve through esm.sh. Explicit workspace imports override both package.json and the built-in aliases. - Add /index.html only when the example needs a custom document. Environment bootstraps reuse #root or append it to the body. The runtime injects its import map, compiled CSS, module, console bridge, and theme bridge. ```json { "version": 1, "entry": "/src/main.tsx", "files": { "/src/main.tsx": "import { App } from './App'\n// mount App", "/src/App.tsx": "export function App() { return

Hello

}" }, "imports": { "react": "https://esm.sh/react@19.2.3" } } ``` ## Live documentation fences - A runnable documentation example is a consecutive group of fenced code blocks with the same group identifier. - Every fence must include an explicit canonical absolute file path. Exactly one fence has the entry flag, and that fence carries the group's only env declaration. - Supported environments are client, react, charts, charts-react, and charts-octane. Their hidden bootstrap mounts the entry module's default export. - Add the collapsed flag to support files that should remain under a disclosure until the reader opens them. - The static highlighted fences are rendered on the server. The workbench hydrates near the viewport and runs once visible and idle; selecting Run starts it immediately. ````md ```tsx group=counter env=charts-react file=/src/App.tsx entry export default function App() { return } ``` ```ts group=counter file=/src/data.ts collapsed // imported source ``` ```` ## Theme - The iframe root has either a light or dark class and follows the TanStack site theme after every run. - Use --notebook-background and --notebook-foreground for theme-aware colors. Use --notebook-error for errors. ## Sharing protocol Anyone can author and run a notebook at `https://tanstack.com/notebook/new`. Unsaved work is a browser-local draft with no public URL. A TanStack login is required to save it. Saved notebooks use stable `https://tanstack.com/notebook/` URLs. Reads are public and unlisted. Saving, updating, deleting, and forking requires a TanStack login. Create one with `POST https://tanstack.com/api/notebook/records` and `{ "project": , "forkedFromId"?: }`. Owners list theirs with `GET /api/notebook/records`; public metadata is available from `GET /api/notebook/records/`. Owners update with `PATCH` and `{ "project": , "expectedUpdatedAt": }`; stale updates return `409`. Owners delete with `DELETE`. Every save stores the project as an immutable SHA-256 snapshot. Read that canonical project JSON at `GET https://tanstack.com/api/notebook/projects/` using the `projectHash` returned in the notebook record. The original one-file notebook URL remains supported for legacy links: `https://tanstack.com/notebook?title=&description=<description>#code=<source>` To produce `<source>`, UTF-8 encode the TSX module, gzip the bytes, encode them as base64url, and omit `=` padding. Small multi-file projects use `https://tanstack.com/notebook#project=<project>`. The decoded JSON and the large-project POST body are exactly `{ "version": 1, "title": string, "description": string, "workspace": <workspace> }`. Encode and decode it with the same UTF-8, gzip, and unpadded base64url process. URL fragments are not sent to the HTTP server. Agents given a `#code` or `#project` URL must decode the fragment locally. Legacy large projects use `https://tanstack.com/notebook/p/<sha256>`. Read their canonical JSON without executing it at `GET https://tanstack.com/api/notebook/projects/<sha256>`. Reads are public and unlisted. Writes are immutable, authenticated, same-origin, and rate-limited through `POST https://tanstack.com/api/notebook/projects`. Git remains canonical for documentation and catalog examples. Saved notebook revisions and legacy project URLs are immutable snapshots. ## Tips - Render inside the provided output element. Do not replace document.body. - Make the result responsive to its container. ResizeObserver is available for charts, canvas, and WebGL scenes. - Use one file for small modules. Use a workspace when separate components, styles, data, assets, or a custom document make the example clearer. - Use console output for diagnostics that should remain available without opening browser developer tools.