table vs react-table vs datatables.net vs react-data-grid vs handsontable vs gridjs vs ag-grid
JavaScript Data Grid Libraries Comparison
1 Year
tablereact-tabledatatables.netreact-data-gridhandsontablegridjsag-gridSimilar Packages:
What's JavaScript Data Grid Libraries?

JavaScript data grid libraries provide developers with tools to display, manage, and manipulate tabular data in web applications. These libraries often come with features such as sorting, filtering, pagination, and editing capabilities, allowing for a rich user experience when dealing with large datasets. They are essential for applications that require data presentation in a structured format, enabling users to interact with data efficiently and intuitively.

NPM Package Downloads Trend
Github Stars Ranking
Stat Detail
Package
Downloads
Stars
Size
Issues
Publish
License
table12,172,961915335 kB26a month agoBSD-3-Clause
react-table1,018,00125,528940 kB206-MIT
datatables.net383,728511.06 MB13 days agoMIT
react-data-grid134,5567,056815 kB1314 months agoMIT
handsontable85,52020,28520.4 MB41424 days agoSEE LICENSE IN LICENSE.txt
gridjs18,6114,4491.37 MB13010 months agoMIT
ag-grid11,97213,218-806 years agoMIT
Feature Comparison: table vs react-table vs datatables.net vs react-data-grid vs handsontable vs gridjs vs ag-grid

Customization

  • table:

    The 'table' package offers minimal customization options, focusing on basic table structures without advanced features or styling capabilities.

  • react-table:

    React Table is designed to be highly customizable, allowing developers to create their own table UI while managing the underlying logic for sorting, filtering, and pagination. It encourages a component-based approach to building tables.

  • datatables.net:

    DataTables provides basic customization through options for styling and layout. However, it is less flexible compared to other libraries when it comes to deep customization of cell behavior or rendering.

  • react-data-grid:

    React Data Grid offers a range of customization options for columns, including custom renderers and editors, making it suitable for applications that require specific data input methods.

  • handsontable:

    Handsontable provides a rich set of customization options, including custom cell types, validation rules, and event handling, allowing developers to create a highly interactive user experience.

  • gridjs:

    Grid.js allows for easy customization of table components and styles, making it simple to adapt to various design requirements. It also supports custom renderers for cells and headers.

  • ag-grid:

    ag-Grid offers extensive customization options, allowing developers to define custom cell renderers, editors, and filters. It supports themes and styles, enabling a tailored look and feel for any application.

Performance

  • table:

    The 'table' package is basic and may not be optimized for performance with large datasets, making it suitable for simpler use cases.

  • react-table:

    React Table is lightweight and efficient, focusing on performance by minimizing re-renders and optimizing rendering logic, making it suitable for large datasets when implemented correctly.

  • datatables.net:

    DataTables performs well with moderate datasets, but performance may degrade with very large datasets unless server-side processing is implemented to handle data operations.

  • react-data-grid:

    React Data Grid is built for performance, offering features like row virtualization and efficient rendering to handle large datasets effectively in React applications.

  • handsontable:

    Handsontable is optimized for performance, especially with large datasets, thanks to its virtual rendering and efficient data handling techniques, providing a smooth user experience.

  • gridjs:

    Grid.js is lightweight and performs well with small to medium datasets. It is designed for speed and efficiency, making it suitable for modern web applications.

  • ag-grid:

    ag-Grid is optimized for performance, capable of handling large datasets efficiently with features like virtual scrolling and lazy loading, ensuring smooth interactions even with thousands of rows.

Integration

  • table:

    The 'table' package is a basic implementation that does not require any specific integration, making it easy to use in any HTML context.

  • react-table:

    React Table is a headless utility for React, allowing developers to build their own table UI while managing the underlying logic, making it highly adaptable for React projects.

  • datatables.net:

    DataTables can be easily integrated with jQuery and works well with existing HTML tables, making it a good choice for projects that already utilize jQuery.

  • react-data-grid:

    React Data Grid is specifically designed for React applications, offering a smooth integration experience with React's component lifecycle and state management.

  • handsontable:

    Handsontable integrates seamlessly with popular frameworks like React, Angular, and Vue, providing a consistent experience across different technology stacks.

  • gridjs:

    Grid.js is framework-agnostic and can be easily integrated into any web application, making it a flexible choice for developers looking for a simple grid solution.

  • ag-grid:

    ag-Grid integrates well with various frameworks including Angular, React, and Vue, providing a consistent API across different environments, making it versatile for multi-framework applications.

Editing Capabilities

  • table:

    The 'table' package does not support any editing capabilities, focusing solely on displaying data without interaction.

  • react-table:

    React Table does not provide built-in editing capabilities but allows developers to implement custom editing logic, giving flexibility in how data is edited within the table.

  • datatables.net:

    DataTables provides basic editing capabilities through external plugins, but it does not natively support inline editing or complex editing workflows.

  • react-data-grid:

    React Data Grid provides robust editing features, including inline editing and customizable editors, allowing for a seamless data entry experience in React applications.

  • handsontable:

    Handsontable excels in editing capabilities, providing a spreadsheet-like experience with support for complex cell types, validation, and formula calculations, making it ideal for data entry applications.

  • gridjs:

    Grid.js offers simple editing capabilities, allowing for inline editing of cell values, making it easy for users to update data directly in the grid.

  • ag-grid:

    ag-Grid supports a wide range of editing capabilities, including inline editing, cell editing, and custom editors, making it suitable for applications that require extensive data manipulation.

Documentation and Community Support

  • table:

    The 'table' package has basic documentation, but community support is limited, making it less ideal for developers seeking extensive resources.

  • react-table:

    React Table has extensive documentation and a vibrant community, providing numerous examples and discussions that help developers understand how to implement and customize the library effectively.

  • datatables.net:

    DataTables has good documentation and a supportive community, with plenty of examples and plugins available to enhance functionality, making it accessible for beginners.

  • react-data-grid:

    React Data Grid provides detailed documentation and an active community, ensuring developers have access to resources and support for building applications.

  • handsontable:

    Handsontable has thorough documentation and a strong community, offering numerous examples and support resources, making it easier for developers to implement and customize the library.

  • gridjs:

    Grid.js offers clear documentation and a growing community, providing essential resources for developers to get started and troubleshoot issues effectively.

  • ag-grid:

    ag-Grid has comprehensive documentation and a large community, providing extensive resources, tutorials, and support for developers, making it easier to implement and troubleshoot.

How to Choose: table vs react-table vs datatables.net vs react-data-grid vs handsontable vs gridjs vs ag-grid
  • table:

    Choose the 'table' package if you need a straightforward and basic table implementation without additional features. It is suitable for simple use cases where advanced functionalities are not required.

  • react-table:

    Opt for React Table if you prefer a lightweight, headless utility for building tables in React. It provides flexibility and allows you to implement custom UI while managing state and logic for sorting, filtering, and pagination.

  • datatables.net:

    Select DataTables if you are looking for a simple yet powerful solution for enhancing HTML tables with features like pagination, sorting, and filtering. It is easy to integrate and works well for smaller datasets or when you need quick enhancements to existing tables.

  • react-data-grid:

    Select React Data Grid if you are building a React application and need a grid component that integrates seamlessly with React's ecosystem. It offers a set of features tailored for React, including cell editing and customizable columns.

  • handsontable:

    Choose Handsontable if you need a spreadsheet-like experience with features such as cell editing, validation, and formula support. It is ideal for applications that require users to interact with data in a familiar spreadsheet format.

  • gridjs:

    Opt for Grid.js if you want a lightweight and flexible grid solution that is easy to set up and customize. It is particularly useful for modern web applications that require a minimalistic approach while still offering essential grid functionalities.

  • ag-grid:

    Choose ag-Grid if you need a highly customizable and feature-rich grid solution that supports complex data interactions and large datasets. It is suitable for enterprise applications that require advanced features like grouping, aggregation, and server-side operations.

README for table

Table

Produces a string that represents array data in a text table.

Github action status Coveralls NPM version Canonical Code Style Twitter Follow

Demo of table displaying a list of missions to the Moon.

Features

  • Works with strings containing fullwidth characters.
  • Works with strings containing ANSI escape codes.
  • Configurable border characters.
  • Configurable content alignment per column.
  • Configurable content padding per column.
  • Configurable column width.
  • Text wrapping.

Install

npm install table

Buy Me A Coffee Become a Patron

Usage

import { table } from 'table';

// Using commonjs?
// const { table } = require('table');

const data = [
    ['0A', '0B', '0C'],
    ['1A', '1B', '1C'],
    ['2A', '2B', '2C']
];

console.log(table(data));
╔════╤════╤════╗
║ 0A │ 0B │ 0C ║
╟────┼────┼────╢
║ 1A │ 1B │ 1C ║
╟────┼────┼────╢
║ 2A │ 2B │ 2C ║
╚════╧════╧════╝

API

table

Returns the string in the table format

Parameters:

  • data: The data to display

    • Type: any[][]
    • Required: true
  • config: Table configuration

    • Type: object
    • Required: false

config.border

Type: { [type: string]: string }
Default: honeywell template

Custom borders. The keys are any of:

  • topLeft, topRight, topBody,topJoin
  • bottomLeft, bottomRight, bottomBody, bottomJoin
  • joinLeft, joinRight, joinBody, joinJoin
  • bodyLeft, bodyRight, bodyJoin
  • headerJoin
const data = [
  ['0A', '0B', '0C'],
  ['1A', '1B', '1C'],
  ['2A', '2B', '2C']
];

const config = {
  border: {
    topBody: `─`,
    topJoin: `┬`,
    topLeft: `┌`,
    topRight: `┐`,

    bottomBody: `─`,
    bottomJoin: `┴`,
    bottomLeft: `└`,
    bottomRight: `┘`,

    bodyLeft: `│`,
    bodyRight: `│`,
    bodyJoin: `│`,

    joinBody: `─`,
    joinLeft: `├`,
    joinRight: `┤`,
    joinJoin: `┼`
  }
};

console.log(table(data, config));
┌────┬────┬────┐
│ 0A │ 0B │ 0C │
├────┼────┼────┤
│ 1A │ 1B │ 1C │
├────┼────┼────┤
│ 2A │ 2B │ 2C │
└────┴────┴────┘

config.drawVerticalLine

Type: (lineIndex: number, columnCount: number) => boolean
Default: () => true

It is used to tell whether to draw a vertical line. This callback is called for each vertical border of the table. If the table has n columns, then the index parameter is alternatively received all numbers in range [0, n] inclusively.

const data = [
  ['0A', '0B', '0C'],
  ['1A', '1B', '1C'],
  ['2A', '2B', '2C'],
  ['3A', '3B', '3C'],
  ['4A', '4B', '4C']
];

const config = {
  drawVerticalLine: (lineIndex, columnCount) => {
    return lineIndex === 0 || lineIndex === columnCount;
  }
};

console.log(table(data, config));

╔════════════╗
║ 0A  0B  0C ║
╟────────────╢
║ 1A  1B  1C ║
╟────────────╢
║ 2A  2B  2C ║
╟────────────╢
║ 3A  3B  3C ║
╟────────────╢
║ 4A  4B  4C ║
╚════════════╝

config.drawHorizontalLine

Type: (lineIndex: number, rowCount: number) => boolean
Default: () => true

It is used to tell whether to draw a horizontal line. This callback is called for each horizontal border of the table. If the table has n rows, then the index parameter is alternatively received all numbers in range [0, n] inclusively. If the table has n rows and contains the header, then the range will be [0, n+1] inclusively.

const data = [
  ['0A', '0B', '0C'],
  ['1A', '1B', '1C'],
  ['2A', '2B', '2C'],
  ['3A', '3B', '3C'],
  ['4A', '4B', '4C']
];

const config = {
  drawHorizontalLine: (lineIndex, rowCount) => {
    return lineIndex === 0 || lineIndex === 1 || lineIndex === rowCount - 1 || lineIndex === rowCount;
  }
};

console.log(table(data, config));

╔════╤════╤════╗
║ 0A │ 0B │ 0C ║
╟────┼────┼────╢
║ 1A │ 1B │ 1C ║
║ 2A │ 2B │ 2C ║
║ 3A │ 3B │ 3C ║
╟────┼────┼────╢
║ 4A │ 4B │ 4C ║
╚════╧════╧════╝

config.singleLine

Type: boolean
Default: false

If true, horizontal lines inside the table are not drawn. This option also overrides the config.drawHorizontalLine if specified.

const data = [
  ['-rw-r--r--', '1', 'pandorym', 'staff', '1529', 'May 23 11:25', 'LICENSE'],
  ['-rw-r--r--', '1', 'pandorym', 'staff', '16327', 'May 23 11:58', 'README.md'],
  ['drwxr-xr-x', '76', 'pandorym', 'staff', '2432', 'May 23 12:02', 'dist'],
  ['drwxr-xr-x', '634', 'pandorym', 'staff', '20288', 'May 23 11:54', 'node_modules'],
  ['-rw-r--r--', '1,', 'pandorym', 'staff', '525688', 'May 23 11:52', 'package-lock.json'],
  ['-rw-r--r--@', '1', 'pandorym', 'staff', '2440', 'May 23 11:25', 'package.json'],
  ['drwxr-xr-x', '27', 'pandorym', 'staff', '864', 'May 23 11:25', 'src'],
  ['drwxr-xr-x', '20', 'pandorym', 'staff', '640', 'May 23 11:25', 'test'],
];

const config = {
  singleLine: true
};

console.log(table(data, config));
╔═════════════╤═════╤══════════╤═══════╤════════╤══════════════╤═══════════════════╗
║ -rw-r--r--  │ 1   │ pandorym │ staff │ 1529   │ May 23 11:25 │ LICENSE           ║
║ -rw-r--r--  │ 1   │ pandorym │ staff │ 16327  │ May 23 11:58 │ README.md         ║
║ drwxr-xr-x  │ 76  │ pandorym │ staff │ 2432   │ May 23 12:02 │ dist              ║
║ drwxr-xr-x  │ 634 │ pandorym │ staff │ 20288  │ May 23 11:54 │ node_modules      ║
║ -rw-r--r--  │ 1,  │ pandorym │ staff │ 525688 │ May 23 11:52 │ package-lock.json ║
║ -rw-r--r--@ │ 1   │ pandorym │ staff │ 2440   │ May 23 11:25 │ package.json      ║
║ drwxr-xr-x  │ 27  │ pandorym │ staff │ 864    │ May 23 11:25 │ src               ║
║ drwxr-xr-x  │ 20  │ pandorym │ staff │ 640    │ May 23 11:25 │ test              ║
╚═════════════╧═════╧══════════╧═══════╧════════╧══════════════╧═══════════════════╝

config.columns

Type: Column[] | { [columnIndex: number]: Column }

Column specific configurations.

config.columns[*].width

Type: number
Default: the maximum cell widths of the column

Column width (excluding the paddings).


const data = [
  ['0A', '0B', '0C'],
  ['1A', '1B', '1C'],
  ['2A', '2B', '2C']
];

const config = {
  columns: {
    1: { width: 10 }
  }
};

console.log(table(data, config));
╔════╤════════════╤════╗
║ 0A │ 0B         │ 0C ║
╟────┼────────────┼────╢
║ 1A │ 1B         │ 1C ║
╟────┼────────────┼────╢
║ 2A │ 2B         │ 2C ║
╚════╧════════════╧════╝

config.columns[*].alignment

Type: 'center' | 'justify' | 'left' | 'right'
Default: 'left'

Cell content horizontal alignment

const data = [
  ['0A', '0B', '0C', '0D 0E 0F'],
  ['1A', '1B', '1C', '1D 1E 1F'],
  ['2A', '2B', '2C', '2D 2E 2F'],
];

const config = {
  columnDefault: {
    width: 10,
  },
  columns: [
    { alignment: 'left' },
    { alignment: 'center' },
    { alignment: 'right' },
    { alignment: 'justify' }
  ],
};

console.log(table(data, config));
╔════════════╤════════════╤════════════╤════════════╗
║ 0A         │     0B     │         0C │ 0D  0E  0F ║
╟────────────┼────────────┼────────────┼────────────╢
║ 1A         │     1B     │         1C │ 1D  1E  1F ║
╟────────────┼────────────┼────────────┼────────────╢
║ 2A         │     2B     │         2C │ 2D  2E  2F ║
╚════════════╧════════════╧════════════╧════════════╝

config.columns[*].verticalAlignment

Type: 'top' | 'middle' | 'bottom'
Default: 'top'

Cell content vertical alignment

const data = [
  ['A', 'B', 'C', 'DEF'],
];

const config = {
  columnDefault: {
    width: 1,
  },
  columns: [
    { verticalAlignment: 'top' },
    { verticalAlignment: 'middle' },
    { verticalAlignment: 'bottom' },
  ],
};

console.log(table(data, config));
╔═══╤═══╤═══╤═══╗
║ A │   │   │ D ║
║   │ B │   │ E ║
║   │   │ C │ F ║
╚═══╧═══╧═══╧═══╝

config.columns[*].paddingLeft

Type: number
Default: 1

The number of whitespaces used to pad the content on the left.

config.columns[*].paddingRight

Type: number
Default: 1

The number of whitespaces used to pad the content on the right.

The paddingLeft and paddingRight options do not count on the column width. So the column has width = 5, paddingLeft = 2 and paddingRight = 2 will have the total width is 9.

const data = [
  ['0A', 'AABBCC', '0C'],
  ['1A', '1B', '1C'],
  ['2A', '2B', '2C']
];

const config = {
  columns: [
    {
      paddingLeft: 3
    },
    {
      width: 2,
      paddingRight: 3
    }
  ]
};

console.log(table(data, config));
╔══════╤══════╤════╗
║   0A │ AA   │ 0C ║
║      │ BB   │    ║
║      │ CC   │    ║
╟──────┼──────┼────╢
║   1A │ 1B   │ 1C ║
╟──────┼──────┼────╢
║   2A │ 2B   │ 2C ║
╚══════╧══════╧════╝

config.columns[*].truncate

Type: number
Default: Infinity

The number of characters is which the content will be truncated. To handle a content that overflows the container width, table package implements text wrapping. However, sometimes you may want to truncate content that is too long to be displayed in the table.

const data = [
  ['Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus pulvinar nibh sed mauris convallis dapibus. Nunc venenatis tempus nulla sit amet viverra.']
];

const config = {
  columns: [
    {
      width: 20,
      truncate: 100
    }
  ]
};

console.log(table(data, config));
╔══════════════════════╗
║ Lorem ipsum dolor si ║
║ t amet, consectetur  ║
║ adipiscing elit. Pha ║
║ sellus pulvinar nibh ║
║ sed mauris convall…  ║
╚══════════════════════╝

config.columns[*].wrapWord

Type: boolean
Default: false

The table package implements auto text wrapping, i.e., text that has the width greater than the container width will be separated into multiple lines at the nearest space or one of the special characters: \|/_.,;-.

When wrapWord is false:

const data = [
    ['Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus pulvinar nibh sed mauris convallis dapibus. Nunc venenatis tempus nulla sit amet viverra.']
];

const config = {
  columns: [ { width: 20 } ]
};

console.log(table(data, config));
╔══════════════════════╗
║ Lorem ipsum dolor si ║
║ t amet, consectetur  ║
║ adipiscing elit. Pha ║
║ sellus pulvinar nibh ║
║ sed mauris convallis ║
║ dapibus. Nunc venena ║
║ tis tempus nulla sit ║
║ amet viverra.        ║
╚══════════════════════╝

When wrapWord is true:

╔══════════════════════╗
║ Lorem ipsum dolor    ║
║ sit amet,            ║
║ consectetur          ║
║ adipiscing elit.     ║
║ Phasellus pulvinar   ║
║ nibh sed mauris      ║
║ convallis dapibus.   ║
║ Nunc venenatis       ║
║ tempus nulla sit     ║
║ amet viverra.        ║
╚══════════════════════╝

config.columnDefault

Type: Column
Default: {}

The default configuration for all columns. Column-specific settings will overwrite the default values.

config.header

Type: object

Header configuration.

Deprecated in favor of the new spanning cells API.

The header configuration inherits the most of the column's, except:

  • content {string}: the header content.
  • width: calculate based on the content width automatically.
  • alignment: center be default.
  • verticalAlignment: is not supported.
  • config.border.topJoin will be config.border.topBody for prettier.
const data = [
      ['0A', '0B', '0C'],
      ['1A', '1B', '1C'],
      ['2A', '2B', '2C'],
    ];

const config = {
  columnDefault: {
    width: 10,
  },
  header: {
    alignment: 'center',
    content: 'THE HEADER\nThis is the table about something',
  },
}

console.log(table(data, config));
╔══════════════════════════════════════╗
║              THE HEADER              ║
║  This is the table about something   ║
╟────────────┬────────────┬────────────╢
║ 0A         │ 0B         │ 0C         ║
╟────────────┼────────────┼────────────╢
║ 1A         │ 1B         │ 1C         ║
╟────────────┼────────────┼────────────╢
║ 2A         │ 2B         │ 2C         ║
╚════════════╧════════════╧════════════╝

config.spanningCells

Type: SpanningCellConfig[]

Spanning cells configuration.

The configuration should be straightforward: just specify an array of minimal cell configurations including the position of top-left cell and the number of columns and/or rows will be expanded from it.

The content of overlap cells will be ignored to make the data shape be consistent.

By default, the configuration of column that the top-left cell belongs to will be applied to the whole spanning cell, except:

  • The width will be summed up of all spanning columns.
  • The paddingRight will be received from the right-most column intentionally.

Advances customized column-like styles can be configurable to each spanning cell to overwrite the default behavior.

const data = [
  ['Test Coverage Report', '', '', '', '', ''],
  ['Module', 'Component', 'Test Cases', 'Failures', 'Durations', 'Success Rate'],
  ['Services', 'User', '50', '30', '3m 7s', '60.0%'],
  ['', 'Payment', '100', '80', '7m 15s', '80.0%'],
  ['Subtotal', '', '150', '110', '10m 22s', '73.3%'],
  ['Controllers', 'User', '24', '18', '1m 30s', '75.0%'],
  ['', 'Payment', '30', '24', '50s', '80.0%'],
  ['Subtotal', '', '54', '42', '2m 20s', '77.8%'],
  ['Total', '', '204', '152', '12m 42s', '74.5%'],
];

const config = {
  columns: [
    { alignment: 'center', width: 12 },
    { alignment: 'center', width: 10 },
    { alignment: 'right' },
    { alignment: 'right' },
    { alignment: 'right' },
    { alignment: 'right' }
  ],
  spanningCells: [
    { col: 0, row: 0, colSpan: 6 },
    { col: 0, row: 2, rowSpan: 2, verticalAlignment: 'middle'},
    { col: 0, row: 4, colSpan: 2, alignment: 'right'},
    { col: 0, row: 5, rowSpan: 2, verticalAlignment: 'middle'},
    { col: 0, row: 7, colSpan: 2, alignment: 'right' },
    { col: 0, row: 8, colSpan: 2, alignment: 'right' }
  ],
};

console.log(table(data, config));
╔══════════════════════════════════════════════════════════════════════════════╗
║                             Test Coverage Report                             ║
╟──────────────┬────────────┬────────────┬──────────┬───────────┬──────────────╢
║    Module    │ Component  │ Test Cases │ Failures │ Durations │ Success Rate ║
╟──────────────┼────────────┼────────────┼──────────┼───────────┼──────────────╢
║              │    User    │         50 │       30 │     3m 7s │        60.0% ║
║   Services   ├────────────┼────────────┼──────────┼───────────┼──────────────╢
║              │  Payment   │        100 │       80 │    7m 15s │        80.0% ║
╟──────────────┴────────────┼────────────┼──────────┼───────────┼──────────────╢
║                  Subtotal │        150 │      110 │   10m 22s │        73.3% ║
╟──────────────┬────────────┼────────────┼──────────┼───────────┼──────────────╢
║              │    User    │         24 │       18 │    1m 30s │        75.0% ║
║ Controllers  ├────────────┼────────────┼──────────┼───────────┼──────────────╢
║              │  Payment   │         30 │       24 │       50s │        80.0% ║
╟──────────────┴────────────┼────────────┼──────────┼───────────┼──────────────╢
║                  Subtotal │         54 │       42 │    2m 20s │        77.8% ║
╟───────────────────────────┼────────────┼──────────┼───────────┼──────────────╢
║                     Total │        204 │      152 │   12m 42s │        74.5% ║
╚═══════════════════════════╧════════════╧══════════╧═══════════╧══════════════╝

createStream

table package exports createStream function used to draw a table and append rows.

Parameter:

  • config: the same as table's, except config.columnDefault.width and config.columnCount must be provided.
import { createStream } from 'table';

const config = {
  columnDefault: {
    width: 50
  },
  columnCount: 1
};

const stream = createStream(config);

setInterval(() => {
  stream.write([new Date()]);
}, 500);

Streaming current date.

table package uses ANSI escape codes to overwrite the output of the last line when a new row is printed.

The underlying implementation is explained in this Stack Overflow answer.

Streaming supports all of the configuration properties and functionality of a static table (such as auto text wrapping, alignment and padding), e.g.

import { createStream } from 'table';

import _ from 'lodash';

const config = {
  columnDefault: {
    width: 50
  },
  columnCount: 3,
  columns: [
    {
      width: 10,
      alignment: 'right'
    },
    { alignment: 'center' },
    { width: 10 }

  ]
};

const stream = createStream(config);

let i = 0;

setInterval(() => {
  let random;

  random = _.sample('abcdefghijklmnopqrstuvwxyz', _.random(1, 30)).join('');

  stream.write([i++, new Date(), random]);
}, 500);

Streaming random data.

getBorderCharacters

Parameter:

  • template
    • Type: 'honeywell' | 'norc' | 'ramac' | 'void'
    • Required: true

You can load one of the predefined border templates using getBorderCharacters function.

import { table, getBorderCharacters } from 'table';

const data = [
  ['0A', '0B', '0C'],
  ['1A', '1B', '1C'],
  ['2A', '2B', '2C']
];

const config = {
  border: getBorderCharacters(`name of the template`)
};

console.log(table(data, config));
# honeywell

╔════╤════╤════╗
║ 0A │ 0B │ 0C ║
╟────┼────┼────╢
║ 1A │ 1B │ 1C ║
╟────┼────┼────╢
║ 2A │ 2B │ 2C ║
╚════╧════╧════╝

# norc

┌────┬────┬────┐
│ 0A │ 0B │ 0C │
├────┼────┼────┤
│ 1A │ 1B │ 1C │
├────┼────┼────┤
│ 2A │ 2B │ 2C │
└────┴────┴────┘

# ramac (ASCII; for use in terminals that do not support Unicode characters)

+----+----+----+
| 0A | 0B | 0C |
|----|----|----|
| 1A | 1B | 1C |
|----|----|----|
| 2A | 2B | 2C |
+----+----+----+

# void (no borders; see "borderless table" section of the documentation)

 0A  0B  0C

 1A  1B  1C

 2A  2B  2C

Raise an issue if you'd like to contribute a new border template.

Borderless Table

Simply using void border character template creates a table with a lot of unnecessary spacing.

To create a more pleasant to the eye table, reset the padding and remove the joining rows, e.g.


const output = table(data, {
    border: getBorderCharacters('void'),
    columnDefault: {
        paddingLeft: 0,
        paddingRight: 1
    },
    drawHorizontalLine: () => false
    }
);

console.log(output);
0A 0B 0C
1A 1B 1C
2A 2B 2C