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

duck-poacher

v0.7.1

Published

DuckDuckGo scraper for Node.js with web and image search.

Downloads

475

Readme

duck-poacher

A Node.js library for image and web search via DuckDuckGo. Image search returns image and thumbnail URLs for a query, with optional filters for size, color, type, and more; web search returns the title, URL, and description of each result.

It calls DuckDuckGo's search endpoints, which are not a public, versioned API. Response formats can change on DuckDuckGo's side and break the library.

Install

npm install duck-poacher

Requires Node.js 18 or newer. The package ships dual ESM/CJS, with both import and require entry points.

Usage

DuckDuckGo is the client. Construct one and call imageSearch — it returns a parsed ImageSearchResult[] (objects with imageUrl / thumbnailUrl, not a raw string) and manages the per-session vqd token for you, so there is no token to pass.

import { DuckDuckGo, type DdgSearchOptions, type ImageSearchResult } from 'duck-poacher';

const ddg = new DuckDuckGo();

const options: DdgSearchOptions = {
  size: 'Large',
  layout: 'Square',
  safeSearch: true,
};
const results: ImageSearchResult[] = await ddg.imageSearch('mountain landscape', options);

for (const result of results) {
  console.log(result.imageUrl, result.thumbnailUrl);
}

For web search, call webSearch — it returns a parsed WebSearchResult[] (objects with title / url / description) and manages the per-session search URL for you. It takes no options.

import { DuckDuckGo, type WebSearchResult } from 'duck-poacher';

const ddg = new DuckDuckGo();

const results: WebSearchResult[] = await ddg.webSearch('Node.js best practices');

for (const result of results) {
  console.log(result.title, result.url, result.description);
}

Each call makes two live requests (mint the token, then search). There is no built-in multi-query, dedupe, or cap.

API

| Export | Kind | Purpose | |--------|------|---------| | DuckDuckGo | class | The client: imageSearch(query, options?) and webSearch(query), token managed internally | | ImageSearchResult | class | Immutable value object { thumbnailUrl, imageUrl } | | WebSearchResult | class | Immutable value object { title, url, description } | | DdgSearchOptions | type | Filter options for imageSearch (image search only) | | DdgTime DdgSize DdgColor DdgType DdgLayout DdgLicense | type | String-union option values |

DuckDuckGo

  • imageSearch(query: string, options?: DdgSearchOptions): Promise<ImageSearchResult[]> — generates a per-session vqd token, runs the image search, and returns the parsed results. Throws Error('Unable to read token from DuckDuckGo response.') if the token cannot be scraped; a malformed response body throws.
  • webSearch(query: string): Promise<WebSearchResult[]> — scrapes a per-session signed search URL, runs the web search, and returns the parsed results. Throws Error('Unable to read search URL from DuckDuckGo response.') if the URL cannot be scraped; a malformed response body throws.

DdgSearchOptions

All fields are optional. safeSearch is a boolean; the rest are string unions:

| Option | Type | Values | |--------|------|--------| | time | DdgTime | Day Week Month | | size | DdgSize | Small Medium Large Wallpaper | | color | DdgColor | color Monochrome | | type | DdgType | photo clipart gif transparent line | | layout | DdgLayout | Square Tall Wide | | license | DdgLicense | Any Public | | safeSearch | boolean | safe search on / off |

Error handling

Errors are thrown rather than swallowed. Token generation throws if no vqd token (image search) or signed search URL (web search) can be read from the response. HTTP failures (status ≥ 400, network errors, timeouts) reject from the underlying request and propagate to the caller.

Contributing

See CONTRIBUTING.md for development setup and commands.

License

ISC © Lars Dreier