{"id":13334,"library":"ink","title":"Ink: React for Command-Line Interfaces","description":"Ink is a JavaScript library that brings the declarative, component-based UI development experience of React to command-line applications. It allows developers to build complex, interactive terminal UIs using React components, leveraging features like state management, hooks, and a virtual DOM. Ink utilizes Yoga for Flexbox layout in the terminal, enabling most CSS-like layout properties. The current stable version is 7.0.1, with an active release cadence that often aligns with major React and Node.js LTS updates. Key differentiators include full React feature support within a CLI context, robust layout capabilities, and a thriving ecosystem of libraries and applications built on Ink, making it a powerful choice for modern CLI development.","status":"active","version":"7.0.1","language":"javascript","source_language":"en","source_url":"https://github.com/vadimdemedes/ink","tags":["javascript","react","cli","jsx","stdout","components","command-line","preact","redux"],"install":[{"cmd":"npm install ink","lang":"bash","label":"npm"},{"cmd":"yarn add ink","lang":"bash","label":"yarn"},{"cmd":"pnpm add ink","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Required as Ink is a React renderer.","package":"react","optional":false},{"reason":"TypeScript type definitions for React, required for TypeScript projects.","package":"@types/react","optional":true},{"reason":"Enables React DevTools integration for debugging Ink applications.","package":"react-devtools-core","optional":true}],"imports":[{"note":"Ink v7 is primarily ESM. CommonJS `require` is generally not recommended for new projects and might not work for all exports due to 'type': 'module' in `package.json`.","wrong":"const { render } = require('ink')","symbol":"render","correct":"import { render } from 'ink'"},{"note":"`Text` is a named export, not a default export. Used for basic text rendering with styling capabilities.","wrong":"import Text from 'ink'","symbol":"Text","correct":"import { Text } from 'ink'"},{"note":"`useInput` is a named export hook for handling keyboard input. Hook names must start with `use` and be lowercase after that.","wrong":"import { UseInput } from 'ink'","symbol":"useInput","correct":"import { useInput } from 'ink'"},{"note":"`useApp` is a named export hook providing access to Ink's app instance methods like `exit()`.","wrong":"import { UseApp } from 'ink'","symbol":"useApp","correct":"import { useApp } from 'ink'"}],"quickstart":{"code":"import React, { useState, useEffect } from 'react';\nimport { render, Text } from 'ink';\n\nconst Counter = () => {\n  const [counter, setCounter] = useState(0);\n\n  useEffect(() => {\n    const timer = setInterval(() => {\n      setCounter(previousCounter => previousCounter + 1);\n    }, 100);\n\n    return () => {\n      clearInterval(timer);\n    };\n  }, []);\n\n  return <Text color=\"green\">{counter} tests passed</Text>;\n};\n\nrender(<Counter />);","lang":"typescript","description":"This example demonstrates a simple counter component using React state and effects, rendered in the terminal via Ink, updating every 100 milliseconds."},"warnings":[{"fix":"Upgrade your Node.js environment to version 22 or later. Consider using a Node.js version manager like `nvm` or `volta`.","message":"Ink v7.0.0 requires Node.js version 22 or higher. Applications running on older Node.js versions will fail to start.","severity":"breaking","affected_versions":">=7.0.0"},{"fix":"Update your `react` and `@types/react` peer dependencies to `^19.2.0` and reinstall dependencies.","message":"Ink v7.0.0 requires React version 19.2.0 or higher. This update leverages `useEffectEvent` internally for improved input handler management, making older React versions incompatible.","severity":"breaking","affected_versions":">=7.0.0"},{"fix":"If your `useInput` handler was checking `key.delete` to detect backspace, switch to checking `key.backspace` instead. Review and update any relevant input handling logic.","message":"In Ink v7.0.0, pressing the Backspace key now correctly sets `key.backspace` to `true` instead of `key.delete`. Most terminals send the same byte for both, which previously caused misreporting.","severity":"breaking","affected_versions":">=7.0.0"},{"fix":"For testing, use `renderToString()` for snapshot testing, or mock `stdout` and `stdin` as needed. The `ink-testing-library` package can also assist with testing components.","message":"Ink relies on `process.stdout` and `process.stdin` for rendering and input. When running tests, ensure you mock or properly handle these streams, or use `renderToString()` for synchronous string output to capture rendered content.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Enable `synchronizedUpdate: true` in `render` options and `incrementalRendering: true` to mitigate flickering. Optimize component re-renders and consider `maxFps` to cap update rates for less critical animations.","message":"Ink components can flicker, especially with rapid updates or complex layouts, due to terminal rendering limitations. While `synchronizedUpdate` (v6.7.0+) and `incrementalRendering` (v6.5.0+) options help, heavy animations might still be challenging.","severity":"gotcha","affected_versions":">=6.5.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Update Node.js to version 22 or higher. You can use `nvm install 22 && nvm use 22`.","cause":"Attempting to run an Ink v7+ application on an incompatible Node.js version.","error":"Error: Ink requires Node.js version >=22.0.0"},{"fix":"Verify that all Ink components (`Text`, `Box`, etc.) are correctly imported as named exports, e.g., `import { Text } from 'ink';`","cause":"Typically indicates that a React component from Ink (e.g., `Text`) was imported incorrectly or not imported at all, resulting in `undefined` being used where a component is expected.","error":"Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined."},{"fix":"Ensure `exit` is correctly destructured from `useApp()` within a functional component: `const { exit } = useApp();`","cause":"Attempting to call `app.exit()` without properly destructuring `exit` from the `useApp()` hook, or calling it outside of a component context.","error":"TypeError: Cannot read properties of undefined (reading 'exit')"}],"ecosystem":"npm","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":null,"cli_name":"","cli_version":null}