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

@principal-ade/industry-themed-terminal

v0.1.14

Published

Industry-themed terminal wrapper with integrated theming for xterm.js

Downloads

1,841

Readme

@principal-ade/industry-themed-terminal

Industry-themed terminal wrapper with integrated theming support for xterm.js.

Features

  • Seamless integration with @a24z/industry-theme
  • Automatic theme synchronization with xterm.js
  • Built on pure UI component architecture (no backend dependencies)
  • TypeScript support with full type definitions
  • Custom CSS theming via CSS custom properties
  • Customizable header, badges, and overlays
  • Support for all xterm.js addons (FitAddon, SearchAddon, WebLinksAddon, etc.)
  • Programmatic control via imperative ref API
  • Scroll preservation and user intent tracking
  • Optional WebGL rendering support

Installation

npm install @principal-ade/industry-themed-terminal @xterm/xterm @a24z/industry-theme

or with bun:

bun add @principal-ade/industry-themed-terminal @xterm/xterm @a24z/industry-theme

Optional addons:

npm install @xterm/addon-fit @xterm/addon-search @xterm/addon-web-links

Usage

Basic Usage with Theme Provider

import { ThemedTerminalWithProvider } from '@principal-ade/industry-themed-terminal';
import '@xterm/xterm/css/xterm.css';
import '@principal-ade/industry-themed-terminal/styles.css';

function App() {
  const handleData = (data: string) => {
    // Send data to your backend (WebSocket, HTTP, etc.)
    console.log('User input:', data);
  };

  return (
    <ThemedTerminalWithProvider
      onData={handleData}
      headerTitle="Terminal"
      headerSubtitle="/home/user/project"
    />
  );
}

Usage with Explicit Theme

import { ThemedTerminal } from '@principal-ade/industry-themed-terminal';
import { useTheme } from '@a24z/industry-theme';
import '@xterm/xterm/css/xterm.css';
import '@principal-ade/industry-themed-terminal/styles.css';

function Terminal() {
  const { theme } = useTheme();

  const handleData = (data: string) => {
    // Send to backend
    websocket.send(data);
  };

  return (
    <ThemedTerminal
      theme={theme}
      onData={handleData}
      headerTitle="Terminal"
    />
  );
}

With Programmatic Control

import { ThemedTerminal, ThemedTerminalRef } from '@principal-ade/industry-themed-terminal';
import { useRef, useEffect } from 'react';

function Terminal() {
  const terminalRef = useRef<ThemedTerminalRef>(null);

  useEffect(() => {
    // Connect to backend
    const ws = new WebSocket('wss://terminal-server.example.com');

    ws.onmessage = (event) => {
      // Write data from backend to terminal
      terminalRef.current?.write(event.data);
    };

    return () => ws.close();
  }, []);

  const handleData = (data: string) => {
    ws.send(data);
  };

  const handleClear = () => {
    terminalRef.current?.clear();
  };

  return (
    <>
      <button onClick={handleClear}>Clear Terminal</button>
      <ThemedTerminal
        ref={terminalRef}
        onData={handleData}
        headerTitle="Terminal"
      />
    </>
  );
}

With Custom Header and Actions

import { ThemedTerminal } from '@principal-ade/industry-themed-terminal';

function Terminal() {
  return (
    <ThemedTerminal
      onData={handleData}
      headerTitle="Terminal"
      headerSubtitle="/home/user/project"
      headerBadge={{ label: 'Running', color: '#50fa7b' }}
      onClose={() => console.log('Hide terminal')}
      onPopOut={() => console.log('Pop out terminal')}
      onDestroy={() => console.log('Destroy terminal')}
    />
  );
}

With Overlay State

import { ThemedTerminal } from '@principal-ade/industry-themed-terminal';
import { Monitor } from 'lucide-react';

function Terminal() {
  const overlayState = {
    message: 'Terminal is owned by another window',
    subtitle: 'This terminal is currently active in a different window.',
    opacity: 1.0, // Full opacity (default) - completely hides terminal content
    actions: [
      {
        label: 'Claim Ownership',
        primary: true,
        onClick: () => console.log('Claim ownership'),
      },
    ],
  };

  return (
    <ThemedTerminal
      onData={handleData}
      overlayState={overlayState}
    />
  );
}

The opacity property controls the overlay background opacity (0-1):

  • 1.0 (default): Full opacity - completely hides terminal content
  • 0.85: Semi-transparent - terminal content slightly visible
  • 0.5: Very transparent - terminal content clearly visible
  • Omitted: Defaults to 1.0 for full opacity

API

ThemedTerminal Props

| Prop | Type | Default | Description | |------|------|---------|-------------| | theme | Theme | Required | Industry theme object | | onData | (data: string) => void | - | Callback when user types | | onBinary | (data: string) => void | - | Callback for binary data | | onResize | (cols: number, rows: number) => void | - | Callback when terminal resizes | | onLinkClick | (url: string, isLocalhost: boolean) => void | - | Callback when link is clicked | | headerTitle | string | 'Terminal' | Header title text | | headerSubtitle | string | - | Header subtitle text | | headerBadge | { label: string; color?: string } | - | Header badge | | hideHeader | boolean | false | Hide the header | | autoFocus | boolean | true | Auto-focus on mount | | isVisible | boolean | true | Visibility state | | scrollbarStyle | 'overlay' \| 'hidden' \| 'thin' \| 'auto-hide' | 'overlay' | Scrollbar style | | onClose | () => void | - | Hide button callback | | onDestroy | () => void | - | Destroy button callback | | onPopOut | () => void | - | Pop-out button callback | | overlayState | OverlayState | - | Overlay message state | | className | string | - | Additional CSS classes |

ThemedTerminalWithProvider Props

Same as ThemedTerminal but without the theme prop (uses theme from context).

ThemedTerminalRef Methods

interface ThemedTerminalRef {
  write: (data: string | Uint8Array) => void;
  writeln: (data: string) => void;
  clear: () => void;
  scrollToBottom: () => void;
  focus: () => void;
  getTerminal: () => Terminal | null;
  findNext: (term: string, options?: ISearchOptions) => boolean;
  findPrevious: (term: string, options?: ISearchOptions) => boolean;
  clearSearch: () => void;
  fit: () => void;
}

useThemedTerminal Hook

const { theme, getTerminalOptions } = useThemedTerminal();

Returns:

  • theme - Processed theme object with terminal-specific values
  • getTerminalOptions() - Function that returns xterm.js terminal options

Backend Integration

This package provides only the UI component. You need to provide your own backend for terminal functionality:

WebSocket Example

import { ThemedTerminal, ThemedTerminalRef } from '@principal-ade/industry-themed-terminal';
import { useRef, useEffect } from 'react';

function Terminal() {
  const terminalRef = useRef<ThemedTerminalRef>(null);
  const ws = useRef<WebSocket>();

  useEffect(() => {
    ws.current = new WebSocket('wss://your-terminal-backend.com');

    ws.current.onmessage = (event) => {
      terminalRef.current?.write(event.data);
    };

    ws.current.onclose = () => {
      terminalRef.current?.write('\r\nConnection closed\r\n');
    };

    return () => ws.current?.close();
  }, []);

  const handleData = (data: string) => {
    ws.current?.send(data);
  };

  const handleResize = (cols: number, rows: number) => {
    ws.current?.send(JSON.stringify({ type: 'resize', cols, rows }));
  };

  return (
    <ThemedTerminal
      ref={terminalRef}
      onData={handleData}
      onResize={handleResize}
    />
  );
}

CSS Custom Properties

The package uses CSS custom properties for theming:

  • --terminal-bg - Background color
  • --terminal-fg - Foreground (text) color
  • --terminal-border - Border color
  • --terminal-header-bg - Header background
  • --terminal-font-family - Font family
  • --terminal-font-size - Font size

License

MIT © Principal ADE Team