I Ported Moonshine to JavaScript

jreynar2 pts0 comments

Why I ported Moonshine to Javascript " Pete Warden's blog

August 15, 2026 By Pete Warden in Uncategorized Tags: ai, artificial-intelligence, javascript, llm, technology Leave a comment

One of the most common requests I’ve heard from developers is an in-browser version of Moonshine that can run on a web page. In theory this should be straightforward – we already built MoonshineJS for the previous generation of models, and the core library is written in portable C++, so emscripten can compile it into WASM. There have even been some interesting community porting projects but I held off on official support until I had time to do it justice.

I knew that porting the C++ core was just the beginning. Building something that would be straightforward for web developers to use required a lot more:

High-level APIs that were both idiomatic for browser Javascript and consistent with the other Moonshine language bindings.

Infrastructure for testing from units to full web pages.

Integration with the existing CI and deployment process.

Examples that were interactive and showed the key capabilities of the library, with interactive inline code.

Larger applications that demonstrated and tested how the framework runs in real-world conditions.

Improved support for in-memory models and data files. This was involved a lot of changes to the core library, because while there had always been some methods that took memory buffers, coverage was patchy compared to loading from files.

After a lot of work, I finally have a version ready for feedback. The easiest way to try it is on the new moonshine.ai home page, where you can now see everything from a minimal transcription example to a full-blown Granola-style meeting note taker. As an open-source project, all the code for these is available and the simple examples include code snippets in-line too. Here’s one that shows how to run speech to text on a web page, to give you a flavor of the API:

import { MicTranscriber, ModelArch } from 'https://cdn.jsdelivr.net/npm/@moonshine-ai/moonshine-wasm/dist/index.js';

const mic = new MicTranscriber()

.modelArch(ModelArch.MediumStreaming)

.onText((text) => showInProgress(text))

.onLine((line) => appendLine(line.text, line.lastTranscriptionLatencyMs));

await mic.load();

await mic.start();

You may still be asking yourself why I made supporting Javascript in the browser such a priority? A lot of “X ported to WASM” stories end up being Hacker News bait without having any practical uses. The evidence that drove me was:

Clear developer demand . It came up frequently as a wishlist item when talking to users.

Javascript’s dominance . Python rules machine learning, but JS is the most common language for applications, web and server-side.

Advantages over alternatives . Voice interfaces are clearly only going to grow in importance over the next few years, but browser APIs are neglected and server-based alternatives are slow and costly compared to our on-client framework.

Obvious applications . Dictation and meeting note taking are popular use cases for speech technology already, and talking with AI bots is becoming a lot more common too.

Technical alignment . Deep in my bones I know that voice interfaces want to run on the client. The current status quo of streaming audio data to a server just to get text and intent back only exists because models used to be too large to run on consumer hardware. Today even household appliances have enough compute horsepower for local voice agents. It offends my engineering sensibilities to see old approaches linger on purely out of inertia. Speech wants to be free to use and local, just like all our other input devices like keyboards, mice, touchscreens, and cameras. Porting makes that possible on the web.

Options . These days a lot of us have to frequently switch between languages and operating systems, and the power of AI coding assistants only increases the pressure to rapidly port applications. A library dependency is a big commitment, and knowing that it will be available anywhere you’re likely to run in the future makes the risk of betting on a framework much lower, even if you don’t need the option in the end.

I’m excited to get feedback on how to improve the initial version, and I’m looking forward to hearing about what people build with it, so please come by our Discord channel if you’d like to join our community.

Share this:

Share on X (Opens in new window)

Share on Facebook (Opens in new window)<br>Facebook

Like Loading...

Related

Leave a comment Cancel reply

Type your email…

Subscribe

Join 2,098 other subscribers

RSS - Posts

Recent Posts

Why I ported Moonshine to Javascript

How to set up Raspberry Pi wifi by just talking

Launching Moonshine Micro

Meet Fiona and Abby

Launching a free, open-source, on-device transcription app

Recent Comments

Ideal Dataset Size f… on How many images do you need to…How to set up Raspbe… on Why has the Internet of Things…Thomas on Launching...

moonshine javascript from text ported browser

Related Articles