@sarthak_krishak/inkforge
v0.4.3
Published
Beautiful terminal UI components for React/Ink — shadcn/ui for your terminal
Maintainers
Readme
InkForge
Beautiful terminal UI components for React/Ink — scaffolded in one command, owned forever.
shadcn/ui for your terminal. Built for the AI coding agent era.
What is InkForge?
InkForge gives you polished, production-ready terminal components — spinners, progress bars, and more — that you actually own. Instead of a locked npm dependency buried in node_modules, InkForge copies the source code directly into your project. Read it. Edit it. Make it yours.
Quick Start
Step 1 — Create a new empty folder and open a terminal inside it
mkdir my-cli-app
cd my-cli-appStep 2 — Scaffold the project
npx @sarthak_krishak/inkforge initThis creates everything your project needs:
| Created | Description |
|---|---|
| package.json | Configured with type: module, start script, and all dependencies listed |
| vite.config.js | Vite + React plugin config |
| app.jsx | Starter app — edit this to build your CLI |
Step 3 — Install dependencies
npm installStep 4 — Add the components you want
npx inkforge add spinner
npx inkforge add progressbarThis copies the component source files directly into your project. You own them now.
Step 5 — Open app.jsx, import your components, and run
import { Spinner } from './components/inkforge/Spinner/index.jsx';
import { ProgressBar } from './components/inkforge/ProgressBar/index.jsx';npm startFull example app.jsx
import React, { useState, useEffect } from 'react';
import { render, Box, Text } from 'ink';
import { Spinner } from './components/inkforge/Spinner/index.jsx';
import { ProgressBar } from './components/inkforge/ProgressBar/index.jsx';
function App() {
const [progress, setProgress] = useState(0);
const [done, setDone] = useState(false);
useEffect(() => {
const t = setInterval(() => {
setProgress(p => {
if (p >= 100) { clearInterval(t); setDone(true); return 100; }
return p + 5;
});
}, 150);
return () => clearInterval(t);
}, []);
return (
<Box flexDirection="column" padding={1} gap={1}>
<Text bold color="cyan">My CLI App</Text>
<Spinner label="Building..." done={done} doneText="✓ Build complete!" />
<Spinner label="Installing..." done={done} doneText="✓ Packages ready!" variant="bounce" theme="cyberpunk" />
<ProgressBar value={progress} label="Progress " />
<ProgressBar value={progress} label="Memory " variant="block" color="#E5C07B" />
</Box>
);
}
render(<App />);Project structure after setup
my-cli-app/
│ └── components/
│ └── inkforge/
│ ├── Spinner/
│ │ └── index.jsx ← edit freely
│ ├── ProgressBar/
│ │ └── index.jsx ← edit freely
│ └── core/
│ └── colors.js ← theme colors
├── app.jsx ← your app starts here
├── vite.config.js
└── package.jsonComponents
Spinner
Animated loading indicator with 5 variants and a done state.
<Spinner variant="dots" label="Fetching data..." />
<Spinner variant="bounce" label="Processing request..." theme="cyberpunk" />
<Spinner variant="arc" label="Compiling..." />
<Spinner variant="line" label="Connecting..." />
<Spinner variant="simple" label="Waiting..." />
// Switches to a completion message when done={true}
<Spinner label="Deploying..." done={isDone} doneText="✓ Deployed!" />Spinner Props
| Prop | Type | Default | Description |
|---|---|---|---|
| variant | string | 'dots' | Animation style: dots line bounce arc simple |
| label | string | 'Loading...' | Text shown next to the spinner |
| color | string | theme primary | Spinner color (any hex value) |
| theme | string | 'default' | Color theme: 'default' or 'cyberpunk' |
| interval | number | 120 | Animation speed in milliseconds |
| done | boolean | false | When true, switches to done state |
| doneText | string | '✓ Done' | Message shown when done is true |
ProgressBar
Fillable progress bar with 3 visual styles.
<ProgressBar value={75} label="Build" />
<ProgressBar value={45} total={200} label="Files" showValue />
<ProgressBar value={progress} variant="thin" label="Upload" />
<ProgressBar value={progress} variant="block" label="Memory" />
<ProgressBar value={progress} color="#E5C07B" label="CPU" />
<ProgressBar value={progress} theme="cyberpunk" label="Hack" />ProgressBar Props
| Prop | Type | Default | Description |
|---|---|---|---|
| value | number | 0 | Current progress value |
| total | number | 100 | Maximum value |
| width | number | 30 | Bar width in characters |
| label | string | '' | Label shown before the bar |
| showPercent | boolean | true | Show percentage on the right |
| showValue | boolean | false | Show value/total instead of percentage |
| color | string | theme success | Fill color (any hex value) |
| bgColor | string | theme muted | Empty bar color (any hex value) |
| theme | string | 'default' | Color theme: 'default' or 'cyberpunk' |
| variant | string | 'default' | Bar style: 'default' 'thin' 'block' |
Themes
| Theme | Accent | Best for |
|---|---|---|
| default | Blue / green | Production tools, professional CLIs |
| cyberpunk | Neon cyan / bright green | Dev tools, personal projects, AI agents |
CLI Reference
# Scaffold a new project in an empty folder (run once)
npx @sarthak_krishak/inkforge init
# Add components to your project
npx inkforge add spinner
npx inkforge add progressbar
npx inkforge add spinner progressbar
# Interactive component picker (arrow keys + space)
npx inkforge add
# See all available components
npx inkforge listWhy own your components?
With a standard npm package, the code is locked inside node_modules. You can't change it without forking the entire repo.
With InkForge, after npx inkforge add spinner, the file is at components/inkforge/Spinner/index.jsx — inside your project. Change the animation frames. Add a new variant. Tweak the colors. No fork needed. No PR required. It's your code.
This is the same philosophy that made shadcn/ui the most popular component library for web React. InkForge brings it to the terminal.
Roadmap
- [x] Spinner — 5 variants, done state, theme support
- [x] ProgressBar — 3 variants, custom colors, theme support
- [x] CLI —
init,add,listcommands - [ ] DiffViewer — git-style diff display for AI coding agents
- [ ] StreamingOutput — token-by-token AI response display
- [ ] PromptInput — input with history and autocomplete
- [ ] Select / MultiSelect — keyboard-navigable menus
- [ ] Table — structured data display
- [ ] StatusBar — footer with agent state
License
MIT © Sarthak Krishak
