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 🙏

© 2025 – Pkg Stats / Ryan Hefner

monaco-esm

v2.0.1

Published

Native ES module build of Monaco Editor with bundled workers and styles. No AMD, no config — just import and go.

Readme

monaco-esm

Made with ❤️ by flexbe.ai team

monthly downloads license npm version PRs welcome

A native ES module build of Monaco Editor — no bundlers, no AMD, no RequireJS. Just import and start coding.


Why this exists

Monaco Editor powers VS Code — but using it outside of that context is a headache. By default, it's distributed as an AMD module and requires require.js to load. Even community tools like @monaco-editor/loader rely on dynamic CDN scripts and require additional setup for workers and styles.

This package provides a modern ESM-friendly build of Monaco Editor that can be used directly in the browser or in any bundler without dealing with require.js, manual worker registration, or separate CSS files.


What it does

  • ✅ Native ES module build of Monaco Editor
  • ✅ Bundles all workers and CSS
  • ✅ No external loader or config required
  • ✅ Works in modern browsers and with any bundler
  • ✅ Exports full Monaco API and TypeScript types

Install

npm install monaco-esm monaco-editor

Usage

Basic Setup with Bundler (Vite, Webpack, Rollup, etc.)

import { monaco, loadCss } from 'monaco-esm';
import { initMonaco } from 'monaco-esm';
import editorWorker from 'monaco-esm/workers/editor';
import htmlWorker from 'monaco-esm/workers/html';
import cssWorker from 'monaco-esm/workers/css';
import typescriptWorker from 'monaco-esm/workers/typescript';
import jsonWorker from 'monaco-esm/workers/json';

// Note: add only workers that you need (e.g js/ts worker is pretty heavy so if you going to use only html/css/json, you don't need to add it)
initMonaco({
    workers: {
        editor: editorWorker,
        html: htmlWorker,
        css: cssWorker,
        typescript: typescriptWorker,
        json: jsonWorker,
    },
});

// Use this to inject styles into the page if you're not using bundler that support css bundling (like Vite)
loadCss();

monaco.editor.create(document.getElementById('container'), {
  value: 'console.log("Hello, world!");',
  language: 'javascript'
});

Note: If you're using a bundler that supports CSS bundling (like Vite), you don't need to call loadCss(). Otherwise, call it to inject styles into the page.

Using Custom Workers with Vite

You can import workers from monaco-editor directly:

import { initMonaco } from 'monaco-esm';
import EditorWorker from 'monaco-editor/esm/vs/editor/editor.worker.js?worker';

initMonaco({
    workers: {
        editor: EditorWorker,
    },
});

In the browser (no bundler)

<script type="module">
  import { monaco, loadCss } from 'https://esm.sh/monaco-esm';

  loadCss();

  monaco.editor.create(document.getElementById('container'), {
    value: 'function hello(name = "world") {\n  console.log(`Hello ${name}!`);\n}',
    language: 'javascript'
  });
</script>

👉 Live Example on CodeSandbox


Why not use @monaco-editor/loader?

@monaco-editor/loader solves part of the problem — but it still:

  • Loads Monaco via CDN
  • Requires require.js (AMD)
  • Needs custom worker setup
  • Doesn't inject styles

monaco-esm removes all that friction:

  • Native ES module build
  • No CDN or AMD loader
  • Workers included and auto-registered
  • One-liner for CSS injection
  • Cleaner setup and better compatibility

API Overview

This package exports:

  • monaco: Full Monaco Editor API
  • loadCss(styleId?, doc?): Injects Monaco's built-in CSS into the document
  • initMonaco(options?): Initialize Monaco with custom configuration (called automatically on import)
  • Re-exports all types and APIs from monaco-editor

TypeScript Support

You don't need to install monaco-editor separately. All types and APIs are re-exported:

import type { monaco, editor } from 'monaco-esm';

export type MonacoEditor = typeof monaco;
export type MonacoModel = editor.ITextModel;

Entry Points

This package provides two standard Node-compatible entrypoints:

  • dist/index.mjs — ESM build (used by modern bundlers and type: module projects)
  • dist/index.cjs — CommonJS build (for Node.js environments)

By default, most tools will resolve the correct one automatically. You can also import explicitly if needed:

// ESM
import { monaco } from 'monaco-esm';

// CommonJS
const { monaco } = require('monaco-esm');

Framework-Specific Notes

Electron

This package works well in Electron. If you're loading workers in a sandboxed context, you may need to configure security policies accordingly.

Next.js

You can use monaco-esm in Next.js projects, but make sure to call loadCss() only on the client side (e.g., inside a useEffect).

Vite

When using Vite, you have two options for handling workers:

  1. Import workers directly from monaco-editor (see example above)
  2. Use the prebundled workers from monaco-esm/workers

Advanced: initMonaco Customization

The initMonaco method is called automatically when you import this package, so you usually do not need to call it yourself. However, you can call it manually to customize Monaco's worker setup and TypeScript language service behavior.

Why customize?

You might want to:

  • Provide your own getWorker method to control how Monaco spawns web workers
  • Specify a customTSWorkerPath to load a custom TypeScript worker script (must export a customTSWorkerFactory)
  • Directly provide a customTSWorkerFactory function to extend or override the TypeScript language service worker

Usage

import { initMonaco } from 'monaco-esm';

// 1. Provide your own getWorker method
initMonaco({
  getWorker: (workerId, label) => {
    // Return a custom Worker instance
    if (label === 'my-custom-language') {
      return new Worker(...);
    }
    // ...handle other labels
  },
});

// 2. Specify a custom TypeScript worker path
//    This must set a `self.customTSWorkerFactory` function
initMonaco({
  customTSWorkerPath: '/my-custom-ts-worker.js',
});

// 3. Extend the TypeScript language service with a custom factory
initMonaco({
  // NOTE: This function will be stringified and passed to the worker, so you can't use closures here
  customTSWorkerFactory: (TSWorkerClass, tsc, libs) => {
    class CustomTSWorker extends TSWorkerClass {
      constructor(ctx, createData) {
        super(ctx, createData);
        // Your custom logic here
      }
    }
    return CustomTSWorker;
  },
});
  • If you use customTSWorkerFactory, you can extend Monaco's TypeScript language service worker. See the original tsWorker implementation for what you can override or extend.
  • If you use customTSWorkerPath, the file must assign a customTSWorkerFactory function to self.

Note: These options are advanced and only needed for deep customization. For most users, the default setup is sufficient.


License

MIT — see LICENSE