con un clic
browser-ml-in-javascript
The user wants to run an ML model in JavaScript
Instalar con Codex o Claude Copia este prompt, pégalo en Codex, Claude u otro asistente, y deja que revise la página de la skill y la instale por ti.
Menú
The user wants to run an ML model in JavaScript
Instalar con Codex o Claude Copia este prompt, pégalo en Codex, Claude u otro asistente, y deja que revise la página de la skill y la instale por ti.
Basado en la clasificación ocupacional SOC
Review code changes and report issues by severity with actionable fixes.
Sharpen a fuzzy intention into one measurable objective string that drives the rest of the work.
Convert a Prompt Flow PRS pipeline submission to run a Microsoft Agent Framework workflow.
Build a Model Context Protocol (MCP) server that lets an LLM call into external tools and resources.
Summarize PDF documents into concise bullet-point digests.
Bump a dependency version across a pnpm workspace and update lockfile.
| name | Browser ML in JavaScript |
| description | The user wants to run an ML model in JavaScript |
| category | browser-automation |
| tags | ["ai","api","backend","cli","frontend"] |
| source | {"url":"https://github.com/huggingface/skills/tree/4948baec814c92edd91024b76d8c2ffa6df4eb70/skills/transformers-js","fetched_at":"2026-06-12","commit":"4948baec814c92edd91024b76d8c2ffa6df4eb70","license":"MIT","original_path":"skills/transformers-js/SKILL.md"} |
| license | Apache-2.0 |
| author | Hugging Face (downstream pack: badhope) |
| version | 0.1.0 |
| needs_review | false |
| slug | browser-ml-in-js |
| created | 2026-06-12 |
| updated | 2026-06-19 |
| inputs | [{"name":"task","type":"string","required":true,"description":"ML task - sentiment-analysis/text-classification/token-classification/translation/feature-extraction/fill-mask/question-answering/image-classification"},{"name":"runtime","type":"string","required":true,"description":"Runtime - browser/node/bun/deno/worker"},{"name":"model_id","type":"string","required":false,"description":"Specific model id to use"},{"name":"device","type":"string","required":false,"description":"Device - auto/webgpu/wasm/cpu/cuda/dml"}] |
| output | {"format":"markdown","description":"Generated content based on the user request"} |
| quality | stable |
The user wants to run an ML model in JavaScript or TypeScript — in a browser, in Node, in Bun, in Deno, or in a Web Worker — without a Python backend. Typical triggers: "run a model in the browser", "client-side ML", "embed a sentence similarity check in my Vite app", "do OCR in TypeScript", "translate on-device".
Use this skill for:
Do not use this when:
task — the ML task; drives the pipeline
import.runtime — where the code runs.model_id (optional) — explicit model id.device (optional) — auto / webgpu / wasm /
cpu / cuda / dml.A ## Stack block, an ## Install block, a
minimal ## Code block with the mandatory
pipe.dispose(), and a ## Footguns block.
You are running an ML model in JavaScript or
TypeScript — in a browser, in Node, in Bun, in
Deno, or in a Web Worker. The model is shipped
in ONNX format and the runtime is
ONNX-Runtime-backed (WebGPU, WASM, CUDA, DML,
or CPU). There is no Python backend.
## 1. Pick the pipeline
The pipeline name is a string. Pick the
smallest pipeline that covers the task. Common
ones:
- `sentiment-analysis` — single-label
classification
- `text-classification` — same, multi-class
- `token-classification` — NER, POS
- `translation` — needs `src_lang` /
`tgt_lang`
- `summarization`
- `text-generation` — needs a generative
model
- `fill-mask` — MLM
- `question-answering` — needs a `question`
+ `context`
- `image-classification`
- `object-detection` — returns boxes +
labels
- `image-segmentation`
- `zero-shot-classification` — needs
`candidate_labels`
- `zero-shot-object-detection`
- `automatic-speech-recognition` — Whisper
family
- `audio-classification`
- `text-to-image` — needs a Stable Diffusion
or SDXL model
- `image-to-text` — captioning
- `feature-extraction` — embeddings
- `sentence-similarity` — embeddings + cosine
If the user asks for "similarity", pick
`feature-extraction` and compute cosine
yourself, or pick `sentence-similarity` and let
the pipeline do it. `sentence-similarity` is the
smarter default for text.
## 2. Pick the runtime
Match the import to the runtime:
- **Browser (ESM via CDN):**
```html
<script type="module">
import { pipeline } from
'https://cdn.jsdelivr.net/npm/@huggingface/transformers';
</script>
```
- **Browser (bundled):** `npm install
@huggingface/transformers` and import from
`'@huggingface/transformers'`.
- **Node (CommonJS or ESM):** same package.
Set `env.allowLocalModels = true` if you
want to load from disk.
- **Bun / Deno:** same package works; verify
on a smoke test before committing.
## 3. Pick the device
- In a browser, default to `webgpu` when
available, fall back to `wasm`. CPU is the
always-works fallback for tiny models.
- In Node, default to `cpu` (no WebGPU
runtime). Use `cuda` only when
`onnxruntime-node` is built with CUDA.
- In Bun / Deno, default to `cpu`; check the
specific runtime's device support before
picking anything faster.
## 4. The mandatory pattern
Every pipeline must:
1. Be created with `await pipeline(task,
model, { device })`.
2. Be invoked with a single input or an
array of inputs.
3. Be disposed with `await pipe.dispose()`
when the work is done.
Skipping `dispose()` leaks GPU / WASM memory.
The leak is silent; the browser tab gets slow
and then crashes.
Minimal example (text classification):
```javascript
import { pipeline } from '@huggingface/transformers';
const pipe = await pipeline(
'sentiment-analysis',
null, // use the default model for the task
{ device: 'webgpu' }
);
try {
const out = await pipe('I love this library.');
// out === [{ label: 'POSITIVE', score: 0.9998 }]
} finally {
await pipe.dispose();
}
For RAG, semantic search, dedup, or
clustering, use feature-extraction and
compute the dot / cosine yourself:
import { pipeline, dot } from '@huggingface/transformers';
const embed = await pipeline(
'feature-extraction',
'Xenova/all-MiniLM-L6-vq',
{ device: 'webgpu', dtype: 'q8' }
);
try {
const a = await embed('pug', { pooling: 'mean', normalize: true });
const b = await embed('bulldog', { pooling: 'mean', normalize: true });
const sim = dot(a.data, b.data);
// sim is the cosine similarity when normalize: true
} finally {
await embed.dispose();
}
The pooling: 'mean', normalize: true pair is
the convention for sentence-transformers
embeddings. Forgetting normalize: true makes
the dot product meaningless; the model
returns raw hidden states, not unit vectors.
Inference in the main thread freezes the UI. Always run the pipeline in a Web Worker.
?worker importdispose(); the main thread just sends
messagesenv.localModelPath and ship the ONNX
files with your app.These are the bugs that bite every new user. Check them before shipping:
dispose() — the most common
bug. Always try { ... } finally { await pipe.dispose() } or use a
helper that disposes on a timeout.mean for sentence
embeddings, none for token-level
features. Picking the wrong one gives
nonsense numbers.normalize: true for embeddings —
dot product is not cosine.q8,
q4) when download size matters.
# When NOT to use
- **Server-side model serving at scale** — use
a Python service with vLLM / TGI / TensorRT.
JS inference does not compete on throughput.
- **Custom PyTorch model with no ONNX export**
— convert to ONNX first, or use a Python
service.
- **Sub-10ms latency budget on a large model**
— JS can't compete. Use a server.
- **Cloudflare Workers (free tier) or other
size-constrained runtimes** — model weights
may exceed the bundle / memory limit. Check
before committing.
- **No clear task** — "do ML" is not a task.
Pick a specific task or don't use this
skill.
- **The user wants a hosted API** — don't
reinvent the API. Use the API.
# Example
**Input:**
```yaml
task: sentence-similarity
runtime: browser
model_id: Xenova/all-MiniLM-L6-vq
device: webgpu
Output:
## Stack
- Runtime: browser (Web Worker recommended)
- Pipeline: `feature-extraction` (and
post-process for cosine)
- Model: `Xenova/all-MiniLM-L6-vq` (q8
quant, ~23MB)
- Device: WebGPU → WASM fallback
## Install
```bash
npm install @huggingface/transformers
// embed-worker.js
import { pipeline, dot } from '@huggingface/transformers';
let pipe = null;
self.onmessage = async (e) => {
if (e.data.type === 'init') {
pipe = await pipeline(
'feature-extraction',
'Xenova/all-MiniLM-L6-vq',
{ device: 'webgpu', dtype: 'q8' }
);
self.postMessage({ type: 'ready' });
return;
}
if (e.data.type === 'embed') {
const out = await pipe(e.data.text, {
pooling: 'mean', normalize: true
});
self.postMessage({
type: 'result', id: e.data.id, vec: out.data
});
}
if (e.data.type === 'dispose') {
await pipe.dispose();
self.postMessage({ type: 'disposed' });
}
};
dispose() wired to a Worker shutdown
handlerpooling: 'mean', normalize: true on
every call