Spike: how Monaco should be loaded and versioned
- Dominant language
- TypeScript
- Stars
- 481
- Forks
- 108
- Avg merge
- 6d 8h
- Merged PRs (30d)
- 5
Description
## Goal
How should Graph Explorer load the Monaco editor? Today the declared dependency and the code that actually runs are two different things, and the editor is fetched from a public CDN at runtime.
The app imports only `@monaco-editor/react`, which declares `monaco-editor` as a **peer** dependency used for types. The real editor is loaded at runtime by `@monaco-editor/loader` 1.7.0, which hardcodes:
```
https://cdn.jsdelivr.net/npm/monaco-editor@0.55.1/min/vs
```
There is no `loader.config`, no `MonacoEnvironment`, and no `?worker` import anywhere in the repo, so that default is what ships. I confirmed the built bundle contains exactly that URL and that Monaco itself is not bundled, while `node_modules` resolves `monaco-editor` at 0.56.0.
## Consequences of the current setup
- **The editor loads from the public internet at runtime.** In an air-gapped or VPC-only deployment, or under a restrictive Content-Security-Policy, the query editor and the "Error Details" and "Raw response" views render an editor that never loads. This is the impact worth caring about, since the tool is normally deployed into a private VPC alongside Neptune.
- **Bumping `monaco-editor` changes nothing for users.** The 0.55.1 → 0.56.0 bump in the dependency sweep had no runtime effect, so reviewing a Monaco version bump gives false confidence.
- **The editor version can change without a visible diff.** A future `@monaco-editor/loader` or `@monaco-editor/react` bump would silently move the editor users get, with nothing in our manifests to review.
- **98 MB of `monaco-editor` sits in the production dependency closure** and is never served.
- The custom theme is applied through `monaco.editor.defineTheme` in an `onMount` callback, so it operates on whatever version the CDN returns.
## Approaches to investigate
- **Keep `@monaco-editor/react` and pin the runtime explicitly.** Call `loader.config({ paths: { vs: ... } })` against a self-hosted copy served from our own bundle. Smallest change, fixes the offline problem, and makes the declared version the real one. Needs a decision on how the `vs` assets get into the image.
- **Use `monaco-editor` directly and own the React bindings.** Drop `@monaco-editor/react` and `@monaco-editor/loader` and wire the editor up ourselves with a `useEffect` that creates and disposes the instance. Removes two dependencies and the CDN indirection entirely, and makes the bundled version the only version. Cost is the mount/unmount, resize, theme, and model lifecycle we would then maintain — worth estimating honestly against how little of Monaco this app actually uses (`CodeEditor.tsx` is the single consumer).
- **Bundle Monaco through Vite's worker support.** Import the ESM build with `?worker` and configure `MonacoEnvironment` so the editor and its workers are build outputs. Fully offline, but the largest bundle-size impact, so it needs measuring.
Whichever route wins, worth quantifying: bundle size and image size before and after, whether the query editor still highlights JSON and the graph query languages, and whether the workers are needed at all for our read-mostly usage.
## Expected Outcome
A recommendation with enough detail to task out: which approach, what it does to bundle and image size, whether `monaco-editor` stays a runtime dependency or becomes a build input, and confirmation that the editor works with no external network access. A proof of concept for the preferred option would make it much easier to act on.
## Related Issues
- Related to #2149
> [!IMPORTANT]
> Internal only — this issue is maintained by the core team and is not accepting external contributions.
Contributor guide
Research direction
Start by reading CodeEditor.tsx and tracing its @monaco-editor/react and @monaco-editor/loader usage, then inspect the Vite build configuration and dependency manifests. Compare the listed loading approaches by measuring bundle and image size, checking worker needs and language highlighting, and testing the editor with external network access disabled. Done means a documented recommendation and a proof of concept suitable for follow-up tasks.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- react, typescript, vite
- Domain
- build-system, frontend, infrastructure
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 15/100