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

runonweb

v0.1.0

Published

Free browser ML modules: speech, vision, text. Runs locally with WebGPU or WASM.

Readme

runonweb

Run AI locally in the browser with one import. No API keys, backend, or file uploads.

Install

npm install runonweb

Quick start

import { removeBackground } from 'runonweb/remove-bg'

const png = await removeBackground(imageFile)
const url = URL.createObjectURL(png)

imageFile can be a File from an <input type="file">. The first call downloads the model; the browser caches it for later use.

For repeated operations, reuse an instance and call dispose() when finished:

import { RemoveBackground } from 'runonweb/remove-bg'

const remover = new RemoveBackground({
  onProgress: ({ status, progress }) => console.log(status, progress),
})

const first = await remover.remove(firstFile)
const second = await remover.remove(secondFile)

remover.dispose()

More examples

Speech to text

import { transcribe } from 'runonweb/stt'

const { text } = await transcribe(audioFile, {
  onPartial: (partial) => console.log(partial),
})

Image captioning

import { caption } from 'runonweb/caption'

const { text } = await caption(imageFile, {
  language: 'es',
  detail: 'short', // 'short' | 'detailed' | 'more'
})

License: Image captioning uses the LFM Open License v1.0. It is free for individuals and companies under USD 10M annual revenue; larger companies need a commercial license.

Depth estimation

import { estimateDepth } from 'runonweb/depth'

const { depth } = await estimateDepth(imageFile)
const url = URL.createObjectURL(depth) // Grayscale PNG: brighter means closer.

Object detection

import { detect } from 'runonweb/detect'

const objects = await detect(imageFile, { threshold: 0.5 })
// [{ label: 'cat', score: 0.98, box: { xmin, ymin, xmax, ymax } }]

OCR

import { read } from 'runonweb/ocr'

const { text, lines } = await read(imageFile, {
  size: 'small', // 'tiny' | 'small' | 'medium'
})

Text embeddings

import { embed, cosineSimilarity } from 'runonweb/embed'

const { embeddings } = await embed(['Hello world', 'Hola mundo'])
const similarity = cosineSimilarity(embeddings[0], embeddings[1])

Text classification

import { classify } from 'runonweb/classify'

const { answers } = await classify({
  state: 'Shoes arrived two weeks late and in the wrong size.',
  questions: {
    department: {
      type: 'choice',
      instructions: 'Which team should handle this?',
      criteria: { returns: null, shipping: null, billing: null },
    },
    escalate: {
      type: 'noul',
      instructions: 'Does this need urgent human attention?',
    },
  },
})

console.log(answers.department.choice)
console.log(answers.escalate.noul) // Probability of "yes".

Translation

import { translate } from 'runonweb/translate'

const { text } = await translate('Hello world', {
  from: 'en',
  to: 'es',
})

Transcript cleanup

import { clean } from 'runonweb/clean'

const { text } = await clean(
  'so um i need to like send the report by uh friday',
  { styling: 'semi-formal', structure: 'prose', context: 'general' },
)

Text to emoji

import { emojify } from 'runonweb/emoji'

const { text, emojis } = await emojify('I love pizza and my dog')
// text: '🍕❤️🐶'

Text to speech

import { TextToSpeech } from 'runonweb/tts'

const tts = new TextToSpeech({ voice: 'af_heart' })
const wav = await tts.speakToBlob('Hello from the browser')
const url = URL.createObjectURL(wav)

tts.dispose()

For English, Korean, Spanish, Portuguese, or French, use new TextToSpeech({ size: 'multi', voice: 'st_f1', language: 'es' }).

Text to image

Requires WebGPU.

import { generateImage } from 'runonweb/image'

const { image } = await generateImage('A bonsai tree in a ceramic studio')
const url = URL.createObjectURL(image) // PNG Blob.

API documentation and live demos · Model details and licenses