Library / SDK
jbrooksuk/node-summary avatar
jbrooksuk/node-summary

node-summary: a sentence picker for summarizing text in Node

Node module that summarizes text using a naive summarization algorithm

768 stars93 forksJavaScriptLicense varies

At a glance

What is it?
node-summary is a small JavaScript module that extracts the key sentence from every paragraph of a text, ported from a Python gist, with a URL helper that fetches a page and strips its HTML. It has had no published release since 2015, and the last push was on 2026-05-08.
Who is it for?
Adopt node-summary only if you want a deterministic, dependency-light way to shorten a document by keeping one sentence per paragraph, and understand that you are getting extraction, not comprehension, so a summary can still be unreadable. Steer away if you need abstractive output, language awareness, or a package with a current release and a declared licence, because the latest published version is 1.1.0 from 2015-03-31 and the licence is not identified in the project files.
Can I use it commercially?
Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
Is it still maintained?
Yes. The repository last received commits 170 days ago.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 24, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The algorithm keeps one sentence from each paragraph

node-summary summarizes text with what the project calls a naive summarization algorithm, ported from a Python implementation published as a gist by shlomibabluki. The algorithm is explained in a linked article, and the README summarizes it in one line: it extracts the key sentence from each paragraph in the text.

That is the whole idea, and it is worth being blunt about what it means. Nothing in the text is rewritten, nothing is inferred, and no model is involved. The module picks, paragraph by paragraph, and the output is the original sentences. The first example in the README ends with a printed comparison of the original length and the summary length, and a computed summary ratio, so the module is built for a quick check on how much text was dropped.

Because the result is assembled from the input, the quality ceiling is set by sentence selection rather than by generation. A paragraph whose most important idea is spread across three sentences will lose two of them, and a paragraph that opens with a rhetorical question can lose the answer. For long reference documents where each paragraph makes one point, that is a fair trade. For anything argumentative or narrative, it is not.

The module is published to npm as node-summary, and the installation instruction in the README is a single line:

bash
    $ npm install node-summary

Callback style API with a URL helper built on axios and cheerio

The API is small and callback based. You require the module, hand it a title and a body of text, and get a summary back:

javascript
var SummaryTool = require('node-summary');

The second entry point takes a URL instead of text, which is the part that saves you writing a fetch and an HTML cleanup yourself. The dependencies list explains how it works: axios for the request, cheerio and html-to-text for turning the returned page into text, and sbd for sentence tokenizing. The URL form of the call looks like this:

javascript
SummaryTool.summarizeFromUrl(url, function(err, summary) {
  if(err) {
    console.log("err is ", result)
  }
  else {
    console.log(summary)
  }
})

Two things about that snippet are worth noticing, and both are honest shortcomings rather than typos on my part. The error branch logs a variable called result, which is not the argument in scope, so an error path prints undefined instead of the error. And the callback shape is the older Node convention, error first and then the value, which is fine but is not the promise or async style a modern caller would reach for.

On the expected output, the README shows a sample summary where the retained sentences come straight from the source:

code
Swayy is a beautiful new dashboard for discovering and curating online content [Invites]
I like it for the simplicity and accuracy of the content curation.

The title is carried through as the first line, and the rest are selected sentences from the body.

A 2013 release, a 2015 tokenizer release, and a 2026 push

The release history is short and dated. Version 1.0.0, the first release, is tagged 2013-12-17, and version 1.1.0, named Sentence Tokenizing, is tagged 2015-03-31. The package metadata in the repository lists the version as 1.2.0, so there is work in the tree that has not been published as a tagged release, and the version number in package.json is not evidence of a shipped artefact.

The commit record tells a different story from the release list. The last push was on 2026-05-08, and the default branch is master. So the code is being touched, but no new release has been cut in more than a decade, and the README still carries a Travis CI badge for a service that has been replaced by GitHub Actions, along with a browser branch that the author describes as started work with all tests passing but not yet released.

That browser branch note tells you something about the architecture. The summary logic is meant to move out of Node so it can run in a browser, but the author also notes that some of the code should be further optimized for the client before release. In other words, the module is not yet a clean split between a platform independent core and the platform specific parts.

The licence is the other gap. The project files do not identify a licence, and the repository carries no LICENSE entry in its top level listing, so there is no clear permission statement to rely on if you want to vendor this into a commercial product.

The package manifest mixes module systems and carries old build tooling

The package metadata is where the rough edges show. The manifest declares the module type and the entry point, and the test command:

json
  "main": "./lib/summary.js",
  "scripts": {
    "test": "mocha --compilers js:babel-core/register --require should --reporter spec"
  },

The type field in the manifest is set to module, which means the package is treated as ES modules by Node, while the README examples import it with require. That is a real inconsistency for a new user, and it is the kind of thing you discover on your first install rather than in a changelog.

The test tooling is older still. The mocha version in devDependencies is 3.2.0 and the assertion library is should at 11.2.1, and the test script relies on the babel-core/register compiler hook with the --compilers flag, which is a Babel 6 era mechanism. The runtime dependencies match that vintage in places: babel-core and babel-preset-es2015 are listed at 6.24.0 and are shipped as runtime dependencies rather than dev dependencies, and cheerio is pinned to 0.22.0 while axios and lodash are current. The sbd package at version 1.0 handles the sentence splitting that gives version 1.1.0 its name.

The .babelrc file in the repository root and the presence of an index.js beside the lib directory suggest a CommonJS source tree transpiled into the lib output that main points at.

Where a naive sentence picker stops being enough

The honest limitation is the algorithm, and it has two parts. First, the selection is per paragraph, so a document whose structure does not match its paragraphs, such as one with long list items or multi-paragraph arguments, will summarize poorly. Second, the output is verbatim text, which means a summary of a technical document can still contain the hedging and digression that made the original long, because the sentence chosen is the longest or most central rather than the clearest.

There is also a structural limitation to the URL helper. Fetching a page, converting it to text and summarizing it means the module inherits every failure mode of a scraper: pages that need JavaScript render nothing, pages behind a login return a sign-in page, and the extracted text may include navigation and footer content that then gets summarized as if it were prose. The cheerio and html-to-text dependencies do a reasonable job of stripping markup, but nothing in the described pipeline distinguishes article text from site chrome.

A concrete alternative is to do the extraction with a tool built for reading pages, such as a readability library, and to do the selection with a real summarization approach. If you want extractive summarization with sentence scoring that considers position and length across the whole document rather than within a paragraph, an existing natural language toolkit does that, and it does it with a maintained package behind it. The case for node-summary is that it is thirty lines of logic with no model, and the case against is that its release history stopped in 2015.

What to check before you depend on this

If you decide the fit is right, a few things are worth settling first, and none of them are guessable from the README alone.

The module system question comes first, since the manifest says module and the examples use require. The dependency list is the second, since babel-core 6 and cheerio 0.22 are old enough that a security review of the tree may flag them. The third is the licence, because a package with no stated licence gives you no permission to use it in a product.

What you can rely on is narrow but real. The core behaviour is one sentence per paragraph, the entry points are summarize for text and summarizeFromUrl for a page, and the tests use mocha with the should assertion library. The test suite is in the test directory at the top of the tree, and the test script in the manifest is the way to run it.

What you cannot rely on is any of the things a maintained package would give you. There is no tagged release for the current version in package.json, no release notes to diff against, no declared licence, and a build pipeline built on Babel 6 tooling that predates the current Node release cycle by several years.

Editorial conclusion

Adopt node-summary only if you want a deterministic, dependency-light way to shorten a document by keeping one sentence per paragraph, and understand that you are getting extraction, not comprehension, so a summary can still be unreadable. Steer away if you need abstractive output, language awareness, or a package with a current release and a declared licence, because the latest published version is 1.1.0 from 2015-03-31 and the licence is not identified in the project files. Before you depend on it, check whether your code loads it as an ES module or with require, since the package metadata declares type module while the README examples use require.

Frequently asked questions

What does the node-summary module actually do to a text?

It extracts the key sentence from each paragraph, and the summary is assembled from those original sentences rather than rewritten. Nothing is inferred or generated, so the output is an extraction, and the README describes the method as a naive summarization algorithm ported from a Python gist.

How do I install node-summary and call it?

Run npm install node-summary, then require the module and call summarize with a title and body of text, or summarizeFromUrl with a link. The URL path fetches the page with axios and cleans it with cheerio and html-to-text before summarizing.

Is node-summary still maintained?

The last push was on 2026-05-08, but the last published release is 1.1.0 from 2015-03-31, with 1.0.0 dating from 2013-12-17. The package manifest lists version 1.2.0, so there are unpushed-to-release changes in the tree and no recent tagged build.

What licence is node-summary released under?

The project files do not state a licence, and the repository has no LICENSE file among its top level entries. If you intend to use the module in a product, that question needs an answer from the author first.

Official sources

  1. Issues
  2. jbrooksuk/node-summary on GitHub
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/jbrooksuk-node-summary.svg)](https://hysenlabs.com/projects/jbrooksuk-node-summary)

Was this useful?