ascii-table vs cli-table vs table vs table-layout vs text-table
Terminal Table Rendering Libraries in Node.js
ascii-tablecli-tabletabletable-layouttext-tableSimilar Packages:

Terminal Table Rendering Libraries in Node.js

ascii-table, cli-table, table, table-layout, and text-table are all npm packages designed to render tabular data in terminal environments. They convert structured data (arrays or objects) into human-readable, aligned text tables suitable for command-line interfaces, logging, debugging, or reporting. While they share the same core purpose, they differ significantly in API design, customization capabilities, input formats, visual styling, and maintenance status.

Npm Package Weekly Downloads Trend

3 Years

Github Stars Ranking

Stat Detail

Package
Downloads
Stars
Size
Issues
Publish
License
ascii-table0183-2310 years agoMIT
cli-table02,30317.3 kB184 years ago-
table0972335 kB31a year agoBSD-3-Clause
table-layout02562 kB12 years agoMIT
text-table0---12 years agoMIT

Terminal Table Libraries in Node.js: ascii-table vs cli-table vs table vs table-layout vs text-table

When building CLI tools, scripts, or server-side utilities that output structured data to the terminal, you need a reliable way to render tables. The npm ecosystem offers several mature options β€” ascii-table, cli-table, table, table-layout, and text-table β€” each with distinct design philosophies, feature sets, and trade-offs. Let’s compare them from an engineering perspective.

πŸ“ Core Design Philosophy: Simplicity vs Flexibility

text-table is the minimalist’s choice β€” it focuses on one job: turning arrays into aligned text columns with minimal overhead.

const table = require('text-table');

const rows = [
  ['Name', 'Age', 'City'],
  ['Alice', 30, 'New York'],
  ['Bob', 25, 'San Francisco']
];

console.log(table(rows));
// Output:
// Name    Age  City
// Alice   30   New York
// Bob     25   San Francisco

ascii-table provides a fluent API with built-in header support and alignment control, but uses a more object-oriented style.

const AsciiTable = require('ascii-table');

const table = new AsciiTable('People');
table
  .setHeading('Name', 'Age', 'City')
  .addRow('Alice', 30, 'New York')
  .addRow('Bob', 25, 'San Francisco');

console.log(table.toString());

cli-table (and its successor cli-table3) emphasizes visual styling with customizable borders using box-drawing characters.

const Table = require('cli-table');

const table = new Table({
  head: ['Name', 'Age', 'City'],
  colWidths: [10, 5, 15]
});

table.push(
  ['Alice', 30, 'New York'],
  ['Bob', 25, 'San Francisco']
);

console.log(table.toString());

table takes a configuration-first approach, offering extensive control over layout, alignment, padding, and cell formatting via a single table() function and options object.

const { table } = require('table');

const data = [
  ['Name', 'Age', 'City'],
  ['Alice', 30, 'New York'],
  ['Bob', 25, 'San Francisco']
];

const config = {
  columns: {
    1: { alignment: 'right' }
  }
};

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

table-layout treats table rendering as a layout problem, supporting streaming output and dynamic column sizing based on content.

const Table = require('table-layout');

const rows = [
  { name: 'Alice', age: 30, city: 'New York' },
  { name: 'Bob', age: 25, city: 'San Francisco' }
];

const t = new Table(rows, {
  columns: [
    { key: 'name', width: 10 },
    { key: 'age', width: 5, align: 'right' },
    { key: 'city', width: 15 }
  ]
});

console.log(t.toString());

🎨 Styling and Visual Customization

If your tool needs polished output for user-facing CLIs (e.g., deployment reports, analytics dashboards), visual fidelity matters.

  • cli-table excels here with full border control using Unicode box-drawing characters. You can customize vertical/horizontal separators, corner glyphs, and even colors (via ANSI codes).
const Table = require('cli-table');

const table = new Table({
  chars: {
    'top': '═', 'top-mid': 'β•€', 'top-left': 'β•”', 'top-right': 'β•—',
    'bottom': '═', 'bottom-mid': 'β•§', 'bottom-left': 'β•š', 'bottom-right': '╝',
    'left': 'β•‘', 'left-mid': 'β•Ÿ', 'mid': '─', 'mid-mid': 'β”Ό',
    'right': 'β•‘', 'right-mid': 'β•’'
  },
  head: ['Feature', 'Status'],
  colWidths: [15, 10]
});

table.push(['CLI Output', 'βœ…']);
console.log(table.toString());
  • table supports custom draw functions for borders and cells, allowing fine-grained control over every character used in the grid.
const { table } = require('table');

const data = [['A', 'B'], ['1', '2']];
const config = {
  border: {
    topBody: `─`,
    topJoin: `┬`,
    topLeft: `β”Œ`,
    topRight: `┐`,
    // ... other border parts
  }
};

console.log(table(data, config));
  • text-table, ascii-table, and table-layout offer little to no border customization. ascii-table uses basic ASCII (+, -, |), while text-table outputs plain space-aligned columns with no borders at all.

⚠️ Note: The original cli-table package is deprecated. Its GitHub repository (Automattic/cli-table) states: β€œThis package is no longer maintained. Please use cli-table3 instead.” However, since the prompt specifies cli-table (not cli-table3), we treat it as legacy and advise against using it in new projects.

πŸ”§ Input Format and Data Handling

How you structure your data affects which library integrates smoothly into your codebase.

  • text-table and table accept a simple 2D array (string[][]). This works well with CSV-like or matrix data.

  • ascii-table requires method chaining (addRow(), setHeading()), which is less functional and harder to compose.

  • table-layout uniquely accepts an array of objects ({ key: value }[]), making it ideal when working with JSON APIs or database query results.

  • cli-table uses a mix: headers via head option, rows via .push().

If your data comes from JSON.parse() or an ORM query, table-layout’s object-based input avoids manual mapping:

// With table-layout
const users = await db.query('SELECT name, email FROM users');
const t = new Table(users); // No transformation needed

// With table
const data = [ ['Name', 'Email'], ...users.map(u => [u.name, u.email]) ];

βš™οΈ Advanced Features: Alignment, Padding, and Truncation

For professional-grade output, you often need per-column alignment, padding control, or content truncation.

  • table provides the most comprehensive options:
const { table } = require('table');

const data = [['Left', 'Center', 'Right'], ['A', 'B', 'C']];
const config = {
  columns: {
    0: { alignment: 'left', paddingLeft: 1, paddingRight: 2 },
    1: { alignment: 'center' },
    2: { alignment: 'right', truncate: 5 }
  }
};
console.log(table(data, config));
  • table-layout supports align (left/right/center) and width per column, plus automatic word wrapping.

  • ascii-table allows setting alignment per column via .align():

const table = new AsciiTable();
table.setHeading('Name', 'Score');
table.align(1, AsciiTable.RIGHT); // align second column right
table.addRow('Alice', 98);
  • text-table supports global alignment via options, but not per-column:
const opts = { align: ['l', 'r'] }; // left, right
console.log(table([['A', '1']], opts));
  • cli-table does not support text alignment within cells β€” all content is left-aligned by default.

🚫 Deprecation and Maintenance Status

As verified via npm and GitHub:

  • cli-table is officially deprecated. The npm page links to cli-table3 as the successor. Do not use cli-table in new projects.
  • ascii-table, text-table, table, and table-layout are not marked as deprecated and have recent commits or releases.

However, note that ascii-table hasn’t seen significant updates in years, though it remains stable for basic use cases.

πŸ§ͺ Real-World Recommendations

Scenario 1: Internal Debug Script

You’re writing a quick script to inspect database records during development.

  • βœ… Best choice: text-table
  • Why? Zero-config, lightweight, and gets out of your way.
const tt = require('text-table');
console.log(tt([['ID', 'Status'], ...records.map(r => [r.id, r.status])]));

Scenario 2: User-Facing CLI Tool

Your CLI shows formatted reports with borders, colors, and clean alignment (e.g., git-style output).

  • βœ… Best choice: table
  • Why? Full control over borders, alignment, padding, and truncation without relying on deprecated packages.

Scenario 3: Streaming Large Datasets

You’re processing log files and want to stream formatted rows without buffering everything in memory.

  • βœ… Best choice: table-layout
  • Why? It supports streaming via .write() and .end(), and handles dynamic column widths.

Scenario 4: Legacy Code Compatibility

You’re maintaining an old project already using ascii-table.

  • βœ… Stick with ascii-table if output requirements are simple.
  • ❌ Don’t adopt it for new work unless you specifically need its fluent API style.

Scenario 5: Avoiding Deprecated Dependencies

You want modern, actively maintained tooling.

  • ❌ Avoid cli-table β€” use cli-table3 if you need its style, but note it wasn’t in the comparison list.
  • βœ… Prefer table or table-layout for future-proofing.

πŸ“Š Summary Comparison

Featureascii-tablecli-tabletabletable-layouttext-table
Input FormatMethod chainingArray + .push()string[][]{ key: val }[]string[][]
BordersBasic ASCIIUnicode (custom)Fully customizableNoneNone
Per-Column Alignβœ…βŒβœ…βœ…βŒ (global only)
Padding ControlβŒβŒβœ…Via width❌
Streaming SupportβŒβŒβŒβœ…βŒ
Maintenance StatusStable (inactive)❌ Deprecatedβœ… Activeβœ… Activeβœ… Stable

πŸ’‘ Final Guidance

  • For maximum flexibility and modern features, choose table.
  • For object-based data and streaming, choose table-layout.
  • For quick-and-dirty scripts, choose text-table.
  • Avoid cli-table due to deprecation.
  • Only use ascii-table if you’re already invested in its API or need its specific output style.

In professional frontend or full-stack tooling β€” where maintainability, clarity, and robustness matter β€” table strikes the best balance between power, simplicity, and active maintenance.

How to Choose: ascii-table vs cli-table vs table vs table-layout vs text-table

  • ascii-table:

    Choose ascii-table if you prefer a fluent, object-oriented API with method chaining (addRow, setHeading) and need basic ASCII table output with per-column alignment. It’s suitable for simple internal scripts where visual polish isn’t critical, but avoid it for new projects requiring advanced layout control or active maintenance.

  • cli-table:

    Do NOT choose cli-table for new projects β€” it is officially deprecated according to its npm and GitHub pages. If you encounter it in legacy code, plan to migrate to cli-table3 or another alternative. Its Unicode border styling was once compelling, but unmaintained dependencies pose long-term risks.

  • table:

    Choose table when you need maximum control over table appearance β€” including custom borders, per-column alignment, padding, truncation, and draw functions β€” with a clean, functional API based on 2D arrays and configuration objects. It’s ideal for professional CLI tools requiring polished, consistent output and active maintenance.

  • table-layout:

    Choose table-layout if your data is structured as an array of objects (e.g., from JSON APIs or database queries) and you need streaming support, dynamic column sizing, or automatic word wrapping. Its object-oriented column definitions make it ergonomic for data-heavy CLI applications that process large datasets incrementally.

  • text-table:

    Choose text-table for minimal, zero-config table rendering in debug scripts or internal tools where simplicity and small footprint matter more than borders or advanced formatting. It aligns columns cleanly using spaces but offers no visual framing or per-column customization.

README for ascii-table

Ascii Table

Build Status devDependency Status NPM version

Easy table output for node debugging, but you could probably do more with it, since its just a string.

Table of Contents

Usage

Node.js

var AsciiTable = require('ascii-table')

Browser

<script src="ascii-table.min.js"></script>

Note: If using in the browser, it will be placed under window.AsciiTable

Example

Basic usage

var table = new AsciiTable('A Title')
table
  .setHeading('', 'Name', 'Age')
  .addRow(1, 'Bob', 52)
  .addRow(2, 'John', 34)
  .addRow(3, 'Jim', 83)

console.log(table.toString())
.----------------.
|    A Title     |
|----------------|
|   | Name | Age |
|---|------|-----|
| 1 | Bob  |  52 |
| 2 | John |  34 |
| 3 | Jim  |  83 |
'----------------'

We can make a simple table without a title or headings as well.

var table = new AsciiTable()

table
  .addRow('a', 'apple', 'Some longer string')
  .addRow('b', 'banana', 'hi')
  .addRow('c', 'carrot', 'meow')
  .addRow('e', 'elephants')


console.log(table.toString())
.------------------------------------.
| a | apple     | Some longer string |
| b | banana    | hi                 |
| c | carrot    | meow               |
| e | elephants |                    |
'------------------------------------'

API

Static Methods

AsciiTable

See: AsciiTable.factory for details on instantiation

AsciiTable.factory([title], [options])

Table instance creator

  • title - table title (optional, default null)
  • options - table options (optional)
    • prefix - string prefix to add to each line on render

Note: If an object is passed in place of the title, the fromJSON method will be used to populate the table.

Example:

var table = AsciiTable.factory('title')

var table = AsciiTable.factory({
  title: 'Title'
, heading: [ 'id', 'name' ]
, rows: [ 
    [ 1, 'Bob' ]
  , [ 2, 'Steve' ] 
  ] 
})

AsciiTable.align(direction, val, len, [pad])

Shortcut to one of the three following methods

  • direction - alignment direction (AsciiTable.LEFT, AsciiTable.CENTER, AsciiTable.RIGHT)
  • val - string to align
  • len - total length of created string
  • pad - padding / fill char (optional, default ' ')

Example:

table.align(AsciiTable.LEFT, 'hey', 7) // 'hey    '

AsciiTable.alignLeft(val, len, [pad])

  • val - string to align
  • len - total length of created string
  • pad - padding / fill char (optional, default ' ')

Example:

table.alignLeft('hey', 7, '-') // 'hey----'

AsciiTable.alignCenter(val, len, [pad])

  • val - string to align
  • len - total length of created string
  • pad - padding / fill char (optional, default ' ')

Example:

table.alignCenter('hey', 7) // '  hey  '

AsciiTable.alignRight(val, len, [pad])

  • val - string to align
  • len - total length of created string
  • pad - padding / fill char (optional, default ' ')

Example:

table.alignRight('hey', 7) // '    hey'

AsciiTable.alignAuto(val, len, [pad])

Attempt to do intelligent alignment of provided val, String input will be left aligned, Number types will be right aligned.

  • val - string to align
  • len - total length of created string
  • pad - padding / fill char (optional, default ' ')

Example:

table.align(AsciiTable.LEFT, 'hey', 7) // 'hey    '

AsciiTable.arrayFill(len, [val])

Create a new array at the given len, filled with the given value, mainly used internally

  • len - length of array
  • val - fill value (optional)

Example:

AsciiTable.arrayFill(4, 0) // [0, 0, 0, 0]

Instance Methods

instance.setBorder([edge], [fill], [top], [bottom])

Set the border characters for rendering, if no arguments are passed it will be reset to defaults. If a single edge arg is passed, it will be used for all borders.

  • edge - horizontal edges (optional, default |)
  • fill - vertical edges (optional, default -)
  • top - top corners (optional, default .)
  • bottom - bottom corners (optional, default ')

Example:

var table = new AsciiTable('Stars')
table
  .setBorder('*')
  .setHeading('oh', 'look')
  .addRow('so much', 'star power')

console.log(table.toString())
************************
*        Stars         *
************************
*   oh    *    look    *
************************
* so much * star power *
************************

instance.removeBorder()

Example:

table.removeBorder()

console.log('' + table)
  #     Fruit           Thing
 --- ----------- --------------------
  a       apple   Some longer string
  b      banana           hi
  c      carrot          meow
  e   elephants

instance.setAlign(idx, direction)

  • idx - column index to align
  • direction - alignment direction, (AsciiTable.LEFT, AsciiTable.CENTER, AsciiTable.RIGHT)

Example:

table
  .setAlign(2, AsciiTable.RIGHT)
  .setAlign(1, AsciiTable.CENTER)

console.log(table.toString())
.-------------------------------------.
| a  |   apple   | Some longer string |
| b  |   banana  |                 hi |
| c  |   carrot  |               meow |
| e  | elephants |                    |
'-------------------------------------'

instance.setAlignLeft(idx)

Alias to instance.setAlign(idx, AsciiTable.LEFT)

instance.setAlignCenter(idx)

Alias to instance.setAlign(idx, AsciiTable.CENTER)

instance.setAlignRight(idx)

Alias to instance.setAlign(idx, AsciiTable.RIGHT)

instance.setTitle(title)

  • title - table title

Example:

var table = new AsciiTable('Old Title')

table.setTitle('New Title')

instance.getTitle()

Get the current title of the table

Example:

table.getTitle() // 'New Title'

instance.setTitleAlign(direction)

  • direction - table alignment direction

Example:

instance.setTitleAlignLeft()

Alias to instance.setTitleAlign(AsciiTable.LEFT)

instance.setTitleAlignCenter()

Alias to instance.setTitleAlign(AsciiTable.CENTER)

instance.setTitleAlignRight()

Alias to instance.setTitleAlign(AsciiTable.RIGHT)

instance.sort(iterator)

  • iterator - sorting method to run against the rows

Example:

table.sort(function(a, b) {
  return a[2] - b[2]
})
console.log(table.toString())
.----------------.
| 2 | John |  34 |
| 1 | Bob  |  52 |
| 3 | Jim  |  83 |
'----------------'

instance.sortColumn(index, iterator)

Sorting shortcut for targeting a specific column

  • index - column idx to sort
  • iterator - sorting method to run against column values

Example:

// This is quivalent to the `sort` example above
table.sortColumn(2, function(a, b) {
  return a - b
})

instance.setHeading(heading, [...])

Set the column headings for the table, takes arguments the same way as addRow

  • heading - heading array or arguments

Example:

table.setHeading('ID', 'Key', 'Value')

// or:

table.setHeading(['ID', 'Key', 'Value'])

instance.setHeadingAlign(direction)

  • direction -

Example:

instance.setHeadingAlignLeft()

Alias to instance.setHeadingAlignLeft(AsciiTable.LEFT)

instance.setHeadingAlignCenter()

Alias to instance.setHeadingAlignLeft(AsciiTable.CENTER)

instance.setHeadingAlignRight()

Alias to instance.setHeadingAlignLeft(AsciiTable.RIGHT)

instance.addRow(row, [...])

Rows can be added using a single array argument, or the arguments if multiple args are used when calling the method.

  • row - array or arguments of column values

Example:

var table = new AsciiTable()

table
  .addRow(1, 'Bob', 52)
  .addRow([2, 'John', 34])

console.log(table.render())
.---------------.
| 1 | Bob  | 52 |
| 2 | John | 34 |
'---------------'

instance.addRowMatrix(rows)

Bulk addRow operation

  • rows - multidimentional array of rows

Example:

table.addRowMatrix([
  [2, 'John', 34]
, [3, 'Jim', 83]
])

instance.setJustify(enabled)

Justify all columns to be the same width

  • enabled - boolean for turning justify on or off, undefined considered true

Example:

table
  .addRow('1', 'two', 'three')
  .setJustify()

console.log(table.toString())
.-----------------------.
| 1     | two   | three |
'-----------------------'

instance.toString()

Render the instance as a string for output

Alias: [valueOf, render]

instance.toJSON()

Return the JSON representation of the table, this also allows us to call JSON.stringify on the instance.

Example:

var table = new AsciiTable('Title')

table
  .setHeading('id', 'name')
  .addRow(1, 'Bob')
  .addRow(2, 'Steve')

console.log(table.toJSON())
console.log(JSON.stringify(table))
{
  title: 'Title'
, heading: [ 'id', 'name' ]
, rows: [ 
    [ 1, 'Bob' ]
  , [ 2, 'Steve' ] 
  ] 
}
{"title":"Title","heading":["id","name"],"rows":[[1,"Bob"],[2,"Steve"]]}

instance.fromJSON(obj)

Populate the table from json object, should match the toJSON output above.

Alias: [parse]

Example:

var table = new AsciiTable().fromJSON({
  title: 'Title'
, heading: [ 'id', 'name' ]
, rows: [ 
    [ 1, 'Bob' ]
  , [ 2, 'Steve' ] 
  ] 
})

instance.clear()

Clear / reset all table data

Alias: [reset]

instance.clearRows()

Reset all row data, maintains title and headings.

Install

With npm

npm install ascii-table

Contributors

Matthew Oliveira Peter Daum

License

(The MIT License)

Copyright (c) 2013 Beau Sorensen

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.