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 🙏

© 2026 – Pkg Stats / Ryan Hefner

prettier-plugin-markdown-compact-tables

v1.0.0

Published

Prettier plugin that prints Markdown and MDX tables in a compact form, without alignment padding.

Readme

prettier-plugin-markdown-compact-tables

CI License: MIT Prettier 3 Node.js 18+

English | 한국어

A Prettier plugin that prints Markdown and MDX tables in a compact form, without alignment padding. It hooks into Prettier 3's markdown and mdx parsers.

Pipes are surrounded by exactly one space, and cells are never padded to match column widths.

Contents

Why

Prettier's built-in Markdown printer pads every cell to its column width whenever the table fits within printWidth. Only a table that overflows the limit is printed in a compact form. In a documentation project that raises printWidth so prose is never wrapped, that means every table gets alignment padding.

When a table packs several lines into one cell with <br />, mixing lists and code, that single cell decides the width of the whole table. In the table below only the send_mode description is long: title and is_public are barely a few words.

What you write

| Name | Type | Description | Required |
| --- | --- | --- | --- |
| title | `String` | Notification title | O |
| send_mode | `Integer` | Delivery mode<br />- `0`: send immediately<br />- `1`: schedule for later<br />--set the time with `send_at`<br />- `2`: do not send<br />**Note**: defaults to `0` when omitted | X |
| is_public | `Boolean` | Whether the notice is public | X |

What the default printer produces

| Name      | Type      | Description                                                                                                                                                                      | Required |
| --------- | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
| title     | `String`  | Notification title                                                                                                                                                               | O        |
| send_mode | `Integer` | Delivery mode<br />- `0`: send immediately<br />- `1`: schedule for later<br />--set the time with `send_at`<br />- `2`: do not send<br />**Note**: defaults to `0` when omitted | X        |
| is_public | `Boolean` | Whether the notice is public                                                                                                                                                     | X        |

The description cells of title and is_public are padded out to the width of the send_mode description.

With word wrap on in an 80-column editor, it looks roughly like this. The padding stretches into what look like blank lines, the last cell of each row is pushed onto a line of its own, and the delimiter row runs on for four lines.

| Name      | Type      | Description

                                           | Required |
| --------- | --------- |
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
---------------- | -------- |
| title     | `String`  | Notification title

                                           | O        |
| send_mode | `Integer` | Delivery mode<br />- `0`: send immediately<br />- `1`:
schedule for later<br />--set the time with `send_at`<br />- `2`: do not
send<br />**Note**: defaults to `0` when omitted | X        |
| is_public | `Boolean` | Whether the notice is public

                                           | X        |

What this plugin produces

| Name | Type | Description | Required |
| --- | --- | --- | --- |
| title | `String` | Notification title | O |
| send_mode | `Integer` | Delivery mode<br />- `0`: send immediately<br />- `1`: schedule for later<br />--set the time with `send_at`<br />- `2`: do not send<br />**Note**: defaults to `0` when omitted | X |
| is_public | `Boolean` | Whether the notice is public | X |

Under the same word wrap, only the long send_mode row folds, into three lines; the other four rows stay on one line each.

| Name | Type | Description | Required |
| --- | --- | --- | --- |
| title | `String` | Notification title | O |
| send_mode | `Integer` | Delivery mode<br />- `0`: send immediately<br />- `1`:
schedule for later<br />--set the time with `send_at`<br />- `2`: do not
send<br />**Note**: defaults to `0` when omitted | X |
| is_public | `Boolean` | Whether the notice is public | X |

Line lengths

| Line | Default printer | This plugin | | --- | --- | --- | | Header | 215 chars | 40 chars | | Delimiter | 215 chars | 25 chars | | title row | 215 chars | 45 chars | | send_mode row | 215 chars | 208 chars | | is_public row | 215 chars | 60 chars |

Not a single character of content was added, yet the short lines grew three to nine times longer, and every added position is a space.

It also affects review. Adding one sentence to the send_mode description recomputes the column widths, so with the default printer all five lines of the table show up in the diff. With this plugin, only the line you actually edited does.

Requirements

| Item | Version | | --- | --- | | Node.js | 18 or later | | Prettier | 3.0 or later |

Every Prettier 3 minor release is covered by the test suite. See Compatibility.

Installation

Install it as a dev dependency alongside Prettier.

# npm
npm install --save-dev prettier prettier-plugin-markdown-compact-tables

# yarn
yarn add --dev prettier prettier-plugin-markdown-compact-tables

# pnpm
pnpm add --save-dev prettier prettier-plugin-markdown-compact-tables

The plugin is ESM-only and cannot be loaded through require(). Prettier 3's plugin loader handles ESM directly, so naming it in the configuration file is all that is needed.

Configuration

Add the package name to plugins in your Prettier configuration.

{
  "plugins": ["prettier-plugin-markdown-compact-tables"]
}

To vendor the plugin inside your repository instead of installing it, point at the file.

{
  "plugins": ["./tools/prettier-plugin-markdown-compact-tables/index.js"]
}

Recommended setup

The plugin compacts tables regardless of printWidth, so you never have to tune printWidth for the sake of tables. The options below concern the prose around them. Applying them through overrides keeps the rest of the repository on your usual formatting.

| Option | Recommended value | Why | | --- | --- | --- | | parser | "markdown" for .md, "mdx" for .mdx | Prettier already infers it from the extension, but stating it makes the override self-explanatory | | proseWrap | "never" | Keeps each paragraph on a single line, so editing one word produces a one-line diff | | printWidth | 99999 | Stops that single line from being folded again. It has no effect on how tables are printed |

Using Markdown

{
  "plugins": ["prettier-plugin-markdown-compact-tables"],
  "overrides": [
    {
      "files": "*.md",
      "options": {
        "parser": "markdown",
        "printWidth": 99999,
        "proseWrap": "never"
      }
    }
  ]
}

Using MDX

{
  "plugins": ["prettier-plugin-markdown-compact-tables"],
  "overrides": [
    {
      "files": "*.mdx",
      "options": {
        "parser": "mdx",
        "printWidth": 99999,
        "proseWrap": "never"
      }
    }
  ]
}

A project that carries both formats lists both entries in overrides.

Running it

# format everything
npx prettier --write .

# format documents only
npx prettier --write "**/*.{md,mdx}"

# check whether anything needs formatting
npx prettier --check "**/*.{md,mdx}"

To format on save, follow the Prettier editor integration guide. In VS Code, install the Prettier extension and add:

{
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "editor.formatOnSave": true,
  "prettier.documentSelectors": ["**/*.mdx"]
}

Table compaction

Table compaction has no option of its own: registering the plugin turns it on.

Rules applied

| Target | Behavior | | --- | --- | | Spaces around pipes | Fixed at one space; no padding is added to match column widths | | Runs of ASCII spaces inside a cell | Collapsed to a single space | | Unicode spaces in a cell | NBSP and ideographic space are content, so they are kept as written, even at the ends of a cell | | Trailing ASCII space in a cell | Removed | | Alignment markers | :--, :-: and --: are preserved as written |

Line-break tags and the wording inside a cell are left as written. Correcting those is what prettier-plugin-markdown-replacements is for.

What is left untouched

Preserving the source beats correcting it automatically and breaking the table structure. The plugin does not touch:

  • the contents of inline code, where spacing and tag spelling stay exactly as written
  • pipe lines that are not read as a table because the delimiter row is missing
  • tables whose rows do not match the header's column count
  • tables inside an MDX comment, {/* ... */}
  • MDX/JSX elements that contain a fenced code block

The one repair the printer makes

A Markdown table written inside an MDX comment can come out of a formatter as */} | on its closing row. The stray pipe is not valid MDX, and the next parse fails on it, so the printer drops it back to */}.

This is the only place the plugin changes anything other than layout, and it is deliberately narrow. The pipe is removed only when it trails a real comment close, matched against the comment ranges found in the source, and only at the end of a row. It repairs damage a formatter caused rather than editing what an author wrote: without it a document can stop parsing after a round trip.

prettier-plugin-markdown-replacements

This plugin only decides how a table is printed and never rewrites the words inside a cell. prettier-plugin-markdown-replacements corrects spellings and unifies notations such as <br> versus <br />, and its markdownReplacements option can be set in the same configuration.

Prettier resolves one parser per language and both plugins contribute one, so prettier-plugin-markdown-replacements has to be listed last. Listed first, its rules are silently skipped.

{
  "plugins": ["prettier-plugin-markdown-compact-tables", "prettier-plugin-markdown-replacements"],
  "markdownReplacements": ["Javascript=>JavaScript"]
}

Compatibility

| Prettier | Status | | --- | --- | | 3.0 to 3.9 | Supported. The full test suite passes on 3.0.3, 3.1.1, 3.2.5, 3.3.3, 3.4.2, 3.5.3, 3.6.2, 3.7.4, 3.8.1, 3.8.5, 3.9.0 and 3.9.6 |

Prettier 3.9 changed tableCell positions to cover the surrounding pipes. The plugin accounts for that, and the test suite asserts the same output on every supported version.

Prettier 4 pre-releases are outside the declared peer dependency range and have not been tested.

Both of Prettier's built-in parsers, markdown and mdx, are supported. The plugin wraps the printer of the built-in Markdown plugin, so anything unrelated to tables follows Prettier's default behavior.

Development

# install dependencies
npm install

# run the tests once
npm run test:run

# run the tests in watch mode
npm test

# format this repository's own documents
npm run format

The tests are written with Vitest and live in __tests__/. The MDX fragments under __tests__/fixtures/ come from real documents and serve as evidence that table structures survive formatting.

The GitHub Actions workflow in .github/workflows/ci.yml runs the same suite on Node.js 18, 20 and 22, and once more against each supported Prettier minor release.

Releasing

A release is a version bump on main: raise version in package.json and push. The workflow in .github/workflows/publish.yml compares that version with the one on npm, and when it is new it runs the tests, publishes the package with provenance through npm trusted publishing, and creates the matching v* tag and GitHub release. Nothing is published while the version stays the same.

License

MIT