← Back to Skills Marketplace
openlark

Ink — React for interactive command-line apps.

by OpenLark · GitHub ↗ · v1.0.0 · MIT-0
cross-platform ✓ Security Clean
61
Downloads
0
Stars
0
Active Installs
1
Versions
Install in OpenClaw
/install ink-tui
Description
Ink — React for interactive command-line apps. Build rich terminal UIs with React components.
README (SKILL.md)

Ink Skill Guide

Overview

Ink renders React components directly to the terminal using Yoga layout (Flexbox for CLI). It handles diffing, re-rendering, and terminal I/O. Components receive real React state, effects, and hooks — the same mental model as web React.Requires Node.js 22+ and React 19.2+ as peer dependencies.

Triggers

when the user wants to create CLI/TUI apps, terminal dashboards, interactive prompts, colored terminal output, spinners, progress bars, or tables using JSX/React syntax.

  • building CLI apps with React
  • creating interactive terminal UIs
  • rendering styled terminal output
  • handling keyboard input in the terminal
  • terminal layout with Flexbox/Yoga

Quick Start

mkdir my-cli && cd my-cli
pnpm init
pnpm add ink react @types/react
pnpm add -D tsx typescript @types/node
// tsconfig.json
{
  "compilerOptions": {
    "target": "ES2022",
    "module": "ESNext",
    "moduleResolution": "bundler",
    "jsx": "react-jsx",
    "strict": true,
    "outDir": "build"
  }
}
// index.tsx
import { render, Box, Text } from 'ink';

const App = () => (
  \x3CBox flexDirection="column">
    \x3CText color="green" bold>Hello, CLI!\x3C/Text>
  \x3C/Box>
);

render(\x3CApp />);

Run: node --import=tsx index.tsx

Architecture

Ink uses react-reconciler as its rendering core and yoga-layout as its layout engine. It mounts components into a virtual terminal, diffs against current output, and writes changes to stdout. This means:

  • Full React state/lifecycle (useState, useEffect, etc.)
  • Flexbox layout via Yoga (not CSS — uses integer-based positioning)
  • Terminal output is treated as an append-only buffer that gets replaced on re-render

Components

\x3CBox> — Layout Container

import { Box, Text } from 'ink';

// Row layout (default flexDirection)
\x3CBox gap={2}>
  \x3CText>Left\x3C/Text>
  \x3CText>Right\x3C/Text>
\x3C/Box>

// Column layout with border
\x3CBox flexDirection="column" borderStyle="round" padding={1} width={40}>
  \x3CText bold>Title\x3C/Text>
  \x3CText dim>subtitle\x3C/Text>
\x3C/Box>

Key Box props: width, height, padding/paddingX/paddingY, borderStyle (single/double/round/classic/bold), borderDimColor, gap, flexGrow, flexShrink, flexDirection (row/column), justifyContent, alignItems.

\x3CText> — Styled Text

// Direct styling
\x3CText color="green" bold underline>Success\x3C/Text>

// Nested spans
\x3CText>
  Regular \x3CText bold>bold\x3C/Text> and \x3CText color="red" inverse>inverse red\x3C/Text>
\x3C/Text>

// Wrap via width
\x3CText width={40} wrap="truncate">Truncated long text...\x3C/Text>

Colors: black/red/green/yellow/blue/magenta/cyan/white/gray + Bright variants (redBright, etc.), hex (#ff0000), rgb(255,0,0).
Background: prefix with bg (bgGreen, bgCyanBright).
Styles: bold, dim, italic, underline, strikethrough, inverse.

\x3CNewline>, \x3CSpacer>

\x3CNewline count={2} />       // n blank lines
\x3CSpacer />                   // flex spacer
\x3CSpacer height={3} />        // fixed height spacer

Hooks

useInput — Keyboard Input

import { useInput } from 'ink';

useInput((input, key) => {
  if (key.escape || input === 'q') exit();           // exit on Escape or 'q'
  if (key.upArrow) navigateUp();
  if (key.downArrow) navigateDown();
  if (key.return) selectItem();
});

key object: upArrow, downArrow, leftArrow, rightArrow, return, escape, tab, backspace, delete, ctrl, shift, meta, space, pageUp, pageDown, home, end, f1–f12.

useApp — App-Level Control

import { useApp } from 'ink';
const { exit } = useApp();
exit();  // or exit(error)

useFocus — Focus Management

import { useFocus } from 'ink';
const { isFocused } = useFocus({ autoFocus: true });
// Style differently when focused
\x3CText color={isFocused ? 'blue' : 'dim'}>{label}\x3C/Text>

useStdin / useStdout — Stream Access

const { stdin, isRawModeSupported } = useStdin();
const { stdout } = useStdout();

render() Options

render(\x3CApp />, {
  exitOnCtrlC: true,         // default true
  debug: false,              // show Yoga layout debug
  patchConsole: true,        // suppress console output
});

Common Patterns

Select/Menu

const Menu = ({ items, onSelect }) => {
  const [idx, setIdx] = useState(0);
  useInput((_, key) => {
    if (key.upArrow) setIdx(i => Math.max(0, i - 1));
    if (key.downArrow) setIdx(i => Math.min(items.length - 1, i + 1));
    if (key.return) onSelect(items[idx]);
  });
  return (
    \x3CBox flexDirection="column">
      {items.map((item, i) => (
        \x3CText key={i} color={i === idx ? 'green' : undefined}>
          {i === idx ? '❯ ' : '  '}{item}
        \x3C/Text>
      ))}
    \x3C/Box>
  );
};

Spinner (useEffect + setInterval)

const Spinner = () => {
  const [frame, setFrame] = useState(0);
  const chars = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
  useEffect(() => {
    const id = setInterval(() => setFrame(f => (f + 1) % chars.length), 80);
    return () => clearInterval(id);
  }, []);
  return \x3CText>{chars[frame]} Loading...\x3C/Text>;
};

Progress Bar

const ProgressBar = ({ percent }) => {
  const filled = '█'.repeat(Math.round(percent / 5));
  const empty = '░'.repeat(20 - filled.length);
  return \x3CText>{filled}{empty} {percent}%\x3C/Text>;
};

Input Field (useInput + useState)

const Input = ({ onSubmit }) => {
  const [value, setValue] = useState('');
  useInput((input, key) => {
    if (key.return) { onSubmit(value); setValue(''); }
    else if (key.backspace) setValue(v => v.slice(0, -1));
    else if (input.length === 1 && !key.ctrl) setValue(v => v + input);
  });
  return \x3CText>❯ {value}\x3CText dim>█\x3C/Text>\x3C/Text>;
};

Resources

This skill includes:

  • components.md — Full component and prop reference
  • hooks.md — Hook API details and custom hook patterns
  • examples.md — Complete runnable examples (counter, table, loading, CLI arguments)

Key Constraints

  • Node.js >= 22 required (ESM only)
  • React >= 19.2 is a peer dependency
  • Only works in real terminal (no browser)
  • Layout via Yoga Flexbox — units are characters/rows, not pixels
  • No scrolling — the terminal viewport is the canvas
  • Colors depend on terminal support (most modern terminals support 256-color)
  • Interactive mode requires raw stdin (Ink enables it automatically)
Usage Guidance
This result is low confidence because the requested files could not be inspected. Re-run the scan in an environment where metadata.json and the artifact directory are readable before relying on this review.
Capability Analysis
Type: OpenClaw Skill Name: ink-tui Version: 1.0.0 The ink-tui skill bundle is a legitimate documentation and reference guide for the Ink library, which allows building terminal UIs using React. It contains standard API references for components (SKILL.md, components.md), hooks (hooks.md), and several practical code examples (examples.md) for common CLI patterns like menus, progress bars, and tables. There are no indicators of malicious intent, data exfiltration, or prompt injection.
Capability Assessment
Purpose & Capability
metadata.json and artifact files were requested for review, but local command execution failed before any files could be listed or read.
Instruction Scope
No SKILL.md or artifact instructions were accessible, so instruction scope could not be assessed from evidence.
Install Mechanism
No install specs or manifest contents were accessible; no install risk is supported by artifact evidence.
Credentials
No runtime, environment, or capability declarations were accessible for proportionality review.
Persistence & Privilege
No artifact-backed evidence of persistence, privilege use, credentials, or sensitive data handling was available.
How to Use
  1. Make sure OpenClaw is installed (local or Docker)
  2. Run the install command in chat: /install ink-tui
  3. After installation, invoke the skill by name or use /ink-tui
  4. Provide required inputs per the skill's parameter spec and get structured output
Version History
v1.0.0
Initial release of ink-tui: React-based toolkit for terminal UIs. - Provides React components (`Box`, `Text`, `Newline`, `Spacer`) for building interactive terminal apps with Flexbox/Yoga layout. - Supports keyboard input, focus, and app control via hooks (`useInput`, `useApp`, `useFocus`, `useStdin`, `useStdout`). - Includes examples for menus, spinners, progress bars, and input fields. - Requires Node.js 22+ (ESM-only) and React 19.2+ as peer dependencies. - Documents key constraints: terminal-only, Yoga-based layout, color/style support per terminal. - Bundles detailed references for components, hooks, and runnable examples.
Metadata
Slug ink-tui
Version 1.0.0
License MIT-0
All-time Installs 0
Active Installs 0
Total Versions 1
Frequently Asked Questions

What is Ink — React for interactive command-line apps.?

Ink — React for interactive command-line apps. Build rich terminal UIs with React components. It is an AI Agent Skill for Claude Code / OpenClaw, with 61 downloads so far.

How do I install Ink — React for interactive command-line apps.?

Run "/install ink-tui" in the OpenClaw or Claude Code chat to install it in one step — no extra setup required.

Is Ink — React for interactive command-line apps. free?

Yes, Ink — React for interactive command-line apps. is completely free, licensed under MIT-0. You can download, install and use it at no cost.

Which platforms does Ink — React for interactive command-line apps. support?

Ink — React for interactive command-line apps. is cross-platform and runs anywhere OpenClaw / Claude Code is available (cross-platform).

Who created Ink — React for interactive command-line apps.?

It is built and maintained by OpenLark (@openlark); the current version is v1.0.0.

💬 Comments