Skip to content

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:

FileWhat
blazepose_worker.jsThe Web Worker entry. Loads the WASM + drives detection.
blazepose_pipeline.jsWASM glue.
blazepose_pipeline.wasmThe pose engine compiled to WASM-SIMD.
blazepose_detector_weights.binDetector model weights (~5 MB).
blazepose_optimized_weights_int8.binLandmark 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.bin

The 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 createImageBitmap ops). Chromium-based browsers + Firefox; Safari fully supports this since 16.4.
  • createImageBitmap with VideoFrame source. 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/wasm for the .wasm.
  • Content-Type: application/octet-stream for the .bin weights.

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.