article-extractor is a free, open source data extraction & web scraping project written in TypeScript and released under MIT. It has 1,913 GitHub stars, 158 forks and 0 open issues, and was last pushed 29 days ago. On this registry it ranks #37 of 45 tracked projects in Data Extraction & Web Scraping, with 5 head-to-head comparisons available. It gained 2 stars over the last 3 tracked days.

What is article-extractor?

What it is

article-extractor is a TypeScript library that extracts the main article, the main image, and metadata from a URL. It is published as @extractus/article-extractor and distributed through JSR and npm, so it lives in the JavaScript and TypeScript package ecosystem.

The concrete problem it solves is extracting the main article, the main image, and metadata from a URL. A caller can pass a URL or raw HTML to extract() and receive fields such as title, description, image, author, publication date, source, content, links, and estimated reading time.

Key capabilities

  • The library extracts article data from a URL or raw HTML through extract() and extractFromHtml().
  • It returns an ArticleData object with fields for url, links, title, description, image, favicon, author, content, source, published, ttr, and type.
  • It lets callers tune extraction with parserOptions, including wordsPerMinute, descriptionTruncateLen, descriptionLengthThreshold, contentLengthThreshold, allowedTags, allowedAttributes, and allowedIframeDomains.
  • It supports content sanitization by limiting which HTML tags, attributes, and iframe domains remain in the extracted article content.
  • It accepts a custom fetcher so callers can control HTTP behavior for proxies, headers, TLS, authentication, and timeouts.
  • It provides transformation APIs, including addTransformations() and removeTransformations(), with a documented priority order.

Who uses it and how

  • JavaScript and TypeScript developers add the package to Deno, Node.js, or Bun projects to extract article data inside application code.
  • Data extraction workflows call extract() with a page URL and use the returned fields as structured article data.
  • Workflows that already have HTML can pass it to extractFromHtml() instead of fetching inside the library.
  • Server-side scripts that need special network behavior pass a custom fetcher, such as a proxy client or a fetch function with authentication headers.
  • Content pipelines can adjust thresholds and allowed tags to fit different article sources and output requirements.

Getting started

Install the package with deno add jsr:@extractus/article-extractor for Deno, or with pnpm add jsr:@extractus/article-extractor, npx jsr add @extractus/article-extractor, bunx jsr add @extractus/article-extractor, npm install @extractus/article-extractor, or bun add @extractus/article-extractor for Node.js and Bun. Then import extract and call it with a URL, for example const data = await extract("https://example.com/article");.

When to use it — and when not to

It fits when a TypeScript or JavaScript application needs an MIT-licensed library to extract article content and metadata from URLs or HTML. It is unsuitable when a hosted deployment or complete platform is required, because the README documents package installation and library APIs, not hosted deployment, database operations, storage, SMTP, or scaling. It also requires caller handling when no article is found, since extract() can return null, and network behavior must be configured through a custom fetcher when proxies, authentication, or timeouts are needed.

project readme (upstream, from github) — read inline

@extractus/article-extractor

Extract main article, main image and meta data from URL.

JSR npm version CI test

Install

Deno

deno add jsr:@extractus/article-extractor

Node.js / Bun

pnpm add jsr:@extractus/article-extractor
# or
npx jsr add @extractus/article-extractor
# or
bunx jsr add @extractus/article-extractor

Alternatively, install from npm:

npm install @extractus/article-extractor
# or
bun add @extractus/article-extractor

Usage

import { extract } from "jsr:@extractus/article-extractor";

const data = await extract("https://example.com/article");
console.log(data);

APIs


extract()

Load and extract article data from a URL or HTML string.

Syntax
extract(input: string): Promise<ArticleData | null>
extract(input: string, parserOptions?: ParserOptions): Promise<ArticleData | null>
extract(input: string, parserOptions?: ParserOptions, fetcher?: Fetcher): Promise<ArticleData | null>

Example:

import { extract } from "jsr:@extractus/article-extractor";

try {
  const article = await extract("https://example.com/some-article");
  console.log(article);
} catch (err) {
  console.error(err);
}

The result can be null (when no article found) or an ArticleData object:

interface ArticleData {
  url?: string;           // best resolved URL
  links?: string[];       // alternative URLs (canonical, shortlink, amphtml)
  title?: string;         // article title
  description?: string;   // short description / excerpt
  image?: string;         // main image URL
  favicon?: string;       // site favicon URL
  author?: string;        // author name
  content?: string;       // extracted article HTML
  source?: string;        // original publisher domain
  published?: string;     // publication date string
  ttr?: number;           // estimated time to read (seconds), 0 = unknown
  type?: string;          // page type (e.g. "article")
}
Parameters
input required

URL string or raw HTML content.

parserOptions optional
Property Type Default Description
wordsPerMinute number 300 Words per minute for time-to-read estimation
descriptionTruncateLen number 210 Max characters for generated description
descriptionLengthThreshold number 180 Min characters to keep meta description
contentLengthThreshold number 200 Min characters for article content
allowedTags string[] (semantic/content tags) HTML tags to keep in output
allowedAttributes Record (src, href, alt, etc.) Per-tag attributes to keep
allowedIframeDomains string[] (youtube, vimeo, etc.) Allowed domains for iframe src
const article = await extract(url, {
  descriptionLengthThreshold: 120,
  contentLengthThreshold: 500,
});
fetcher optional

A custom fetch function with the signature (url: string) => Promise. Use this to customize HTTP behavior: proxy, headers, TLS, authentication, timeouts, etc.

Defaults to globalThis.fetch.

Deno (with proxy):

import { extract } from "@extractus/article-extractor";

const client = Deno.createHttpClient({
  proxy: { url: "http://proxy.example.com:8080" },
});
const myFetcher = (url: string) => fetch(url, { client });

const result = await extract("https://example.com/some-article", {}, myFetcher);

Node.js (with proxy via undici):

import { extract } from "@extractus/article-extractor";
import { fetch, ProxyAgent } from "undici";

const dispatcher = new ProxyAgent("http://proxy.example.com:8080");
const myFetcher = (url: string) => fetch(url, { dispatcher });

const result = await extract("https://example.com/some-article", {}, myFetcher);

Bun (with proxy):

import { extract } from "@extractus/article-extractor";

const myFetcher = (url: string) =>
  fetch(url, {
    proxy: "http://proxy.example.com:8080",
  });

const result = await extract("https://example.com/some-article", {}, myFetcher);

Custom headers:

const myFetcher = (url: string) =>
  fetch(url, {
    headers: {
      "user-agent": "MyBot/1.0",
      authorization: "Bearer token123",
    },
  });

const result = await extract("https://example.com/some-article", {}, myFetcher);

Request timeout:

const myFetcher = (url: string) =>
  fetch(url, {
    signal: AbortSignal.timeout(5000),
  });

const result = await extract("https://example.com/some-article", {}, myFetcher);

extractFromHtml()

Extract article data from an HTML string directly.

Syntax
extractFromHtml(html: string): Promise<ArticleData | null>
extractFromHtml(html: string, url?: string): Promise<ArticleData | null>
extractFromHtml(html: string, url?: string, parserOptions?: ParserOptions): Promise<ArticleData | null>

Example:

import { extractFromHtml } from "jsr:@extractus/article-extractor";

const res = await fetch(url);
const html = await res.text();

const article = await extractFromHtml(html, url);
Parameters
html required

HTML string containing the article.

url optional

Source URL for resolving relative links.

parserOptions optional

See parserOptions above.


Transformations

Sometimes the default extraction algorithm may not work well. Transformations let you add pre/post processing per-site.

  • addTransformations(transformation: Transformation | Transformation[]): number
  • removeTransformations(patterns?: RegExp[]): number
Transformation object
interface Transformation {
  patterns: RegExp[];                        // URL patterns to match
  pre?: (document: Document) => Document;    // pre-process raw HTML
  post?: (document: Document) => Document;   // post-process extracted article
}

For URLs matching patterns, run pre on raw HTML, extract article, then run post on the result.

extraction process

Example:

import { addTransformations } from "jsr:@extractus/article-extractor";

addTransformations({
  patterns: [/([\w]+.)?domain\.tld\/*/],
  pre: (document) => {
    document.querySelectorAll(".advertise-area").forEach((el) => {
      el.parentNode?.removeChild(el);
    });
    return document;
  },
  post: (document) => {
    document.querySelectorAll("h4").forEach((el) => {
      const h2 = document.createElement("h2");
      h2.innerHTML = el.innerHTML;
      el.parentNode?.replaceChild(h2, el);
    });
    return document;
  },
});

To write better transformations, refer to linkedom and the Document API.

addTransformations(transformation | Transformation[])

Add a single or multiple transformations. Transformations without patterns are ignored.

import { addTransformations } from "jsr:@extractus/article-extractor";

addTransformations([
  {
    patterns: [/([\w]+.)?abc\.tld\/*/],
    pre: (doc) => { /* ... */ return doc; },
    post: (doc) => { /* ... */ return doc; },
  },
  {
    patterns: [/([\w]+.)?xyz\.tld\/*/],
    post: (doc) => { /* ... */ return doc; },
  },
]);
removeTransformations(patterns?: RegExp[])

Remove transformations matching the given patterns. Call without arguments to remove all.

import { removeTransformations } from "jsr:@extractus/article-extractor";

removeTransformations([
  /([\w]+.)?abc\.tld\/*/,
  /([\w]+.)?xyz\.tld\/*/,
]);
Priority order

When multiple transformations match, they all execute in order.

Given two transformations matching goo.gl:

pre_one -> pre_three -> extraction -> post_two -> post_four

Content sanitization options

Extracted HTML is sanitized using a built-in DOM tree walker. Disallowed tags are removed (not escaped), and disallowed attributes are stripped. Configure via parserOptions:

import { extract } from "jsr:@extractus/article-extractor";

// allow class attributes on <code> and 
const article = await ext

readme truncated — read the full docs on github

Frequently asked questions

Is article-extractor free to use?

article-extractor is open source under the MIT licence. There is no licence fee and no seat count — you can self-host it or, where the project offers one, pay a vendor for a managed version instead.

What does article-extractor do?

To extract article from given URL

What is article-extractor written in?

article-extractor is primarily written in TypeScript. Its source is publicly available at https://github.com/extractus/article-extractor, and it has 1,913 GitHub stars.