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

@principal-ade/industry-themed-monaco-editor

v0.1.10

Published

Industry-themed Monaco editor wrapper with presentation capabilities

Readme

@principal-ade/industry-themed-monaco

A Monaco editor wrapper that seamlessly integrates with @principal-ade/industry-theme, providing a themed code editor experience that matches your application's industry theme.

Features

  • 🎨 Automatic theming - Editor theme automatically adapts to your industry-theme colors
  • 🔧 Fully typed - Complete TypeScript support with industry-theme integration
  • 📦 Lightweight - Minimal wrapper around Monaco editor
  • Easy to use - Works standalone or with ThemeProvider
  • 🎯 Configurable - Full access to Monaco editor options
  • ⌨️ Vim mode support - Built-in Vim keybindings with status bar

Installation

npm install @principal-ade/industry-themed-monaco @principal-ade/industry-theme @monaco-editor/react monaco-editor

or with bun:

bun add @principal-ade/industry-themed-monaco @principal-ade/industry-theme @monaco-editor/react monaco-editor

Usage

With ThemeProvider (Recommended)

The easiest way to use the editor is with ThemedMonacoWithProvider, which automatically pulls the theme from React context:

import React, { useState } from 'react';
import { ThemeProvider, terminalTheme } from '@principal-ade/industry-theme';
import { ThemedMonacoWithProvider } from '@principal-ade/industry-themed-monaco';

function App() {
  const [code, setCode] = useState('// Start coding...');

  return (
    <ThemeProvider theme={terminalTheme}>
      <div style={{ height: '100vh' }}>
        <ThemedMonacoWithProvider
          value={code}
          onChange={(value) => setCode(value || '')}
          language="typescript"
          height="100%"
        />
      </div>
    </ThemeProvider>
  );
}

Standalone (Without ThemeProvider)

You can also use ThemedMonacoEditor directly by passing a theme object:

import React, { useState } from 'react';
import { terminalTheme } from '@principal-ade/industry-theme';
import { ThemedMonacoEditor } from '@principal-ade/industry-themed-monaco';

function CodeEditor() {
  const [code, setCode] = useState('console.log("Hello, World!");');

  return (
    <ThemedMonacoEditor
      theme={terminalTheme}
      value={code}
      onChange={(value) => setCode(value || '')}
      language="javascript"
      height="400px"
    />
  );
}

Uncontrolled editing with save shortcuts

ThemedMonacoEditor can manage its own value when you omit the value prop. Provide an initialValue and an onSave callback to let the component keep track of dirty state, show a Saved/Unsaved badge, and hook into Ctrl/Cmd + S:

import { useCallback, useState } from 'react';
import { terminalTheme } from '@principal-ade/industry-theme';
import { ThemedMonacoEditor } from '@principal-ade/industry-themed-monaco';

function FileEditor({ filePath }: { filePath: string }) {
  const [status, setStatus] = useState<'idle' | 'saving' | 'saved' | 'error'>('idle');

  const handleSave = useCallback(
    async (contents: string) => {
      setStatus('saving');
      try {
        const response = await fetch(`/api/files/${encodeURIComponent(filePath)}`, {
          method: 'PUT',
          headers: { 'Content-Type': 'text/plain' },
          body: contents,
        });
        if (!response.ok) {
          throw new Error('Failed to save file');
        }
        setStatus('saved');
      } catch (error) {
        console.error(error);
        setStatus('error');
        throw error;
      }
    },
    [filePath]
  );

  return (
    <div style={{ height: '100%' }}>
      <ThemedMonacoEditor
        theme={terminalTheme}
        filePath={filePath}
        initialValue={'// Contents fetched from your backend'}
        language="typescript"
        height="100%"
        onSave={handleSave}
        onDirtyChange={(dirty) => dirty && setStatus('idle')}
      />
      <div>{status === 'saving' ? 'Saving…' : status === 'error' ? 'Save failed' : null}</div>
    </div>
  );
}

ℹ️ Fetch the initial file contents from your backend, pass them into initialValue, and reuse the same endpoint inside onSave. The save callback can be synchronous or return a promise—ThemedMonacoEditor waits for it to resolve before clearing the dirty badge.

Disable the keyboard shortcut entirely by setting enableSaveShortcut={false} when you want to handle save triggers in your own UI.

Advanced Usage

You can pass any Monaco editor options through the options prop:

import { ThemedMonacoWithProvider } from '@principal-ade/industry-themed-monaco';

function AdvancedEditor() {
  return (
    <ThemedMonacoWithProvider
      value={code}
      onChange={setCode}
      language="typescript"
      height="600px"
      options={{
        minimap: { enabled: true },
        fontSize: 14,
        lineNumbers: 'on',
        readOnly: false,
        wordWrap: 'on',
        scrollBeyondLastLine: false,
        automaticLayout: true,
      }}
    />
  );
}

Vim Mode

Enable Vim keybindings with the vimMode prop. This adds Vim-style navigation and editing commands, along with a status bar showing the current mode:

import { ThemedMonacoWithProvider } from '@principal-ade/industry-themed-monaco';

function VimEditor() {
  return (
    <ThemedMonacoWithProvider
      value={code}
      onChange={setCode}
      language="typescript"
      height="600px"
      vimMode={true}  // Enable Vim mode
    />
  );
}

When Vim mode is enabled:

  • A status bar appears at the bottom showing the current mode (Normal, Insert, Visual, etc.)
  • Standard Vim keybindings are available (i, a, o for insert mode, hjkl for navigation, etc.)
  • The status bar is styled to match your theme

You can also toggle Vim mode dynamically:

function ToggleableVimEditor() {
  const [vimEnabled, setVimEnabled] = useState(false);

  return (
    <>
      <button onClick={() => setVimEnabled(!vimEnabled)}>
        {vimEnabled ? 'Disable' : 'Enable'} Vim Mode
      </button>
      <ThemedMonacoWithProvider
        value={code}
        onChange={setCode}
        language="typescript"
        height="600px"
        vimMode={vimEnabled}
      />
    </>
  );
}

Custom Loading Component

Provide a custom loading component that matches your theme:

import { ThemedMonacoEditor } from '@principal-ade/industry-themed-monaco';
import { terminalTheme } from '@a24z/industry-theme';

function EditorWithCustomLoading() {
  return (
    <ThemedMonacoEditor
      theme={terminalTheme}
      value={code}
      onChange={setCode}
      language="python"
      loadingComponent={
        <div style={{
          color: terminalTheme.colors.primary,
          padding: 20,
          textAlign: 'center'
        }}>
          Loading editor...
        </div>
      }
    />
  );
}

Available Themes

The package works with all themes from @principal-ade/industry-theme:

import {
  terminalTheme,
  regalTheme,
  glassmorphismTheme,
  matrixTheme,
  matrixMinimalTheme,
  slateTheme,
} from '@principal-ade/industry-theme';

API Reference

ThemedMonacoEditor

The base editor component that accepts a theme prop.

Props

| Prop | Type | Required | Description | |------|------|----------|-------------| | theme | Theme | Yes | Industry theme object | | value | string | No | Current editor value | | onChange | (value: string \| undefined) => void | No | Callback when value changes | | language | string | No | Programming language (e.g., 'typescript', 'javascript', 'python') | | height | string \| number | No | Editor height (default: '100%') | | width | string \| number | No | Editor width (default: '100%') | | options | monaco.editor.IStandaloneEditorConstructionOptions | No | Monaco editor options | | loadingComponent | React.ReactNode | No | Custom loading component | | vimMode | boolean | No | Enable Vim mode keybindings (default: false) |

Plus all other props from @monaco-editor/react's EditorProps.

ThemedMonacoWithProvider

A convenience component that automatically uses the theme from ThemeProvider context.

Props

Same as ThemedMonacoEditor but without the theme prop (automatically pulled from context).

Examples

Read-only Code Viewer

<ThemedMonacoWithProvider
  value={sourceCode}
  language="typescript"
  options={{ readOnly: true }}
  height="500px"
/>

Multi-language Editor

function MultiLanguageEditor() {
  const [language, setLanguage] = useState('javascript');
  const [code, setCode] = useState('');

  return (
    <>
      <select value={language} onChange={(e) => setLanguage(e.target.value)}>
        <option value="javascript">JavaScript</option>
        <option value="typescript">TypeScript</option>
        <option value="python">Python</option>
        <option value="json">JSON</option>
      </select>
      <ThemedMonacoWithProvider
        value={code}
        onChange={setCode}
        language={language}
        height="400px"
      />
    </>
  );
}

Monaco Worker Configuration

The package automatically configures Monaco editor workers for the browser environment. If you need custom worker paths, you can configure them before importing the component:

window.MonacoEnvironment = {
  getWorkerUrl: (moduleId: string, label: string) => {
    // Your custom worker configuration
  }
};

License

MIT

Contributing

Contributions are welcome! Please check the repository for guidelines.

Related Packages

Support

For issues and questions, please visit the GitHub repository.