Typebulb runs apps in markdown files called bulbs. To run bulbs:
npx typebulb. When you want a quick local app or tool where the overhead of an entire npm project is overkill (trivial for your LLM to convert to when you actually need to). Can be entirely client code, or both client and Node.js code that talk via a secure bridge.npx typebulb agent. When you want to view agent conversations with embedded bulbs in the agent messages. Two harnesses are supported: Claude Code and Pi.You can create and edit bulbs either directly using the AI on typebulb.com or locally. The former uses BYOKs, the latter uses whatever agent you want, though we provide special support for Claude Code (CC). LLMs find the "markdown with code blocks" format intuitive, and given an example bulb, can effortlessly create a new bulb.
Bulbs standardize API calls that run in both typebulb.com's sandbox & locally. Most notably, they provide the ability to call agents at runtime.
Run bulbs locally via typebulb's agent mirror, which is included in the open-source Typebulb CLI:
npx typebulb agent then draw fireworks." Claude should launch Typebulb's agent mirror of your CC sessions.npx typebulb agent from the command line, and the agent mirror will auto-detect Pi. Then type "draw fireworks".The agent mirror is a GUI that mirrors your agent harness to provide a code scratchpad experience. Features:
Pi is nicer because you can both prompt and read responses in the agent mirror. I seldom even need to touch Pi's CLI.
With Claude Code the mirror is strictly a read-only view, so you still need to prompt via CC. But CC lets you use your subscription key, so it's hard to resist the price advantage there.
server.ts block; exported functions become callable from the code.tsx block running in the browser via tb.server.<name>() (e.g., export async function query(...) → await tb.server.query(...))tb.fs.read() (UTF-8 text), tb.fs.readBytes() (raw bytes), and tb.fs.write() (text or bytes); relative paths resolve to the bulb's own data folder.env and .env.local auto-loaded from cwdtb.server.log(...) prints to the CLI's stdout. Particularly useful for your LLM to conduct tests and instrument your code.--server runs only the server.ts section in Node, skipping the web server. Bulbs with only server.ts (no code.tsx) use this mode automatically.--no-watch)typebulb check <file> type-checks a bulb without running it (runs tsc --noEmit, exits non-zero on errors).--replace <name>=<path> replaces a declared dependency with a local built package folder instead of a CDN, for testing an unpublished build.tb.infer() works locally too: same confirmation modal and streaming as typebulb.com, against your own .env keys, plus sharing/saving a good run.By default the CLI runs bulbs sandboxed (no filesystem, AI, or server.ts), matching typebulb.com. Pass --trust to grant those to a bulb you've vetted.
You can re-import your bulbs into Typebulb. If they have a server.ts code block, you will be warned that this will be stripped out as it's only meaningful locally.
Bulbs implicitly have access to the tb const. This is useful when the client code needs to interact with the host, or access special features of Typebulb.
| API | Description | Runs on |
|---|---|---|
tb.data(n) / tb.json(n) | Access data chunks from the Data tab | Both |
tb.dump(...) | Log lazy/device-backed tensor values to the console | Both |
tb.copy(text) | Copy to clipboard | Both |
tb.url() | Get the canonical bulb URL | Both |
tb.proxy(url) | Proxy CDN URL for Web Worker/WASM same-origin loading | Both |
tb.insight() | Read the current Insight JSON | Both |
tb.infer(data?) | Call an LLM at runtime (uses Infer tab instructions) | Both |
tb.ai(options) | General-purpose AI calls (chatbots, agents, experiments) | Both |
tb.server.log(...) | Built-in: prints to CLI stdout, falls back to console.log on web | Both |
tb.models() | Available AI models (for dynamic model selectors) | Both |
tb.hasOwnKeys() | Whether the user's own AI keys back tb.ai (false = courtesy model only — gate AI-heavy bulbs on it) | Both |
tb.theme | Get/set the bulb's light/dark override; undefined follows the OS | Both |
tb.mode | Runtime mode: 'local', 'editor', 'published', or 'embedded' (in a sandboxed iframe — e.g. a bulb-in-a-bulb or the CLI's default launch; client-only) | Both |
tb.fs.read(path) / tb.fs.readBytes(path) / tb.fs.write(path, content) | Local filesystem access (text or binary) | CLI |
tb.dir | The bulb's data folder (absolute path), where relative tb.fs paths land | CLI |
tb.server.<name>(...) | Call exported server-side functions by name | CLI |
Note: For the most part, you don't really need to know, as only the AI edits the bulb.
A bulb is composed of code blocks providing the minimum viable structure for sandboxed apps that may have runtime inference. Each block is optional, and maps to an editor tab on typebulb.com:
| Block | Purpose | AI editable |
|---|---|---|
| code.tsx | App logic and UI (TypeScript/TSX) | Yes |
| styles.css | Styling | Yes |
| index.html | Usually just an HTML stub or fragment, but can be whole page, or blank for console apps | Yes |
| data.txt | Data chunks for your code to process (JSON, CSV, XML, YAML, or plain text); multiple chunks separated by two blank lines | No |
| infer.md | Prompt for runtime LLM calls via tb.infer() | Yes |
| insight.json | Output from tb.infer(), read via tb.insight() | Yes |
| config.json | Dependencies, app description, inference modal settings | Partial |
| notes.md | Persistent context for the AI assistant | No |
| server.ts | Server-side Node.js code (CLI only) | N/A |
The Data tab is for content that your code processes, whether structured (JSON, CSV, XML, YAML) or unstructured (plain text). The AI gets a read-only, schema-aware truncated view. Multiple chunks are separated by two blank lines.
Note: For general-purpose runtime AI calls, use
tb.ai.
This feature is easiest to understand via an example, such as the bach bulb. The user clicks on "AI Compose" and it launches a dialog, where the user types the genre, e.g. "fugue", and then the AI generates a fugue. The AI assistant will write such a bulb for you, but how does this work?
The Infer tab is a prompt for runtime LLM calls. When your code in code.tsx calls tb.infer(), the LLM receives: your inference instructions, an example output (from insight.json), your code.tsx (so it knows the expected JSON shape), and the data.txt to process. A modal shows the user what will be sent; confirm and the LLM streams its response.
The Insight tab holds JSON that serves as both a working example (showing the LLM what shape you expect) and the current output (updated after tb.infer() completes). Your code reads it via tb.insight(). There's no separate JSON Schema. The code IS the schema.
Free tier users are rate limited. Users with their own API keys have no Typebulb-imposed limits (within reason). Runtime inference always uses the user's API keys, or Typebulb's courtesy models, never your API keys.
Persistent context for the AI, carried across conversations and clones. Useful for API docs, examples, or skills the LLM requires.
Typebulb's AI assistant is great for 1-shot bulbs. If you've got a more complex bulb, develop it locally with Claude Code or Codex, and run with the typebulb CLI. When it's ready you can import to typebulb.com.
OpenAI, Anthropic, Gemini and OpenRouter. Bring your own keys. Your keys are used for the AI assistant and tb.infer() calls that you make, but not anyone else who runs your bulb.
| Mode | AI sees your bulb | AI will edit | Use case |
|---|---|---|---|
| Code | Yes | Yes | Default. Sees code, HTML, CSS, notes, truncated data, errors, and logs. |
| Ask | Yes | No | Same context as Code, but when you just want to discuss, not edit code. |
| Chat | No | No | General conversation, unrelated to your bulb. |
| Raw | No | No | No system prompt. Good for prompt testing. |
In Code mode, Typebulb will automatically reply to the AI if it makes a patch error or generates TypeScript errors, with precise details on how to fix them.
Yes, with caveats. Web search is most reliable with native provider integrations (OpenAI/Anthropic/Gemini); OpenRouter support can be model-dependent and less consistent.
This is web search, not browsing. It works best for well-indexed topics (news, popular libraries, recent releases), and may not retrieve obscure npm or GitHub pages from a URL alone.
If you need the AI to use specific documentation, paste excerpts into the Notes tab; for structured data, use the Data tab.
Add console.logs to your code, and logs are automatically fed back to the AI. You can even debug manually, as we automatically generate TypeScript source maps:
code.tsxAdd tb.server.log(...) calls to your code. Get your AI agent to run the bulb directly, and it will stream results to them. Use tb.fs.write(...) to write big files. For a bulb already running (e.g. one you launched from the UI), your agent can fetch its console with typebulb logs <file> — and drive the whole lifecycle from the terminal (typebulb logs / stop / trust), while you keep an eye on it in the UI.
Typebulb is heavily optimized for building responsive bulbs that work beautifully on both mobile and desktop. "alt-enter" toggles between a mobile-friendly portrait layout and full screen.
For building bulbs, Typebulb works on mobile, but is heavily optimized for desktop usage. The mobile experience has one key feature: you can see the bulb's logs, which is useful for testing.
A bulb has 3 possible visibilities adjustable in the toolbar/menu:
When you share a bulb, the user will see any changes you make if you save the bulb and they refresh their browser. The user has a read-only view of your bulb; if they try to edit it, a clone is made.
This is what we store:
We don't use your data for training or sell it to third parties. Your AI providers have their own data policies.
Ben Albahari. I worked as a Program Manager at MSFT, and co-authored the C# in a Nutshell series (with my brother, Joe Albahari, the author of the popular LINQPad tool). It's very cheap to maintain, but if it ever got really popular, I'd seek investment.
This changes all the time. Currently it's a transformer that runs in your browser. Also You're Absolutely Right!, a sycophancy benchmark written as a bulb, that automates hundreds of API calls. The bulb approach makes it easy for anyone to inspect or re-run the results.
← Back to Typebulb