# termcn: shadcn-style terminal UI components built on Ink and OpenTUI

> termcn is a collection of React components for building terminal user interfaces, distributed through the shadcn registry format and CLI so the source lands in your repository rather than in a node_modules dependency. It targets both Ink and OpenTUI renderers, and it covers everything from charts to agent chat interfaces.

**shadcn-labs/termcn** — Beautiful terminal UI components, built on Ink and OpenTUI. 100% Free, Zero config, one command setup.

- Repository: https://github.com/shadcn-labs/termcn
- Website: https://termcn.dev
- Stars: 1,224 · Forks: 50
- Language: TypeScript
- License: MIT
- Published: 2026-10-19 · Updated: 2026-10-19 · Language: en
- Canonical page: https://hysenlabs.com/projects/shadcn-labs-termcn

## The shadcn model, applied to a terminal

termcn is described as free and open-source, ready-to-use, customizable terminal UI components for React. Zero config. One command setup. Built on Ink and OpenTUI, and it works seamlessly with shadcn/ui.

The shadcn connection is the key to understanding the whole project, and it is more than a visual influence. The features list says it plainly: shadcn/ui compatible, it uses the same registry format and CLI. So termcn is not distributed as a package you depend on. It is distributed through the same mechanism shadcn uses, which means the component source is copied into your repository and becomes yours.

That model has a well-known rationale and it applies here with unusual force. A component library that you depend on is one you cannot modify; a component library whose source is in your tree is one you own, restyle, and adapt to whatever your terminal needs. For web components that reasoning is about theming and about the design system agreeing with your brand. For terminal components there is an extra constraint, because the terminal is a hostile rendering environment: a fixed cell grid, limited or non-existent colour support, no font metrics, and a width that changes when the user resizes. A component that has to survive all of that is much more likely to need adjusting, and much more likely to need to be read.

The primary language is TypeScript, the licence is MIT, and the homepage is termcn.dev with documentation at termcn.dev/docs. The repository is not archived and the last push was on 2026-10-07. There are no GitHub releases, which is consistent with the registry model, since there is no npm package to version.

The audience is a developer building a command line tool with a real interface, who has discovered that Ink gives you React but no components, and who would rather not design a text input, a table and a spinner from scratch.

## Ink and OpenTUI, and why both

The rendering foundation is Ink, the React renderer for the terminal by the same author who made React, together with OpenTUI from anomalyco, and the features list calls it full access to powerful terminal rendering.

The two are not interchangeable, and that is the point. Ink is the long-established React renderer for the terminal, built on top of Yoga for layout, and it works by re-rendering the React tree to a string and writing it out. OpenTUI is a different and more capable rendering layer, one that is not built around the idea that a terminal program is a sequence of screen writes.

Building a component set that works on both is the harder problem, and it explains a constraint that shows up in the feature list. Ink and OpenTUI are not pixel or cell identical, so a component that relies on a specific layout behaviour may not render identically on the two. The shadcn compatibility claim is about the component API and the registry mechanism rather than about the two renderers being interchangeable behind it, and a team that picks termcn for a terminal app has to pick a renderer and verify the components they use on it.

The theme-aware feature is the other interesting one. It says the components automatically adapt to your chosen terminal theme, which in practice means detecting the terminal's background brightness and picking a palette accordingly, so a light-themed terminal does not get white-on-white text. That is the kind of detail that separates a component set from a set of components, because the terminal's own theme is something the program usually has to guess about.

The composability claim sits alongside. Build complex terminal UIs with simple, declarative components. That is the React model applied to the terminal, and it is what makes the difference between a CLI that prints lines and a program with panels, tabs and a live-updating region.

## What is in the set, and the AI components in particular

The features list covers three groups, and the third is the one that is unusual for a component library.

The first is data display: bar charts, line charts, gauges, heat maps, and more. A chart in a terminal is a genuinely difficult thing, because you have a cell grid and a character set, and a bar chart has to be drawn with block characters, a line chart with box-drawing runes, and a heat map with colour ramps that degrade to nothing on a monochrome terminal. Shipping these as components means someone else solved the alignment arithmetic, which is the part that is tedious and the part that is done once.

The second is navigation: command palettes, tabs, menus, sidebars and pagination. A command palette in particular is not a trivial thing in a terminal, since it needs a fuzzy filter, a live text input, a scrolling result list and a selected-item indicator, and Ink does not give you any of that.

The third is AI components: chat messages, tool approvals, streaming text, and thinking blocks. This is the group that says something about where the project sees terminal applications going. A tool-approval component is a dialog with a decision attached, in a terminal, for an agent that wants to run a command. Streaming text is text that arrives in fragments and has to be re-rendered without flicker. A thinking block is a collapsible region for model reasoning output. These are components for AI coding assistants and agent runtimes, and they are the reason the term AI Components is a separate bullet rather than a passing mention.

The rest of the feature list is the standard set: zero config, works out of the box with sensible defaults, theme-aware, Ink and OpenTUI powered, composable.

So the scope is a design system for terminal applications, with an unusual emphasis on the interactive parts that agent tooling needs.

## The registry CLI, and what ends up in your repository

The setup is described as one command, and the documentation site has an installation page at termcn.dev/docs/installation, which is where the project points for the actual command. The README does not spell out the command itself, so the honest path is to follow the documentation link rather than to guess at a CLI invocation.

What the shadcn model means in practice is worth spelling out, because it changes how you maintain the project. When you add a component, the CLI fetches its source and writes it into a directory in your repository. From that point the component is your code. You can edit it, and if the upstream version gains a fix, there is no automatic way to get it: you re-run the add command and it will ask about overwriting, or you diff it yourself. A project with thirty termcn components is a project with thirty files to reconcile on upgrade.

That is the deal shadcn users accept, and the reason they accept it is that the alternative is a dependency whose internals they cannot change. The registry format is a convention for distributing source rather than a package, and the CLI is the tool that writes it. The same registry format and CLI as shadcn/ui is the practical benefit for a team already running one, since the workflow, the file layout and the mental model are already familiar.

The repository layout reflects a workspace project with several apps and packages: apps/ and packages/ under pnpm workspaces, a turbo.json for task running, a pnpm-workspace.yaml and a pnpm-lock.yaml, and a root package.json that is marked private. The scripts are all turbo calls filtered to the web app, dev, build, start, typecheck, examples:build and registry:build, plus a check and fix pair that run ultracite, which is the linting and formatting wrapper that sits on top of oxlint and oxfmt, and a prepare script that installs lefthook, the git hook runner.

The engines field requires node >=20.9.0 and pnpm >=10.0.0, and the packageManager field pins pnpm@10.28.2. There is a .nvmrc for the Node version, a vercel.json for the documentation site deployment, and a skills-lock.json alongside a .agents/ directory, a .claude/ directory and a .cursor/ directory, which is the usual set of files for a project that ships agent skills and editor integrations.

## Where termcn is the wrong tool

There are three limits, and the first is about the renderer rather than the components.

The first is that a terminal component library is only as good as the terminal it targets, and terminals are not a uniform target. There are the ones that support true colour and the ones that do not, the ones with a Unicode box-drawing font and the ones that render it as ASCII, the ones that support hyperlinks and the ones that do not, and the ones that handle wide characters correctly and the ones that do not, which is the classic source of misaligned tables in a CJK locale. A component set can handle this by degrading, and a well-built one will, but the degradation is a decision the component makes on your behalf, and for a table of financial figures in a terminal without colour support, the fallback is not always what you want.

The second is the ownership cost of the registry model, which I mentioned above and which deserves to be stated as a limitation rather than a feature. The components are yours once added, and there is no upgrade path for them other than manual. A team that wants to track upstream improvements to a chart component is doing a diff and a merge by hand, and a team that adds many components accumulates that work. This is a fine trade for a design system you intend to fork deliberately, and a poor one for a team that wants to consume and update.

The third is scope. The feature list is a component inventory, and it does not include the things a terminal application needs that are not components: a proper screen buffer or scrollback handling, a resize-aware layout, keyboard escape sequence parsing for the keys your terminal sends, a way to suspend and resume the program, a shell integration, or a job output pager. Ink gives you a React renderer and a layout engine, and termcn gives you the visual vocabulary, and neither of those is the same as a complete terminal application framework.

And there is a fourth point that belongs to any terminal UI: accessibility and non-visual use. A component set built around colour and spatial arrangement is not going to be usable by a screen reader, and it is not going to work in a pipeline that captures output for a log file, where the ANSI escapes become noise. A CLI whose output is consumed by a script rather than a person wants plain text, and a component library is the wrong abstraction for that case.

## Conclusion

Adopt termcn if you are building a terminal application in React with Ink and want a component set that looks designed rather than assembled from escape sequences, and you are comfortable owning the component source in your repository. Do not adopt it if you want a dependency you can install and update from npm without thinking about it, because the registry model means the code becomes yours to maintain. Verify first which renderer you are on, Ink or OpenTUI, since the components target both, and that the registry CLI version you use matches the format your project has already committed to.

## FAQ

### What is termcn and what does it provide?

termcn is a collection of free and open-source terminal UI components for React, built on Ink and OpenTUI, covering charts and data display, navigation such as command palettes, tabs, menus and sidebars, and AI components including chat messages, tool approvals, streaming text and thinking blocks.

### How is termcn related to shadcn/ui?

It uses the same registry format and CLI as shadcn/ui, which means the component source is copied into your repository rather than installed as a dependency, and it works alongside shadcn/ui. The README describes the setup as zero config with a one command setup, and the installation page is at termcn.dev/docs/installation.

### Which terminal renderers do the termcn components support?

Both Ink and OpenTUI, and the features list describes it as Ink and OpenTUI powered with full access to powerful terminal rendering. The two are not identical renderers, so components should be verified against the one your application uses.

### What licence is termcn released under?

MIT, with a LICENSE file at the root of the repository and the README linking to it. The project also asks that security vulnerabilities not be reported in public issues, and be reported privately through GitHub Security Advisories as described in SECURITY.md.

## Sources

- [Issues](https://github.com/shadcn-labs/termcn/issues)
- [License: MIT](https://github.com/shadcn-labs/termcn/blob/main/LICENSE)
- [Project website](https://termcn.dev)
- [README](https://github.com/shadcn-labs/termcn/blob/main/README.md)
- [shadcn-labs/termcn on GitHub](https://github.com/shadcn-labs/termcn)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/shadcn-labs-termcn
