Ink

TUIReactCLIJSXTerminal

GitHub概要

vadimdemedes/ink

🌈 React for interactive command-line apps

ホームページ:https://term.ink
スター30,219
ウォッチ112
フォーク699
作成日:2017年6月12日
言語:TypeScript
ライセンス:MIT License

トピックス

clicommand-lineflexboxinteractivejavascriptreact

スター履歴

vadimdemedes/ink Star History
データ取得日時: 2025/7/25 11:10

Ink

Inkは、React開発者にとって馴染みのあるコンポーネントベースのアプローチでターミナルUIを構築できるJavaScriptライブラリです。「React for CLI」として知られ、Web開発の知識をそのままターミナルアプリケーション開発に活かすことができます。

特徴

Reactコンポーネントベース

  • JSX記法: React同様のJSX記法でターミナルUIを記述
  • 状態管理: useState, useEffectなどのReactフックを使用
  • コンポーネント再利用: UIコンポーネントの再利用が可能
  • 仮想DOM: 効率的な差分レンダリング

豊富な組み込み機能

  • Flexboxレイアウト: Facebook製のYogaレイアウトエンジンを使用
  • テキストスタイリング: 色、太字、下線、取り消し線をサポート
  • フォーカス管理: Tab/Shift+Tabでのフォーカス移動
  • 入力処理: キーボード入力イベントの処理

開発体験

  • TypeScript対応: 型安全な開発が可能
  • ホットリロード: 開発時の高速な反映
  • デバッグ支援: React DevToolsと類似の体験
  • テスト対応: コンポーネントテストが容易

基本的な使用方法

インストール

npm install ink react
# or
yarn add ink react

Hello World

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

const App = () => <Text>Hello World</Text>;

render(<App />);

ユーザー入力の処理

import React, {useState} from 'react';
import {render, Text, useInput} from 'ink';

const Counter = () => {
  const [counter, setCounter] = useState(0);

  useInput((input, key) => {
    if (input === 'q') {
      process.exit();
    }

    if (key.upArrow) {
      setCounter(counter + 1);
    }

    if (key.downArrow) {
      setCounter(counter - 1);
    }
  });

  return (
    <>
      <Text>Count: {counter}</Text>
      <Text color="gray">Use up/down arrows, 'q' to quit</Text>
    </>
  );
};

render(<Counter />);

レイアウト構築

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

const App = () => (
  <Box flexDirection="column" padding={1}>
    <Box marginBottom={1}>
      <Text color="green">Header</Text>
    </Box>
    
    <Box flexDirection="row">
      <Box marginRight={2}>
        <Text>Left Sidebar</Text>
      </Box>
      
      <Box flexGrow={1}>
        <Text>Main Content</Text>
      </Box>
    </Box>
    
    <Box marginTop={1}>
      <Text color="gray">Footer</Text>
    </Box>
  </Box>
);

render(<App />);

主要コンポーネント

Text

テキストの表示とスタイリング

<Text color="red" bold underline>
  Styled text
</Text>

Box

Flexboxベースのレイアウトコンテナ

<Box
  flexDirection="row"
  justifyContent="center"
  alignItems="center"
  padding={2}
  border={{type: 'round'}}
>
  <Text>Centered content</Text>
</Box>

Static

画面に永続的に残るコンテンツ

<Static items={logs}>
  {log => <Text key={log.id}>{log.message}</Text>}
</Static>

実際のプロジェクト例

CLI進捗表示

import React, {useState, useEffect} from 'react';
import {render, Box, Text} from 'ink';
import Spinner from 'ink-spinner';

const ProgressApp = () => {
  const [progress, setProgress] = useState(0);
  const [isComplete, setIsComplete] = useState(false);

  useEffect(() => {
    const timer = setInterval(() => {
      setProgress(prev => {
        if (prev >= 100) {
          setIsComplete(true);
          clearInterval(timer);
          return 100;
        }
        return prev + 10;
      });
    }, 500);

    return () => clearInterval(timer);
  }, []);

  return (
    <Box flexDirection="column">
      <Box>
        <Text color={isComplete ? 'green' : 'blue'}>
          {isComplete ? '✓' : <Spinner type="dots" />}
        </Text>
        <Text> Processing... {progress}%</Text>
      </Box>
      
      <Box marginTop={1}>
        <Text>
          {'█'.repeat(Math.floor(progress / 5))}
          {'░'.repeat(20 - Math.floor(progress / 5))}
        </Text>
      </Box>
    </Box>
  );
};

render(<ProgressApp />);

エコシステム

関連パッケージ

  • ink-spinner: スピナーコンポーネント
  • ink-select-input: 選択メニュー
  • ink-text-input: テキスト入力
  • ink-table: テーブル表示
  • ink-gradient: グラデーション効果
  • ink-link: クリック可能なリンク

採用事例

  • Cloudflare Wrangler: サーバーレス開発CLI
  • Shopify CLI: Shopify開発ツール
  • Prisma: データベース管理CLI
  • Linear CLI: プロジェクト管理CLI

利点

  • 学習コストの低さ: React開発者なら即座に使用可能
  • 保守性: コンポーネントベースで保守しやすい
  • テスト容易性: 単体テストが書きやすい
  • パフォーマンス: 効率的な差分更新
  • 活発なコミュニティ: 豊富なサードパーティ製コンポーネント

制約事項

  • React依存: Reactのバンドルサイズが含まれる
  • 学習曲線: Reactの知識が必要
  • マウスサポート: 限定的なマウス操作サポート
  • 複雑なレイアウト: 高度なターミナル機能は制限される

他のライブラリとの比較

項目InkBlessedTerminal Kit
アプローチReact風Widget風関数風
学習コスト低(React経験者)
パフォーマンス
エコシステム豊富
TypeScript優秀部分的部分的

まとめ

Inkは、React開発者にとって最も親しみやすいTUIライブラリです。Web開発で培ったReactの知識をそのまま活用でき、保守性の高いターミナルアプリケーションを構築できます。特に、チーム開発やCI/CDツールなど、継続的な保守が必要なCLIツールの開発に適しています。