- React in MCP hosts (Claude Desktop, ChatGPT, VS Code, Cursor) via
@metabindai/bindjs-react, inside a sandboxed iframe. - SwiftUI on iOS, macOS, and visionOS via the
BindJSlibrary from bindjs-apple, when embedded in your own app via the Assistant SDK. - Jetpack Compose on Android via bindjs-android, when embedded via the Assistant SDK.
Why this works
BindJS is a declarative, SwiftUI-inspired component language. A component author writes layout, behavior, and styling using primitives likeVStack, HStack, Text, Image, frame, padding, and foregroundStyle. These primitives have a well-defined semantic meaning, and each renderer maps them to the platform’s native equivalent:
Because each renderer targets the platform’s own UI toolkit, the mobile output isn’t a web view in disguise — it’s real SwiftUI and real Jetpack Compose, with 60 FPS scrolling, native gestures, and platform conventions. On the web, the output is React components in the DOM.
Two rendering paths
What’s compiled and what’s runtime
Components are compiled to a portable BindJS bundle on the server when a Type is published or when a tool call resolves. The bundle is a content-addressed package containing:- The compiled
bodyfunction for each component. - Asset references resolved to CDN URLs.
- Dependency packages (other projects’ components your project imports).
What’s available and where
Every rendering target is open source under Apache 2.0. The BindJS runtime and React renderer —@metabindai/bindjs-runtime and @metabindai/bindjs-react, from the bindjs-runtime repo — power what Claude, ChatGPT, and every other MCP host show your users. The SwiftUI engine (bindjs-apple, covering iOS, macOS, and visionOS) and the Jetpack Compose engine (bindjs-android) render the same components when embedded in your own app via the Assistant SDK.
Your tool definitions, schemas, and components are exportable; the protocol path on the wire is open MCP. The hosted platform — MCP App Studio, the hosted MCP App Server, and the agent proxy — is the commercial product.
Performance characteristics
- Edge-cached bundles. Compiled component bundles are content-addressed by hash and pushed to global CDN edges. The first request to a render path is one round trip; subsequent requests hit the cache.
- No cold starts on the render path. The renderer is preloaded in the host or SDK; rendering a tool result is bundle parse + body execution.
- Native gestures and animations. On iOS and Android, rendering is platform-native, so scroll velocity, gesture recognition, and animation timing match the rest of the embedding app.
- Rendering logic lives in the app binary. Only tool specifications (data) are delivered over the network. The renderer is signed and bundled with your app at build time; the network surface is data, not executable layout code.
When the rendering target matters for the component author
Most BindJS components compile cleanly across all three targets without special-casing. There are a few areas where the renderer’s capabilities differ:- Custom drawing. Canvas-based components, WebGL, or
Shadercomponents have a primary target and may render as a static fallback on others. - Platform-specific gestures. A SwiftUI-only gesture pattern can be expressed in BindJS, but it’ll behave differently on Compose and React.
- 3D models. USDZ on iOS, GLB on Android and web. The platform picks the right format from the asset’s
modelreferences.
What to read next
Components and Packages
The unit that gets compiled to each rendering target.
MCP Apps integration
How rendering works inside Claude Desktop and other MCP hosts.
Assistant SDK
Native rendering inside your own iOS, Android, or web app.
BindJS Reference
Component primitives, modifiers, and property system.