Qué es MediaPipe: la IA de Google que corre en tu navegador
Imagina que te piden una feature sencilla: detectar si el usuario levanta la mano delante de la webcam para pasar de diapositiva.
Lo primero que piensas es una API de visión en la nube. A 30 frames por segundo son 1.800 peticiones por minuto y por usuario, cada una con su latencia y su factura. Y con la cara del usuario viajando a un servidor que no controlas.
Hay otra forma: que el modelo baje una vez al navegador y haga la inferencia en la GPU del usuario. Si te preguntas qué es MediaPipe, en una línea es eso. La pregunta incómoda es si sigue vivo en 2026. Sí, pero no entero.
En corto: MediaPipe es el framework de Google para ejecutar modelos de IA en el propio dispositivo, con tareas listas para visión, texto y audio que en el navegador funcionan con WebAssembly y GPU. Hoy forma parte de Google AI Edge, y su paquete de visión para web, @mediapipe/tasks-vision, va por la versión 1.1.1. La parte de LLMs (LLM Inference API) está en modo solo mantenimiento y Google recomienda migrar a LiteRT-LM.
¿Qué es MediaPipe?
MediaPipe es un conjunto de librerías de Google que ejecutan modelos de machine learning ya entrenados directamente en el dispositivo (navegador, Android, iOS o Python) a través de APIs de alto nivel llamadas MediaPipe Tasks.
Google lo coloca dentro de Google AI Edge, su stack para IA on-device. Ahí cada pieza tiene un papel. MediaPipe son las "Prebuilt APIs for common AI tasks". LiteRT es el runtime para modelos propios. LiteRT-LM son los SDK para ejecutar LLMs.
La diferencia con un runtime a pelo: no interpretas tensores. Le pasas un <video> y te devuelve "mano izquierda, 21 puntos, estas coordenadas". El repositorio google-ai-edge/mediapipe tiene licencia Apache-2.0 y más de 37.000 estrellas (17 de octubre de 2026).
Qué soluciones trae MediaPipe Tasks en 2026
MediaPipe Tasks cubre visión, texto, audio, recuperación, decisión y una tarea generativa, pero no todas existen en web. Esta es la foto según la guía oficial de soluciones, revisada el 17 de octubre de 2026:
| Dominio | Tareas | ¿Hay versión web? | Paquete npm |
|---|---|---|---|
| Visión | Detección de caras, landmarks faciales, gestos, landmarks de manos, holistic, landmarks de pose, clasificación, embeddings y segmentación de imagen, segmentación interactiva, detección de objetos | Sí, todas | @mediapipe/tasks-vision |
| Texto | Detección de idioma, clasificación, embeddings | Sí | @mediapipe/tasks-text |
| Texto | Corrección (proofreading), resumen | No (Android, iOS, Python) | — |
| Audio | Clasificación de audio | Sí | @mediapipe/tasks-audio |
| Recuperación | Semantic retriever, universal embedder | Sí | @mediapipe/tasks-retrieval |
| Decisión | Decision maker | Sí | @mediapipe/tasks-decision |
| Generativa | LLM Inference API | Sí, pero en mantenimiento | @mediapipe/tasks-genai |
| Legacy | Hands, Pose, Face Mesh, Holistic, Objectron y compañía | Sin soporte desde el 1 de marzo de 2023 | @mediapipe/hands, @mediapipe/pose… |
Si un tutorial importa @mediapipe/hands o @mediapipe/pose, es código legacy: su última versión en npm es del 4 de febrero de 2023. Hands pasó a Hand Landmarker y Pose a Pose Landmarker.
Y fíjate en los ritmos. Según el registro de npm, @mediapipe/tasks-vision publicó la 1.0.0 el 28 de julio de 2026 y la 1.1.1 el 14 de octubre. tasks-text, tasks-audio, tasks-retrieval y tasks-decision también están en la 1.1.1. @mediapipe/tasks-genai sigue en la 0.10.29, del 8 de julio.
Qué pasó con la LLM Inference API de MediaPipe
La LLM Inference API de MediaPipe sigue funcionando, pero ya no es el camino recomendado para LLMs en el navegador. La página oficial para web lo dice arriba del todo: "The MediaPipe LLM Inference API is in maintenance-only mode", y recomienda migrar los proyectos web a la API de JavaScript de LiteRT-LM.
En las notas de la v1.0.0 aparece también la línea "Remove iOS and Android LLM Inference Engine from release". El relevo es LiteRT-LM, que se instala como @litert-lm/core y carga modelos Gemma 4 en formato .litertlm.
Mi opinión: si empiezas hoy un proyecto con un LLM local, no lo montes sobre tasks-genai. Y si lo que quieres es un LLM en el navegador sin descargar nada, mira antes la vía de Chrome: lo conté en cómo integrar Gemini Nano en Angular para IA local en el navegador.
Donde MediaPipe sigue siendo la mejor opción es en visión y audio en tiempo real.
Cómo usar MediaPipe en JavaScript paso a paso
Para usar MediaPipe en el navegador son tres pasos:
- Instala el paquete de la tarea:
npm install @mediapipe/tasks-vision. - Carga el runtime WebAssembly con
FilesetResolver.forVisionTasks(). - Crea la tarea con
createFromOptions()y llama adetectForVideo()en cada frame.
Este es un detector de objetos sobre la webcam, en TypeScript. Las firmas son las del código fuente del repositorio:
import { FilesetResolver, ObjectDetector } from 39;@mediapipe/tasks-vision39;;
// Fija la versión del WASM a la misma que tienes en package.json
const WASM_URL = 39;https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@1.1.1/wasm';
const MODEL_URL =
39;https://storage.googleapis.com/mediapipe-tasks/object_detector/efficientdet_lite0_uint8.tflite';
export async function createDetector(): Promise<ObjectDetector> {
const vision = await FilesetResolver.forVisionTasks(WASM_URL);
return ObjectDetector.createFromOptions(vision, {
baseOptions: { modelAssetPath: MODEL_URL, delegate: 39;GPU39; },
runningMode: 39;VIDEO39;,
scoreThreshold: 0.5,
maxResults: 5,
});
}
export function startLoop(
detector: ObjectDetector,
video: HTMLVideoElement,
onLabels: (labels: string[]) => void,
): void {
let lastVideoTime = -1;
const tick = () => {
if (video.currentTime !== lastVideoTime) {
lastVideoTime = video.currentTime;
// detectForVideo exige el timestamp del frame en milisegundos
const { detections } = detector.detectForVideo(video, performance.now());
onLabels(
detections.map((d) => {
const top = d.categories[0];
return `${top?.categoryName} ${(top?.score ?? 0).toFixed(2)}`;
}),
);
}
requestAnimationFrame(tick);
};
requestAnimationFrame(tick);
}
Tres cosas que la doc no deja claras.
El timestamp es obligatorio. Los ejemplos web de la doc llaman a detectForVideo(video) sin segundo argumento, pero la firma real en object_detector.ts es detectForVideo(videoFrame, timestamp, imageProcessingOptions?). Si copias el ejemplo, TypeScript no compila.
delegate solo acepta 'CPU' o 'GPU'. En web, GPU significa WebGL: el tipo VisionTaskOptions documenta que la tarea "will initialize a WebGL context" en el canvas que le pases. No es WebGPU. WebGPU es requisito de la LLM Inference API, no de las tareas de visión.
Fija versiones. La doc usa @latest en la URL del WASM. Si package.json y el CDN difieren, el JS y el WASM se desincronizan. Pon el mismo número en los dos.
Cuando el componente se destruya, llama a detector.close() para liberar los recursos. Si lo integras en Angular, encapsúlalo en un servicio y expón las etiquetas con un signal: es el mismo patrón de servicios y signals que enseño en el curso de Angular Moderno.
MediaPipe en el navegador frente a una API de visión en la nube
MediaPipe gana cuando necesitas tiempo real, privacidad o coste cero por inferencia. La nube gana cuando necesitas modelos grandes o resultados idénticos en cualquier dispositivo.
| Criterio | MediaPipe en el navegador | API de visión en la nube |
|---|---|---|
| Latencia por frame | Sin red: solo la inferencia local | Ida y vuelta de red en cada llamada |
| Coste por inferencia | Cero; pagas solo el hosting de los modelos | Facturas por petición |
| Privacidad | La imagen no sale del dispositivo (con matiz, ver abajo) | La imagen viaja a un tercero |
| Peso inicial | WASM de visión de 13,5 MB (3,6 MB con Brotli) + modelo: 4,6 MB EfficientDet-Lite0, 7,8 MB Hand Landmarker | Ninguno |
| Calidad del modelo | Modelos pequeños, pensados para el dispositivo | Modelos grandes, mejor en casos difíciles |
| Riesgo principal | Rendimiento distinto según la GPU del usuario | Coste que escala con el uso y dependencia del proveedor |
Los tamaños los he medido con peticiones HEAD a jsDelivr y Google Cloud Storage el 17 de octubre de 2026, versión 1.1.1.
Es la misma lógica que defiendo para los datos con local-first y PGlite en el navegador: mover el trabajo al cliente cuando el cliente puede hacerlo. Y es la decisión de arquitectura que trabajamos en Construye con IA: qué corre en local, qué va a un modelo en la nube y por qué.
Cuándo NO usar MediaPipe
No uses MediaPipe si tu caso exige estabilidad perfecta frame a frame, rendimiento igual en todos los móviles, cero datos enviados a Google, o si necesitas un LLM o un modelo propio. Son cuatro límites reales.
Los landmarks tiemblan. El issue #4507, abierto desde junio de 2023, lo describe: al migrar de la solución legacy de Pose a tasks-vision los puntos vibran más. La versión antigua tenía un parámetro smoothLandmarks que la nueva no expone.
Google dio el problema por resuelto en la 0.10.7. Usuarios de JavaScript respondieron que seguían viéndolo, y en mayo de 2025 alguien lo reportaba aún en Python 0.10.21. Si haces captura de movimiento, presupuesta tu propio filtro de suavizado.
El rendimiento depende de la GPU del usuario. En el issue #5190, la segmentación multiclase con delegate GPU fallaba en Chrome para Android. El equipo de MediaPipe pidió ayuda a un ingeniero del runtime web, que explicó el diseño: "If GPU delegate is chosen, we try to do everything on the GPU, for maximal performance".
El fallo se arregló en el WASM de la 0.10.15, pero el autor confirmó el arreglo con un aviso: "it is relatively slow compared to the operation of an iPhone". Prueba en Android de gama media antes de prometer nada.
"On-device" no significa "sin telemetría". El aviso de privacidad de MediaPipe Tasks dice que las imágenes, el vídeo y el texto se procesan en el dispositivo y no se envían a Google.
También dice que las APIs envían a Google métricas de rendimiento y uso, y que obtener el consentimiento informado de tus usuarios es responsabilidad tuya. Si vendes "nada sale del navegador", revísalo con quien lleve tu RGPD.
No es para LLMs nuevos ni para modelos propios. Para LLMs, Google apunta a LiteRT-LM. Para un modelo que no encaje en ninguna tarea, la pieza es LiteRT.
Cómo decidir si MediaPipe encaja en tu proyecto
Abre la demo de la tarea que te interesa, mira cuánto tarda en cargar en tu peor móvil de pruebas y decide con ese número, no con la demo en tu portátil.
Si el número aguanta, MediaPipe te da visión en tiempo real sin servidor y sin factura por frame: gestos, poses, caras y fondos. Para todo lo que lleve un LLM, ya no.
En el canal de YouTube de Dominicode seguimos probando estas herramientas de IA en local con código real.
Preguntas frecuentes
¿MediaPipe es gratis?
Sí. Tiene licencia Apache-2.0 y no hay coste por inferencia porque se ejecuta en el dispositivo. Solo pagas el hosting de modelos y WASM si no usas los CDN públicos.
¿MediaPipe envía las imágenes de la cámara a Google?
No. Según el aviso de privacidad oficial, imágenes, vídeo y texto se procesan en el dispositivo. Sí se envían métricas de rendimiento y uso de las APIs, y debes informar de ello a tus usuarios.
¿Puedo usar MediaPipe con Angular, React o Vue?
Sí. @mediapipe/tasks-vision es un paquete npm con tipos de TypeScript que no depende de ningún framework. Crea la tarea en un servicio o hook y llama a close() al destruir el componente.
¿Sigue sirviendo MediaPipe para ejecutar LLMs en el navegador?
Funciona, pero no para proyectos nuevos. La LLM Inference API está en modo solo mantenimiento, exige WebGPU y Google recomienda migrar a LiteRT-LM (@litert-lm/core).
¿Qué pasó con @mediapipe/hands y @mediapipe/pose?
Son Legacy Solutions sin soporte desde el 1 de marzo de 2023. Sus sustitutos son Hand Landmarker y Pose Landmarker en @mediapipe/tasks-vision. El código y los binarios antiguos siguen disponibles tal cual (as-is), sin soporte.
¿Qué relación hay entre MediaPipe y Google AI Edge?
MediaPipe es una pieza de Google AI Edge, el stack de Google para IA on-device. Dentro de AI Edge, MediaPipe aporta las APIs prediseñadas para tareas comunes; LiteRT es el runtime para modelos propios y LiteRT-LM, el SDK para ejecutar LLMs.
¿Qué navegadores soporta MediaPipe?
La guía de configuración web pide Chrome o Safari. Con el delegate GPU usa WebGL, así que el rendimiento depende de la GPU de cada dispositivo. Pruébalo también en Android.
Por Bezael Pérez — Developer senior con más de 15 años de experiencia y fundador de Dominicode.
¿Te resultó útil este artículo?
Compártelo con tu comunidad y ayuda a otros desarrolladores.
