Integrating on web
PoseFlow runs on web via a pose pipeline (WASM Web Worker). The high-level
API is the same as native (TrackedMovementView, MovementTracker,
the same .pose files), the integration differences are about
how the WASM + worker JS get served from your web app.
Required assets
The web pipeline needs these files served from a URL prefix of your choice:
| File | What |
|---|---|
blazepose_worker.js | The Web Worker entry. Loads the WASM + drives detection. |
blazepose_pipeline.js | WASM glue. |
blazepose_pipeline.wasm | The pose engine compiled to WASM-SIMD. |
blazepose_detector_weights.bin | Detector model weights (~5 MB). |
blazepose_optimized_weights_int8.bin | Landmark model weights (~3 MB, quantised int8). |
Place all five in your app’s web/ directory under a single
prefix folder, e.g. web/pose_flow/. So the layout is:
web/ index.html pose_flow/ blazepose_worker.js blazepose_pipeline.js blazepose_pipeline.wasm blazepose_detector_weights.bin blazepose_optimized_weights_int8.binThe files ship with the
blaze_flow package. Copy
them from packages/blaze_flow/web/ in the source tree (or from the
published package’s web assets) into a directory under your app’s
web/ folder.
Telling PoseFlow where to find them
For TrackedMovementView direct usage, the asset path is
auto-resolved to pose_flow/, the default works if you placed
the files there.
For Studio embeds, configure via StudioScope.assetBasePath:
StudioScope( persistence: persistence, assetBasePath: 'pose_flow/', // ← your prefix folder child: const PoseFlowStudioScreen(),)(Trailing slash matters, the path is prepended to the asset filenames.)
Web-specific browser requirements
- WASM SIMD support. All Chromium-based browsers since 2021, Firefox 89+, Safari 16.4+.
- OffscreenCanvas (used by the worker for
createImageBitmapops). Chromium-based browsers + Firefox; Safari fully supports this since 16.4. createImageBitmapwithVideoFramesource. Same browsers.
For older Safari we have a fallback path that processes frames on the main thread; FPS drops to ~10 from ~25 but tracking still works.
Camera permissions
The web <video> element uses getUserMedia({video: { facingMode: 'user' }}) for selfie mode. The user is prompted for camera
permission on first activation. PoseFlow doesn’t manage this ,
the browser does.
You can force the user-facing camera by passing
facingMode: 'user' via the constraints, but the camera plugin
defaults already handle this.
Mirror mode
The default web CameraTrackingView (used inside Studio + any
host that wraps it) CSS-mirrors the video preview for selfie
semantics. The pose landmarks are mirrored to match, when the
user raises their right hand, the visible video shows their right
hand on the screen’s right, AND pose.point(right_wrist).dx is on
the right of the image space.
If you’re embedding PoseCameraView directly with mirror: false,
the landmarks come back in raw camera-space coordinates (anatomical
left appears on screen-right).
Frame rate
Web typically runs at 20–25 FPS on a modern laptop. Limited by:
- WASM model inference: ~12–18 ms per frame.
createImageBitmap+ worker message: ~5–10 ms per frame.- JS event loop: main thread does the camera + rendering.
To push higher, the Worker can run with multiple inference slots
via ExecutionConfig (advanced, see blaze_flow docs).
CORS
The Worker fetches the WASM + weights from your origin. Make sure your web server serves them with the right CORS headers:
Content-Type: application/wasmfor the.wasm.Content-Type: application/octet-streamfor the.binweights.
Most static servers do this by default. Firebase Hosting + Cloudflare Pages + Vercel all work out of the box.
Cross-origin isolation (optional, for SharedArrayBuffer)
PoseFlow doesn’t require SharedArrayBuffer today (the worker
transfers ImageBitmaps zero-copy). If you opt into COOP/COEP
headers for other reasons, PoseFlow stays compatible, no extra
config needed.
Test setup
flutter test --platform chrome runs widget + integration tests
in headless Chrome. Camera + worker tests need a real camera and
the WASM assets served from the test server’s web root.