This skill should be used when building command-line interfaces with React, creating terminal UIs with Ink, developing interactive CLI applications, or working with terminal-based React components
Build interactive command-line applications using React components with Ink.
Ink is a React renderer for terminals, allowing you to build CLI applications using familiar React patterns including components, hooks, JSX, and Flexbox layouts. It leverages Yoga (Facebook's Flexbox layout engine) to create responsive terminal UIs.
Use Ink when building:
npm install ink react
For TypeScript:
npm install --save-dev @types/react
import React from 'react';
import {render, Text} from 'ink';
const App = () => <Text color="green">Hello World</Text>;
render(<App />);
my-cli/
├── source/
│ ├── cli.tsx # Entry point
│ └── app.tsx # Main component
├── dist/ # Compiled output
├── package.json
└── tsconfig.json
Ink provides React components that render to terminal output:
See components.md for detailed documentation.
Ink extends React with terminal-specific hooks:
See hooks.md for detailed documentation.
Ink uses Flexbox via Yoga:
flexDirection, justifyContent, alignItemsSee layouts.md for common patterns.
#!/usr/bin/env node
import React from 'react';
import {render} from 'ink';
import App from './app.js';
render(<App />);
import React from 'react';
import {Text} from 'ink';
export default function App() {
return <Text>Hello from Ink!</Text>;
}
TypeScript (tsconfig.json):
{
"compilerOptions": {
"module": "Node16",
"target": "ES2022",
"lib": ["ES2022"],
"moduleResolution": "Node16",
"esModuleInterop": true,
"strict": true,
"outDir": "dist",
"jsx": "react-jsx"
}
}
package.json:
{
"type": "module",
"bin": "dist/cli.js",
"scripts": {
"build": "tsc",
"dev": "tsc --watch",
"start": "node dist/cli.js"
}
}
Ink applications can be tested using ink-testing-library:
npm install --save-dev ink-testing-library
See testing.md for testing patterns and examples.
See patterns.md for implementation examples.
useEffect cleanup for timers and intervalsexit() from useApp() when doneNothing renders: Ensure you're calling render() at the end of your script
Input not working: Make sure you're using useInput hook inside a component rendered by Ink
Layout issues: Remember every element is a Flexbox container by default
TypeScript errors: Ensure you're using "jsx": "react-jsx" in tsconfig.json