ink-component-patterns

v2026.09.24

Use when building terminal UIs with Ink component patterns for React-based CLI applications.

GitHub
Install command
npx skhub add thebushidocollective/ink-component-patterns
Markdown
SKILL.md

Ink Component Patterns

You are an expert in building terminal UIs with Ink, React for the terminal.

Core Principles

  • Use functional components with TypeScript for type safety
  • Leverage Ink's built-in components (Box, Text, Newline, Spacer)
  • Keep components focused and composable
  • Use proper prop types and interfaces
  • Handle terminal resizing gracefully

Component Structure

Basic Component

import { Box, Text } from 'ink';
import React from 'react';

interface MyComponentProps {
  title: string;
  items: string[];
}

export const MyComponent: React.FC<MyComponentProps> = ({ title, items }) => {
  return (
    <Box flexDirection="column">
      <Text bold color="cyan">
        {title}
      </Text>
      {items.map((item, index) => (
        <Box key={index} marginLeft={2}>
          <Text>• {item}</Text>
        </Box>
      ))}
    </Box>
  );
};

Layout Patterns

Vertical Stack

<Box flexDirection="column">
  <Text>First item</Text>
  <Text>Second item</Text>
</Box>

Horizontal Row

<Box>
  <Text>Left</Text>
  <Spacer />
  <Text>Right</Text>
</Box>

Centered Content

<Box justifyContent="center" alignItems="center" height={10}>
  <Text>Centered content</Text>
</Box>

Padded Container

<Box padding={1} borderStyle="round" borderColor="cyan">
  <Text>Content with border and padding</Text>
</Box>

Common Patterns

List with Icons

interface ListItem {
  icon: string;
  label: string;
  value: string;
}

const List: React.FC<{ items: ListItem[] }> = ({ items }) => (
  <Box flexDirection="column">
    {items.map((item, i) => (
      <Box key={i}>
        <Text color="yellow">{item.icon} </Text>
        <Text bold>{item.label}: </Text>
        <Text>{item.value}</Text>
      </Box>
    ))}
  </Box>
);

Status Messages

const StatusMessage: React.FC<{ type: 'success' | 'error' | 'warning'; message: string }> = ({
  type,
  message,
}) => {
  const config = {
    success: { icon: '✅', color: 'green' },
    error: { icon: '❌', color: 'red' },
    warning: { icon: '⚠️', color: 'yellow' },
  };

  const { icon, color } = config[type];

  return (
    <Box>
      <Text color={color}>
        {icon} {message}
      </Text>
    </Box>
  );
};

Progress Indicator

const ProgressIndicator: React.FC<{ current: number; total: number; label: string }> = ({
  current,
  total,
  label,
}) => (
  <Box>
    <Text color="blue">
      {label}: {current}/{total}
    </Text>
  </Box>
);

Collapsible Section

const CollapsibleSection: React.FC<{ title: string; isOpen: boolean; children: React.ReactNode }> = ({
  title,
  isOpen,
  children,
}) => (
  <Box flexDirection="column">
    <Text bold>
      {isOpen ? '▼' : '▶'} {title}
    </Text>
    {isOpen && <Box marginLeft={2}>{children}</Box>}
  </Box>
);

Best Practices

  1. Type Safety: Always define prop interfaces
  2. Performance: Use React.memo for expensive renders
  3. Accessibility: Use semantic structure and clear labels
  4. Error Boundaries: Wrap components in error boundaries
  5. Testing: Test components with ink-testing-library

Anti-Patterns to Avoid

  • Don't use DOM-specific APIs (document, window)
  • Don't use CSS classes or inline styles (use Ink props)
  • Don't mutate terminal state directly
  • Don't forget to handle edge cases (empty arrays, null values)
  • Don't create deeply nested component trees (keep it flat)
Discovery
Tags

No tags published for this skill.

Version
Latest version metadata

Version

v2026.09.24

Published

Sep 24, 2026

Category

Uncategorized

License

NOASSERTION

Source path

plugins/frameworks/ink/skills/ink-component-patterns

Default branch

main

Latest commit

19caa51

Tree SHA

3c784de