Documentation

Decision guide · 26 August 2026

Choose a link preview library by the job.

linkpeek is a focused choice for server-side preview cards with typed output and safe network defaults. Broader scraping, text-to-URL detection, rich oEmbed fetching, and provider-specific rules are different jobs with different good tools.

Start with the capability you need

PackageGood fitTradeoff versus linkpeek
linkpeekTyped URL previews on Node.js, Bun, Deno, and fetch-based edge runtimesDeliberately not a full article or provider-rule extraction framework
link-preview-jsPreviewing a URL or finding the first URL in textBroader input API; a different result shape and runtime focus
open-graph-scraperNode-oriented Open Graph scraping with broader scraper controlsLarger install tree; edge parse-only users may prefer its separate lite package
metascraperComposable, provider-specific metadata rulesMore setup and dependencies for a much broader extraction framework
unfurl.jsRich nested metadata and fetched oEmbed data in Node.jsArchived upstream as of this guide; not focused on a small edge-runtime preview path
url-metadataBroad page metadata in Node.jsBroader output and dependency surface than a preview-card utility

This is a fit comparison, not a universal ranking. Verify the linked dated evidence before using it in an architectural decision.

Normalize the result shape before migrating

The packages expose similar concepts through different keys. In the benchmarked APIs, title access commonly looks like this:

PackageTypical title accessFetch ownership
linkpeekresult.titlepreview() fetches; parseHTML() parses existing HTML
link-preview-jsresult.titleURL and content APIs
open-graph-scraperresponse.result.ogTitleMain package fetches
metascraperresult.titleYour application supplies HTML
unfurl.jsresult.open_graph?.titleunfurl() fetches
url-metadataresult["og:title"]Main API fetches

Compare the outbound-fetch boundary

For a public preview endpoint, the important question is not merely whether metadata parses: it is which layer validates an untrusted destination and every redirect before the next request.

PackageSecurity consideration as of 26 August 2026
linkpeekBlocks credential-bearing input, common secret headers, private/special-use IP literals, and redirect targets by default. Platform fetch still owns final DNS resolution, so infrastructure egress controls remain important.
link-preview-jsVersion 5.0.0 contains the fix for CVE-2026-43897, which affected versions through 4.0.0. Do not evaluate the current release using the fixed historical behavior.
open-graph-scraperThe main package owns the Node.js fetch path. If your application already has a controlled fetch boundary, compare the maintainers' separate parse-only open-graph-scraper-lite option.
metascraperThe application supplies HTML, so redirect validation, address policy, timeouts, byte limits, and credentials belong to the caller's fetch implementation.
unfurl.jsThe repository is archived; still-open PR #117 documents destination validation proposed after the last published release.
url-metadataThe Node-oriented API exposes request-filtering agent options. Review its current defaults and options against your threat model rather than assuming every runtime has the same network controls.

These are dated architectural notes, not security ratings. Every server-side URL fetcher also benefits from rate limiting, cache controls, and platform egress policy.

Map behavior, not just field names

npm install linkpeek

import { preview } from "linkpeek";

const result = await preview(url);

if (result.statusCode >= 400) {
	// Render a fallback and skip caching.
}

const card = {
	title: result.title,
	description: result.description,
	image: result.image,
	url: result.canonicalUrl,
};
  • HTTP error pages resolve with their metadata and statusCode; invalid input, blocked targets, timeouts, and network failures throw.
  • Private and special-use addresses are blocked by default. Keep that default for public input and review the documented DNS-resolution limit.
  • Discovered oEmbed endpoints are returned in oEmbedUrl but are not fetched.
  • The default preset scans the head with a 30 KB ceiling. Use presets.quality when body JSON-LD or body-image fallback is worth more work.
  • Keep preview fetching on the server; browser CORS and untrusted outbound requests make this a poor client-side boundary.

Check dated size, speed, and security notes

Same-corpus latency, package footprint, competitor versions, known runtime constraints, security sources, and reproduction commands live in the dated comparison notes; refresh that evidence before quoting it later.