npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

mediapipe-three

v0.1.8

Published

Three.js integration for MediaPipe face landmark detection — attach 3D objects to face anchors (head, eyes) with live camera background rendering.

Readme

mediapipe-three

Three.js integration for MediaPipe face landmark detection. Attach 3D objects to face anchors (head, left eye, right eye) with live camera background rendering.

Install

npm install mediapipe-three

Quick Start

import * as THREE from 'three'
import { FaceTracker } from 'mediapipe-three'

const scene = new THREE.Scene()
const camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 1000)
camera.position.z = 1

const renderer = new THREE.WebGLRenderer({ antialias: true })
renderer.setSize(window.innerWidth, window.innerHeight)
document.body.appendChild(renderer.domElement)

// Create the tracker and add its group to the scene
const faceTracker = new FaceTracker({ camera, renderer, scene })
scene.add(faceTracker.faceGroup)

// Start the webcam (true = front camera, false = rear)
faceTracker.startCamera(true)

function animate() {
  requestAnimationFrame(animate)
  faceTracker.update()     // runs face detection + renders camera background
  renderer.render(scene, camera)
}
animate()

Attaching Objects to the Face

faceTracker.anchors exposes three THREE.Group nodes that move and rotate with the face every frame:

| Anchor | Description | |---|---| | anchors.head | Full head transform (position + rotation) | | anchors.leftEye | Left eye position | | anchors.rightEye | Right eye position |

// Add any Three.js object to an anchor
const geometry = new THREE.BoxGeometry(0.1, 0.1, 0.1)
const material = new THREE.MeshStandardMaterial({ color: 0xff6600 })
const box = new THREE.Mesh(geometry, material)

faceTracker.anchors.head.add(box)
// Add helpers to visualize eye positions
faceTracker.anchors.leftEye.add(new THREE.AxesHelper(0.1))
faceTracker.anchors.rightEye.add(new THREE.AxesHelper(0.1))

Loading a GLTF Model onto the Face

import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'

const loader = new GLTFLoader()
loader.load('./mask.glb', (gltf) => {
  faceTracker.anchors.head.add(gltf.scene)
})

Wait for the Model to Load

Use the onLoad callback to run code once the MediaPipe model is ready:

faceTracker.onLoad = () => {
  console.log('Face tracker ready')
}

Or check the ready flag:

if (faceTracker.ready) {
  // safe to call detect()
}

Detect on a Custom Image or Video

Instead of update() (which reads from the webcam), use detect() to run face detection on any image, video, or canvas element:

function animate() {
  requestAnimationFrame(animate)
  faceTracker.detect(myVideoElement)  // HTMLImageElement | HTMLVideoElement | HTMLCanvasElement
  renderer.render(scene, camera)
}

Occlusion Mesh

A built-in occlusion mesh is available to hide objects that should appear behind the face (e.g. earrings behind the head). It is hidden by default:

faceTracker.occlusion.visible = true

Resize

Call resize when the renderer dimensions change:

window.addEventListener('resize', () => {
  camera.aspect = window.innerWidth / window.innerHeight
  camera.updateProjectionMatrix()
  renderer.setSize(window.innerWidth, window.innerHeight)
  faceTracker.resize(window.innerWidth, window.innerHeight)
})

Constructor Options

new FaceTracker({
  camera,                   // THREE.PerspectiveCamera  (required)
  renderer,                 // THREE.WebGLRenderer       (required)
  scene,                    // THREE.Scene               (required)
  forVisionTasksWasmPath,   // string — CDN path to MediaPipe WASM (optional)
  modelAssetPath,           // string — path to face_landmarker.task model (optional)
})

By default the WASM and model are loaded from the official CDN, so no local files are needed.

Full Example

import * as THREE from 'three'
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'
import { FaceTracker } from 'mediapipe-three'

const scene = new THREE.Scene()
const camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 1000)
camera.position.z = 1

const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true })
renderer.setSize(window.innerWidth, window.innerHeight)
document.getElementById('app').appendChild(renderer.domElement)

const faceTracker = new FaceTracker({ camera, renderer, scene })
scene.add(faceTracker.faceGroup)
faceTracker.startCamera(true)

scene.add(new THREE.AmbientLight(0xffffff, 0.5))
const dirLight = new THREE.DirectionalLight(0xffffff, 2)
dirLight.position.set(1, 2, 3)
scene.add(dirLight)

window.addEventListener('resize', () => {
  camera.aspect = window.innerWidth / window.innerHeight
  camera.updateProjectionMatrix()
  renderer.setSize(window.innerWidth, window.innerHeight)
  faceTracker.resize(window.innerWidth, window.innerHeight)
})

function animate() {
  requestAnimationFrame(animate)
  faceTracker.update()
  renderer.render(scene, camera)
}
animate()

License

MIT