You want a finished 3D world from a prompt, an image, or a video. World Labs Marble generates splat files, a mesh, and a viewer URL. Generation often takes several minutes.
Use worldlabsWorld() with generateWorld(). This adapter does not support chat().
npm i @tanstack/ai-worldlabspnpm add @tanstack/ai-worldlabsyarn add @tanstack/ai-worldlabsbun add @tanstack/ai-worldlabsPeer dependency: @tanstack/ai. A full working app is in examples/ts-react-media. Open the World tab and pick a Marble model.
Create a key in the World Labs platform. Set WORLDLABS_API_KEY, or pass apiKey.
import { generateWorld } from '@tanstack/ai'
import { worldlabsWorld } from '@tanstack/ai-worldlabs'
const world = await generateWorld({
adapter: worldlabsWorld('marble-1.1'),
prompt: 'A mystical forest with glowing mushrooms',
})To pass a key explicitly:
import { worldlabsWorld } from '@tanstack/ai-worldlabs'
const adapter = worldlabsWorld('marble-1.1', {
apiKey: process.env.WORLDLABS_API_KEY!,
})world.url is the Marble viewer URL (https://marble.worldlabs.ai/world/{id}). Do not iframe it. world.assets is optional. Splat, mesh, panorama, and thumbnail links appear only when the World Labs response includes them. Those URLs are often signed CDN links.
World Labs bills in credits per generation. The call waits until the world is ready (often several minutes). Pass a long timeout on serverless, or set wait: false and poll later.
Pass a string literal so TypeScript can narrow options.
import { worldlabsWorld } from '@tanstack/ai-worldlabs'
const adapter = worldlabsWorld('marble-1.1')| Id | Notes |
|---|---|
| marble-1.1-plus | Dynamic world sizing |
| marble-1.1 | World Labs default model id |
| marble-1.0 | Marble 1.0 |
| marble-1.0-draft | Faster draft quality |
The prompt argument is the text. Put media on modelOptions.
import { generateWorld } from '@tanstack/ai'
import { worldlabsWorld } from '@tanstack/ai-worldlabs'
const world = await generateWorld({
adapter: worldlabsWorld('marble-1.1'),
prompt: 'A cozy living room',
modelOptions: {
image: { uri: 'https://example.com/room.jpg' },
isPano: 'auto',
},
})Pass only one of image, images, or video.
| Option | Meaning |
|---|---|
| image | One image. uri, mediaAssetId, or dataBase64 |
| images | Several images of the same scene, each with optional azimuth |
| video | One video. Same source fields as image |
| isPano | auto, true, or false for a single image |
| wait | Default true. Set false to return operationId at once |
| pollIntervalMs | Poll delay when wait is true. Default 2000 |
Optional metadata: displayName, seed, tags, disableRecaption, permission.
When wait is false, world.status is waiting and world.operationId is set. This adapter cannot resume that id. Call generateWorld again with wait: true only starts a new job. Poll GET /marble/v1/operations/{operationId} yourself, or keep wait at the default.
A server call that generates a Marble world and returns the viewer URL plus optional asset links. The media example picks one SPZ (prefers 500k) and loads it in Spark through /api/marble-splat. If no splat URL is present, it shows a thumbnail and an Open in Marble link.