Terminal Components
API reference for InkTerminalBox and InkXterm components
ink-web provides two main components for rendering Ink applications in the browser: InkTerminalBox and InkXterm. These components handle the xterm.js integration and provide a terminal-like environment for your Ink components.
InkTerminalBox
A higher-level component that wraps InkXterm with styling, CSS isolation, and loading state support. This is the recommended component for most use cases.
import { InkTerminalBox, Box, Text } from "ink-web";
import "ink-web/css";
import "xterm/css/xterm.css";
export function MyTerminal() {
return (
<InkTerminalBox rows={10} focus>
<Box flexDirection="column">
<Text color="green">Hello from Ink!</Text>
</Box>
</InkTerminalBox>
);
}Props
| Prop | Type | Default | Description |
|---|---|---|---|
children | React.ReactElement | Required | The Ink component tree to render |
className | string | "" | Additional CSS class for the container |
focus | boolean | true | Whether to focus the terminal on mount |
termOptions | ITerminalOptions | {} | xterm.js terminal options |
rows | number | undefined | Number of rows to display. Sets a fixed height. |
onReady | () => void | undefined | Callback fired when terminal is fully initialized |
loading | React.ReactNode | undefined | Loading indicator shown while terminal initializes |
Features
- CSS Isolation: Resets inherited styles to prevent parent CSS from affecting terminal rendering
- Loading States: Show a custom loading indicator while xterm.js initializes
- Fixed Height: Use
rowsprop to set consistent height across SSR and client - Automatic Sizing: Automatically fits to container and handles resize events
Example with Loading State
import { InkTerminalBox, Box, Text } from "ink-web";
import { Loader2 } from "lucide-react";
export function MyTerminal() {
return (
<InkTerminalBox
rows={15}
focus
loading={<Loader2 className="h-6 w-6 animate-spin text-gray-400" />}
onReady={() => console.log("Terminal ready!")}
>
<Box flexDirection="column">
<Text>Terminal content</Text>
</Box>
</InkTerminalBox>
);
}InkXterm
A lower-level component that directly integrates xterm.js with Ink. Use this when you need more control or don't want the additional styling from InkTerminalBox.
import { InkXterm, Box, Text } from "ink-web";
import "xterm/css/xterm.css";
export function MyTerminal() {
return (
<InkXterm focus>
<Box flexDirection="column">
<Text>Hello World</Text>
</Box>
</InkXterm>
);
}Props
| Prop | Type | Default | Description |
|---|---|---|---|
children | React.ReactElement | Required | The Ink component tree to render |
className | string | "" | CSS class for the container div |
focus | boolean | true | Whether to focus the terminal on mount |
termOptions | ITerminalOptions | {} | xterm.js terminal options |
onReady | () => void | undefined | Callback fired when terminal is fully initialized |
Initialization Behavior
InkXterm uses a robust initialization strategy:
- requestAnimationFrame: Waits for the browser's next paint cycle to ensure the DOM is ready
- Dimension Check: Verifies the container has non-zero dimensions
- ResizeObserver: If dimensions aren't ready, observes for when they become available
This approach ensures reliable initialization without arbitrary timeouts.
mountInkInXterm
For advanced use cases, you can use the mountInkInXterm function directly to create your own terminal integration.
import { mountInkInXterm, Box, Text } from "ink-web";
const container = document.getElementById("terminal");
const { term, unmount } = mountInkInXterm(
<Box>
<Text>Hello</Text>
</Box>,
{
container,
focus: true,
termOptions: { fontSize: 14 },
onReady: () => console.log("Ready!"),
}
);
// Later, to cleanup:
await unmount();Options
| Option | Type | Description |
|---|---|---|
container | HTMLElement | DOM element to mount the terminal in |
focus | boolean | Whether to focus the terminal |
termOptions | ITerminalOptions | xterm.js terminal options |
onReady | () => void | Callback when terminal is ready |
Return Value
| Property | Type | Description |
|---|---|---|
term | Terminal | The xterm.js Terminal instance |
unmount | () => Promise<void> | Cleanup function |
Terminal Options
Both components accept termOptions which are passed to xterm.js. Common options include:
<InkTerminalBox
termOptions={{
fontSize: 14,
fontFamily: "Menlo, Monaco, 'Courier New', monospace",
cursorBlink: true,
theme: {
background: "#1a1a1a",
foreground: "#ffffff",
},
}}
>
{/* ... */}
</InkTerminalBox>See the xterm.js documentation for all available options.
Choosing Between Components
| Use Case | Recommended Component |
|---|---|
| Standard terminal UI | InkTerminalBox |
| Need loading states | InkTerminalBox |
| SSR/Next.js apps | InkTerminalBox |
| Custom styling/no CSS reset | InkXterm |
| Advanced/custom integration | mountInkInXterm |