Library / SDK
jshemas/openGraphScraper avatar
jshemas/openGraphScraper

open-graph-scraper: Reading Social Metadata From a URL in Node

Node.js scraper service for Open Graph Info and More!

754 stars114 forksTypeScriptMIT

At a glance

What is it?
open-graph-scraper is a MIT licensed TypeScript module that fetches a page and returns its Open Graph, Twitter Card and JSON-LD metadata as a plain object, with custom meta tag extraction and typed results. It suits Node developers who want link previews without writing a parser.
Who is it for?
open-graph-scraper fits a Node service that needs link previews, a social card generator or a metadata audit, and that wants the result typed rather than assembled from regex matches. It is the wrong tool in a browser, because the module does not support browser usage and the project points you at a separate lite package for that case, and it is the wrong tool if you need to follow a page that only renders client-side.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 121 days ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

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

Editorial analysis

What the module actually returns

The module is described as a simple node module with TypeScript declarations for scraping Open Graph, Twitter Card and other metadata off a site. The call returns a promise resolving to four fields. The error flag returns true or false, true if there was an error, with the error itself inside the result object. The html field contains the HTML of the page, the result field contains all of the Open Graph results, and the response field contains the response from the Fetch API. That last one is worth noting because it gives you the status and headers, which is how you distinguish a page that has no Open Graph tags from a page that was never fetched successfully. The documentation asks you to check a success flag in the returned object, and says that if success is set to true the url input was valid, otherwise it will be set to false.

Installing it and making the first call

Installation is one npm command.

bash
npm install open-graph-scraper --save

The usage example is a require, an options object with a url, and a promise handler that destructures the four returned fields.

javascript
const ogs = require('open-graph-scraper');
const options = { url: 'http://ogp.me/' };
ogs(options)
  .then((data) => {
    const { error, html, result, response } = data;
    console.log('error:', error);  // This returns true or false. True if there was an error. The error itself is inside the result object.
    console.log('html:', html); // This contains the HTML of page
    console.log('result:', result); // This contains all of the Open Graph results
    console.log('response:', response); // This contains response from the Fetch API
  })

The result object for a page with Open Graph tags is flat and predictable, with ogTitle, ogType, ogUrl and ogDescription as strings, an ogImage array of objects holding height, type, url and width, plus charset and requestUrl fields and the success flag. The image being an array rather than a single value is the kind of detail that catches people out, since a page can and does declare more than one image.

The options that change what gets fetched

The options table is the practical part of the documentation. The url is the only required one, and html lets you pass a page you already have, used without options.url. fetchOptions passes options through to the Fetch API, and timeout sets the request timeout with a default of 10 seconds. blacklist takes an array of sites you do not want the scraper to run on, and onlyGetOpenGraphInfo stops the module from falling back on anything else, and also accepts an array of properties for which no fallback should be used. customMetaTags defines extra tags to scrape, jsonLDOptions sets the options used when parsing JSON-LD data, and urlValidatorSettings sets the options used by validator.js for testing the URL, with a link to the default settings in the source. The fallback behaviour is the option to understand first, because it is the difference between a strict Open Graph reader and one that will also dig for a title tag when the page has no og:title.

Custom meta tags, with the multiple flag

The customMetaTags option is for sites that publish metadata under names the module does not know about, and the shape of it is worth reading.

javascript
const ogs = require('open-graph-scraper');
const options = {
  url: 'https://github.com/jshemas/openGraphScraper',
  customMetaTags: [{
    multiple: false, // is there more than one of these tags on a page (normally this is false)
    property: 'hostname', // meta tag name/property attribute
    fieldName: 'hostnameMetaTag', // name of the result variable
  }],
};

Three fields per tag. The multiple flag says whether more than one of these tags exists on a page and is normally false, the property is the meta tag name or property attribute to look for, and the fieldName is the name of the result variable the value lands under. The last one is what makes the feature composable: because you name the output field yourself, several custom tags can be scraped in one call and each arrives under a key you chose.

Passing HTML you already have, and the browser caveat

There is a documented limitation that shapes where this can run. The module does not support browser usage at this time, and the project points you at open-graph-scraper-lite if you already have the HTML and cannot use Node's Fetch API. The same limitation is why the html option exists, since that is how you run the scraper over markup you fetched some other way, for example in a serverless function that received the page body. The example for that is the same call with the html property instead of a url.

javascript
const ogs = require('open-graph-scraper');
const options = {
  html: `<html><head>
  <link rel="icon" type="image/png" href="https://bar.com/foo.png" />
  <meta charset="utf-8" />
  <meta property="og:description" name="og:description" content="html description example" />

The underlying implementation uses the Fetch API for requests, and the documentation notes that most of Fetch's own options should work as the fetchOptions option here, which means the request behaviour is the platform's rather than the library's.

TypeScript consumers and the separate types entry point

The types are importable on their own, which matters when you want the result type without the runtime.

javascript
// example of how to get types
import type { SuccessResult } from 'open-graph-scraper/types';
const example: SuccessResult = {
  result: { ogTitle: 'this is a title' },
  error: false,
  response: {},
  html: '<html></html>'
}

The manifest confirms the arrangement. The package ships an exports map with a types entry, an import entry pointing at the ESM build and a require entry pointing at the CommonJS build, and a separate ./types subpath. The default import is ogs, and the import example shows the same promise handling as the require form. The SuccessResult type covers the success case, which is a small but useful distinction, since a failure resolves with a different shape rather than throwing.

The build, the test split and the dependency list

The package manifest describes the toolchain. The build produces both a CommonJS and an ESM bundle with separate tsc projects and out directories, plus a declaration build with its own tsconfig, and the build script clears the dist directory first. The tests are split into unit and integration suites, both run through ts-mocha recursively over the tests directory, with the integration suite given a 10 second timeout and the unit suite run under nyc for coverage. The continuous integration script runs eslint, then the build, then the declaration build, then the tests. The runtime dependencies are small and each has a job: cheerio for parsing the HTML, chardet and iconv-lite for character encoding detection and conversion, which is what stops a page in a non-UTF-8 charset from producing garbage, and undici for the fetch implementation. The engines field requires Node 20 or newer, and the prepare script runs snyk-protect before the build.

Editorial conclusion

open-graph-scraper fits a Node service that needs link previews, a social card generator or a metadata audit, and that wants the result typed rather than assembled from regex matches. It is the wrong tool in a browser, because the module does not support browser usage and the project points you at a separate lite package for that case, and it is the wrong tool if you need to follow a page that only renders client-side. Before you rely on it, check the success flag on every response rather than assuming a result object is populated, since a failed fetch still resolves.

Frequently asked questions

What does open-graph-scraper return?

A promise resolving to four fields: error, a boolean that is true when something went wrong with the error itself inside the result object, html containing the page HTML, result containing the Open Graph results, and response containing the Fetch API response. The result object also carries a success flag that says whether the url input was valid.

Can open-graph-scraper be used in a browser?

Not at the moment. The project states that open-graph-scraper does not support browser usage, and points you at open-graph-scraper-lite if you already have the HTML and cannot use Node's Fetch API. You can also pass an html string to the main module directly.

How do I scrape a meta tag the module does not know about?

Use the customMetaTags option, defining an object with multiple for whether more than one such tag exists, property for the meta tag name or property attribute, and fieldName for the name of the result variable the value is stored under.

What are the main options open-graph-scraper accepts?

url, which is required, html to scrape a page you already have, fetchOptions passed to the Fetch API, timeout with a 10 second default, blacklist of sites to skip, onlyGetOpenGraphInfo to stop the fallback to other metadata, customMetaTags, jsonLDOptions and urlValidatorSettings.

Which libraries does open-graph-scraper depend on?

cheerio for parsing the HTML, chardet and iconv-lite for character encoding detection and conversion, and undici for the fetch implementation. The package requires Node 20 or newer and ships both CommonJS and ESM builds with a separate types entry point.

Official sources

  1. Issues
  2. jshemas/openGraphScraper on GitHub
  3. License: MIT
  4. README
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/jshemas-opengraphscraper.svg)](https://hysenlabs.com/projects/jshemas-opengraphscraper)

Was this useful?