terminal-table-printer
v0.2.0
Published
A TypeScript library for rendering JSON or Apache Arrow data into styled, responsive tables for terminal applications.
Readme
Terminal Table Printer
A TypeScript library for rendering JSON or Apache Arrow data into styled, responsive tables for terminal applications.
Features
- Data Sources: Renders data from
JSONObject[]or Apache ArrowTableobjects. - Styling: Customize colors (hex codes supported), background colors, and text styles (
bold,italic,underline). - Responsive Layout: Columns can intelligently grow and shrink to fit the terminal width using flexbox-like controls (
minWidth,maxWidth,flexGrow). - Dynamic Formatting: Apply styles to rows or cells conditionally based on their data.
- Layout Control: Supports text alignment, per-column padding, and automatic content truncation.
- Customizable: Full control over border characters and themes.
Installation
npm install terminal-table-printerExamples
npm run example
npm run matrix
Kapture 2025-09-07 at 16.47.02.webm
Quick Start
import { TableFormatter, JSONDataSource } from 'terminal-table-printer';
const data = [
{ id: 1001, product: 'Supernova Gizmo', price: 1299.99, stock: 15 },
{ id: 1002, product: 'Quantum Widget', price: 74.50, stock: 122 },
];
// 1. Create a data source
const dataSource = new JSONDataSource(data);
// 2. Configure the table
const config = {
columns: {
price: {
header: 'Price',
alignment: 'right',
formatter: (val) => `$${Number(val).toFixed(2)}`,
style: { color: 'green' },
},
stock: {
alignment: 'right',
},
},
};
// 3. Create and render the table
const table = new TableFormatter(dataSource, config);
console.log(table.render());Output:
┌──────┬─────────────────┬──────────┬───────┐
│ id │ product │ Price │ stock │
├──────┼─────────────────┼──────────┼───────┤
│ 1001 │ Supernova Gizmo │ $1299.99 │ 15 │
│ 1002 │ Quantum Widget │ $74.50 │ 122 │
└──────┴─────────────────┴──────────┴───────┘Data Sources
The library accepts two types of data sources.
JSONDataSource
Accepts an array of plain JavaScript objects (JSONObject[]). The keys from the first object are used as column identifiers.
import { JSONDataSource } from 'terminal-table-printer';
const dataSource = new JSONDataSource([
{ name: 'Alice', role: 'Admin' },
{ name: 'Bob', role: 'User' },
]);ArrowDataSource
Accepts an apache-arrow Table object.
import { ArrowDataSource } from 'terminal-table-printer';
import { tableFromArrays } from 'apache-arrow';
const arrowTable = tableFromArrays({
name: ['Alice', 'Bob'],
role: ['Admin', 'User'],
});
const dataSource = new ArrowDataSource(arrowTable);```
## Configuration
The `TableFormatter` constructor accepts a `TableConfig` object to customize the output.
### Theming and Alternating Rows
Use the `theme` object for global styling and `alternatingRows` for readability. Colors can be standard `chalk` names or hex codes (e.g., `'#ff0000'`).
```typescript
const config = {
alternatingRows: true,
theme: {
header: { color: '#268bd2', bold: true },
cell: { color: '#839496' },
alternatingCell: { backgroundColor: '#073642' },
footer: { color: '#586e75', italic: true },
},
};Column Configuration
The columns property allows you to configure each column by its key from the data source.
const config = {
columns: {
// The key 'id' must match a key in your data
id: {
header: 'Product ID', // Rename the column header
alignment: 'center', // 'left', 'right', or 'center'
padding: { left: 2, right: 2 }, // Override global padding
headerStyle: { color: 'yellow' },// Style only the header of this column
},
price: {
// Format the cell value. Receives the value and its rowIndex.
formatter: (value, rowIndex) => `$${Number(value).toFixed(2)}`,
style: { color: 'green' }, // Style all data cells in this column
},
},
};Responsive Layout (Flexible Columns)
To make tables automatically adapt to the terminal's width, you can use minWidth, maxWidth, and flexGrow on a per-column basis. The table will fill the available width (or the global maxWidth if set) and distribute space intelligently.
minWidth: The minimum content width this column can shrink to.maxWidth: The maximum content width this column can grow to.flexGrow: A ratio that dictates how much of the remaining space this column should claim.
const config = {
// No global maxWidth is set, so the table will try to use the full terminal width
columns: {
id: {
minWidth: 5, // Won't shrink below 5 characters
},
name: {
header: 'Product Name',
flexGrow: 1, // Will expand to take up all available extra space
minWidth: 20, // But will truncate if the terminal is too narrow
},
status: {
flexGrow: 1, // Also expands, sharing space with 'name'
maxWidth: 15, // But will never grow wider than 15 characters
},
price: {
alignment: 'right',
minWidth: 10, // Resists shrinking
}
}
};When run in a wide terminal, the name and status columns will expand to fill the space. In a narrow terminal, all columns will shrink until they hit their minWidth, at which point their content will be truncated.
Conditional Styling (Data-Driven)
Apply styles dynamically based on the data of a row or a specific cell. This is the most powerful styling feature.
The style precedence is: cellStyle > column.style > rowStyle > theme.
const config = {
// Style an entire row if a condition is met.
// The function receives the full row object.
rowStyle: (row) => {
if (row.status === 'Discontinued') {
return { color: 'red', italic: true };
}
},
columns: {
status: {
// Style a specific cell based on its own value.
cellStyle: (value) => {
if (value === 'Active') return { color: 'green' };
if (value === 'Backordered') return { color: 'yellow' };
},
},
},
};Sizing, Pagination, and Borders
Control the table's dimensions and borders.
import { DOUBLE_LINE_BORDER } from 'terminal-table-printer';
const config = {
// If set, imposes a maximum width on the entire table.
// If unset, the table defaults to the terminal's width.
maxWidth: 80,
// Display only 5 rows, starting from the 11th row (index 10)
rowLimit: 5,
rowOffset: 10,
// Add a descriptive footer
footer: (info) => `Showing rows ${info.startRow + 1}-${info.endRow} of ${info.totalRows}.`,
// Use a pre-defined or custom border style
border: DOUBLE_LINE_BORDER,
};