npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

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 Arrow Table objects.
  • 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-printer

Examples

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,
};