frame3d
v1.0.1
Published
Quickly render images of 3D models (GLB/ glTF-binary)
Maintainers
Readme
Frame3D
Frame3D is a small HTTP API for rendering images from 3D models (GLB). It uses Puppeteer to drive a headless browser and @google/model-viewer to load and render the model, then returns the rendered image(s) as base64 data URLs.
You can use Frame3D through the hosted web API, run the API yourself with or without Docker, or use the local CLI that can read local files (GLB / HDR / images) and write output images to disk.
Frame3D provides three modes with full control over camera, lighting, and environment:
- Single render (one image)
- Batch renders (multiple frames with per-frame options)
- Sequence renders (multiple frames for rotation and/or animation)
For full documentation and request schemas, see frame3d.dev/docs.
Install globally with npm: npm i -g frame3d

frame3d mode=sequence model=./examples/model.glb background="radial-gradient(circle, #5f5f5f 0%, #141414 120%)" frameCount=66 rotationAxis=y width=1280 height=720 shadowIntensity=0.5 shadowSoftness=0.5 outputFormat=png out=./examples/seq/frameRequirements
Depending on how you want to run Frame3D, you’ll need at least one of the following:
- Node.js >= 18: Required for local development and using the CLI tool.
- Chrome / Chromium: Required for non-Docker runs.
- Docker: For containerized runs.
Limits Configuration
Default limits are defined in src/config.ts. You can edit that file or override at runtime for stricter or more lenient limits, e.g.: docker run -e JSON_BODY_MAX_SIZE=25mb -e MAX_FRAMES_PER_REQUEST=128 frame3d, or set the same env vars in .env / .env.local when running without Docker.
Run as an API (Docker)
From the project root directory:
docker build -t frame3d .
docker run -p 8080:8080 frame3dHealth check:
curl http://localhost:8080/healthSingle render example:
curl -X POST http://localhost:8080/single \
-H "content-type: application/json" \
-d '{"model":"https://example.com/model.glb","outputFormat":"png"}'Run as an API (Node, no Docker)
From the project root directory:
npm ciConfigure Chrome/Chromium path:
Copy .env.local.example to .env.local and set your Chrome path:
# .env.local
# Linux
PUPPETEER_EXECUTABLE_PATH=/usr/bin/google-chrome
# Windows
PUPPETEER_EXECUTABLE_PATH="C:\Program Files\Google\Chrome\Application\chrome.exe"Alternatively, set the environment variable for your current terminal session only:
# Linux
export PUPPETEER_EXECUTABLE_PATH=/usr/bin/google-chrome
# Windows
set PUPPETEER_EXECUTABLE_PATH="C:\Program Files\Google\Chrome\Application\chrome.exe"Then start the server:
npm start
# or for development:
npm run devLocal CLI Script
The CLI is intentionally minimal: use key=value pairs; JSON payloads can be passed via [email protected] (or just @file.json).
Notes:
- The CLI auto-starts and stops a local Node server for the request unless you pass
server=...to use an already running instance. - Default mode is
single; usemode=sequenceormode=batchfor other routes. - Include metadata by adding
includeMetadata=truein your args or JSON. - If
model=...points to a local file, the CLI converts it todata:model/gltf-binary;base64,.... - If
environment=...orskybox=...points to a local file, the CLI converts it todata:<mime>;base64,.... - If a value is already an
http(s)URL or adata:URL, it is sent unchanged. - Base64 is omitted by default in CLI output; use
out=...to save files orprint-imageto print base64. - Saving outputs:
- Single:
out=out.png - Sequence/Batch: give a base name (no extension) and files will be written as name-.ext, e.g. out=frames -> frames-0.png, frames-1.png, ...
- Single:
CLI default (auto-start Node server)
Install/use the CLI in one of these ways:
- Global install:
npm i -g frame3d - From source (linked globally): run
npm linkin the project root - From source (no global install): run
node frame3d.js ...in the project root
Then run:
frame3d model=./examples/model.glb outputFormat=png out=./examples/out/single.pngFrom source without global install:
npm ci
node frame3d.js model=./examples/model.glb outputFormat=png out=./examples/out/single.pngThe CLI auto-detects Chrome/Chromium. If detection fails, create .env.local with your Chrome path (see .env.local.example).
CLI + Docker server
Start the container (as shown above).
From the project root directory, call the running API and pass local files:
frame3d server=http://localhost:8080 model=./examples/model.glb outputFormat=png out=./examples/out/single.pngCLI Examples
Single render with metadata:
frame3d model=./examples/model.glb outputFormat=png includeMetadata=true out=./examples/out/single.pngBatch via JSON file (with metadata):
- Create
./examples/request.json, then:
frame3d mode=batch json=@./examples/request.json includeMetadata=true out=./examples/out/batch- Create
Sequence (8 frames):
frame3d mode=sequence model=./examples/model.glb frameCount=8 rotationAxis=y outputFormat=png out=./examples/out/frames
Tests
From the project root directory:
npm test
# Or individually
npm run test:unit
npm run test:integrationNote: Integration tests require PUPPETEER_EXECUTABLE_PATH to be set. Create .env.local with your Chrome path (see .env.local.example) before running tests.
