Monaco Editor: The VS Code Editor as a Browser Library, With Strings Attached
GitHub describes it as A browser based code editor. The repository metadata lists JavaScript as its primary language. The metadata lists the MIT license. This article stays within the project description and details documented in the GitHub repository README.
At a glance
- What is it?
- Monaco Editor brings the full VS Code editing experience to the browser, but its model and worker architecture demand careful integration. This review covers what it solves, how it works, and where it trips up.
- Who is it for?
- Adopt Monaco Editor if you need a browser-based code editor with VS Code-grade editing, syntax highlighting, and language services, and you can serve it over HTTP and manage web workers. Avoid it for mobile web apps, for file:// deployments, or if you need TextMate grammars without extra glue.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 3 days ago.
- What is it written in?
- Mainly JavaScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on November 13, 2026, and from our analysis. They are not legal advice.
Star history
- microsoft/monaco-editor46,969 ★ · +421
| Repository | 2026-08-13 | 2026-11-13 |
|---|---|---|
| microsoft/monaco-editor | 46.5k | 47k |
421 Stars in the last 92 days, measured from the daily GitHub snapshot. Compare with other projects
Editorial analysis
What Monaco Editor Actually Gives You
Monaco Editor is the code editor component extracted from VS Code, repackaged as a JavaScript library for the browser. It solves a specific problem: embedding a full-featured code editor into a web application without building one from scratch. It is not a VS Code replacement in the browser: VS Code extensions will not work, and the version numbers of Monaco and VS Code have no relationship. What you get is the editor core: syntax highlighting, IntelliSense, multi-cursor editing, find and replace, and a programmable API. This is for teams building web IDEs, code playgrounds, documentation sites with live editing, or any tool where users write code or structured text. If your need is a simple textarea with a few lines of code, Monaco is overkill. But if you need editing features that match a desktop IDE, it is one of the few credible options.
The Architecture: Models, URIs, and Providers
The README describes a clean separation of concerns. A model is the underlying data object: it holds text content, tracks edit history, and knows which language the content uses. Each model is tied to a URI, which must be unique. This URI is not just an identifier; it drives language services. For example, TypeScript import resolution and JSON schema selection depend on the file path you assign to the model. The README advises thinking of your content as a virtual file system that mirrors what users are editing. An editor is a view onto a model, attached to the DOM. Providers supply smart features like completion and hover, and they operate on models, not on editor instances. This separation means you can have multiple editors showing the same model, or swap models without recreating the editor. It also means you must be deliberate about URIs: pick a scheme like file:/// and stick to a consistent structure, or features that rely on file paths will misbehave.
Installation and the ESM vs AMD Split
Getting Monaco running starts with a single command: npm install monaco-editor. The package ships an ESM version under /esm, which works with bundlers like webpack. It also includes monaco.d.ts, the API declaration file that is the only versioned public surface. The README warns that everything else is private and can break between releases. The AMD build is still shipped for backwards compatibility, but the README explicitly calls it deprecated and slated for removal. This matters for legacy integrations that load Monaco via script tags or require.js. If you are starting fresh, use the ESM build and a bundler. The README also points to a dedicated integration guide for the ESM version, which suggests the setup is not trivial. You will need to configure web workers for language services, and the README's FAQ hints that getting workers to work correctly is a common stumbling block.
Web Workers: The Cross-Domain Catch
Language services in Monaco run in web workers to keep heavy computation off the UI thread. The README says these workers cost little in resource overhead, but only if you can create them. HTML5 forbids web workers on file:// pages, so loading the editor from a local file will produce the warning 'Could not create web worker'. The fix is to serve the editor over http:// or https://. This is a hard constraint, not a suggestion. If your deployment target is a static file opened directly from disk, Monaco will fail to provide full language features. Cross-origin setups also complicate worker loading. The takeaway: plan your hosting and worker paths before you adopt Monaco. A development server is fine, but production must respect the same-origin policy or you will need to configure worker URLs explicitly.
Localization and the nls Script Order
Monaco supports localized UI strings, but the mechanism is fragile. The README says to load a language-specific nls script before the main editor script. The example shows a script tag for German: <script src="path/to/monaco-editor/esm/nls.messages.de.js"></script>. The order is non-negotiable: if the nls file loads after the editor, the localization will not apply. The README does not list all available languages, telling you to check the sources. This is a minor feature, but it illustrates a broader point about Monaco's integration style: many things depend on load order and global script state. In a bundler-based ESM setup, this might require careful import ordering or dynamic script injection. For a simple English-only editor, you can ignore this. For a multilingual product, budget time to verify each language file loads correctly.
Disposables and Resource Management
Monaco objects implement a .dispose() method to clean up resources. The README gives two examples: calling model.dispose() unregisters the model and frees its URI for reuse, and editors should be disposed to remove model listeners. This is not optional hygiene; it is core to the API. If you create models dynamically, as a code playground would, failing to dispose them leaves their URIs taken. The README also notes that many objects are disposable, so you need a consistent pattern for tracking and cleaning up. This adds boilerplate to your application code. The payoff is control over the editor's lifecycle, which is useful in single-page apps where users open and close files. But it is a sharp edge: forget a dispose call and you have a slow leak that is hard to trace.
What It Does Not Do: Mobile, TextMate, and Extensions
The README is blunt about three gaps. First, no support for mobile browsers or mobile web app frameworks. If your target is iOS Safari or a hybrid app, look elsewhere. Second, no native TextMate grammar support. The README points to a third-party project, monaco-tm, that combines monaco-editor with vscode-oniguruma and vscode-textmate to get that functionality. That means if you rely on TextMate grammars for syntax highlighting, you are on your own to wire up an extra library. Third, VS Code extensions do not work in Monaco. The only exception is if an extension is fully based on LSP and the language server is written in JavaScript, in which case it might be portable. These limitations are not hidden; they are stated plainly. But they are easy to miss when you evaluate Monaco based on its VS Code pedigree. The editor is powerful, but it is not a drop-in replacement for VS Code's extension ecosystem.
Alternatives and the Real Trade-Off
The obvious alternative is CodeMirror, a browser code editor that is lighter and more modular. CodeMirror does not come from VS Code, so it does not carry the same heavyweight language services. It supports mobile browsers better and has a simpler worker story. The trade-off is depth of features: Monaco gives you IntelliSense, multi-cursor editing, and a rich API out of the box, while CodeMirror requires you to assemble those features from its extension system. Another alternative is Ace, which is older and simpler but lacks the modern language service integration. For a project that needs a full IDE feel, Monaco is the stronger choice. For a lightweight editor on a mobile-friendly site, CodeMirror is more practical. The README does not mention these alternatives, but the comparison is unavoidable when you hit Monaco's constraints.
Editorial conclusion
Adopt Monaco Editor if you need a browser-based code editor with VS Code-grade editing, syntax highlighting, and language services, and you can serve it over HTTP and manage web workers. Avoid it for mobile web apps, for file:// deployments, or if you need TextMate grammars without extra glue. Before committing, verify your bundler handles the ESM build, test cross-origin worker loading, and confirm the AMD build deprecation does not break your legacy integration.
Frequently asked questions
what is monaco editor
The Monaco Editor is the fully featured code editor from VS Code, generated straight from VS Code's sources with some shims around the services the code needs to make it run in a web browser outside of its home. It is a browser based code editor published on npm as monaco-editor under the MIT license, and version 0.57.0 corresponds to no VS Code version at all because it reflects the source directly.
how to install monaco editor
Run npm install monaco-editor. You get an ESM version of the editor inside /esm, compatible with e.g. webpack, and monaco.d.ts, which specifies the API of the editor and is what is actually versioned, while everything else is considered private and might break with any release. An AMD build is also shipped for backwards-compatibility reasons, but AMD support is deprecated and will be removed in future versions.
how to use monaco editor in react
There is no named React integration guide; what the repository offers is bundler samples, samples/browser-esm-vite-react/ and samples/browser-esm-webpack-typescript-react/, plus the ESM guide at docs/integrate-esm.md. The lifecycle rule that matters in a component is that editors should be disposed to free up resources and remove their model listeners, and that model.dispose() unregisters the model and frees its URI for a new model.
how to use monaco editor in angular
The samples directory has no Angular project. What exists covers webpack, esbuild, parcel, vite, vite with React, electron, legacy and the NW.js AMD pair, so an Angular user is expected to follow the ESM integration guide at docs/integrate-esm.md and consume the ESM build inside /esm of the installed package.
Is Monaco editor free to use?
Yes, the library is under the MIT license with LICENSE.txt and ThirdPartyNotices.txt in the repository, and it is published on npm as monaco-editor. The costs are not licensing but what you supply yourself: a language service or your own providers for smart features, a grammar story, since TextMate grammars are not supported, and a real web server, because HTML5 does not allow pages loaded on file:// to create web workers.
Is Monaco editor a good choice?
The project answers this per use case rather than overall. It says the interactive playground is the best way to learn how to use the editor and to build minimal reproducible examples, and it states plainly that the editor is not supported in mobile browsers or mobile web app frameworks, that VS Code extensions do not work unless they are fully LSP-based with a language server authored in JavaScript, and that TextMate grammars are not supported.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/microsoft-monaco-editor)Star history chart for your README
[](https://hysenlabs.com/projects/microsoft-monaco-editor)Was this useful?