desearch-js
v1.3.1
Published
Desearch SDK for the Node.js
Readme
desearch.js
Official JavaScript and TypeScript SDK for the Desearch public API.
This repo publishes the npm package desearch-js. In the current source tree, the package version is 1.3.0.
Related docs:
- docs/features.md
- docs/architecture.md
- docs/known-issues.md
- docs/decisions/0001-thin-node-sdk-transport.md
Package purpose
desearch.js is a thin, Node-oriented SDK for the Desearch API. It wraps the public read-side endpoints implemented in src/index.ts behind one Desearch client class and ships a typed surface from src/types.ts.
What it covers today:
- AI multi-source search
- AI web-links search
- AI X-links search
- X search and lookup endpoints
- web search
- web crawl
What it does not try to be:
- a browser-first SDK
- a configurable transport layer
- a write or mutation client
- a framework with retries, pagination helpers, or runtime validation
Quick Start
Install
npm install desearch-jsESM usage
import Desearch from 'desearch-js';
const client = new Desearch(process.env.DESEARCH_API_KEY!);
const result = await client.aiSearch({
prompt: 'latest Bittensor developments',
tools: ['web', 'twitter', 'reddit'],
date_filter: 'PAST_24_HOURS',
result_type: 'LINKS_WITH_FINAL_SUMMARY',
count: 10,
});
console.log(result);CommonJS usage
const Desearch = require('desearch-js').default;
const client = new Desearch(process.env.DESEARCH_API_KEY);Authentication
The constructor accepts a single argument, your API key:
const client = new Desearch('your-api-key');The SDK sends that value as the Authorization header on every request.
API overview
AI search methods
aiSearch(payload)→POST /desearch/ai/searchaiWebLinksSearch(payload)→POST /desearch/ai/search/links/webaiXLinksSearch(payload)→POST /desearch/ai/search/links/twitter
X methods
xSearch(params)→GET /twitterxPostsByUrls(params)→GET /twitter/urlsxPostById(params)→GET /twitter/postxPostsByUser(params)→GET /twitter/post/userxPostRetweeters(params)→GET /twitter/post/retweetersxUserPosts(params)→GET /twitter/user/postsxUserReplies(params)→GET /twitter/repliesxPostReplies(params)→GET /twitter/replies/postxTrends(params)→GET /twitter/trends
Web methods
webSearch(params)→GET /webwebCrawl(params)→GET /web/crawl
Usage examples
AI search
const result = await client.aiSearch({
prompt: 'recent AI chip announcements',
tools: ['web', 'hackernews', 'reddit', 'twitter'],
result_type: 'LINKS_WITH_FINAL_SUMMARY',
count: 20,
});Notes:
toolsaccepts the source names defined insrc/types.ts:web,hackernews,reddit,wikipedia,youtube,twitter,arxivaiSearchalways sendsstreaming: false, even if a caller tries to add astreamingfield manually
AI web links search
const links = await client.aiWebLinksSearch({
prompt: 'open source browser automation tools',
tools: ['web', 'hackernews', 'reddit', 'youtube'],
count: 20,
});AI X links search
const xLinks = await client.aiXLinksSearch({
prompt: 'Bittensor subnet updates',
count: 20,
});X search
const tweets = await client.xSearch({
query: 'bittensor',
sort: 'Top',
lang: 'en',
min_likes: 50,
count: 20,
});X posts by URL
const tweets = await client.xPostsByUrls({
urls: ['https://x.com/DesearchAI/status/1234567890123456789'],
});Web search
const results = await client.webSearch({
query: 'site:desearch.ai sdk docs',
start: 0,
});Web crawl
const page = await client.webCrawl({
url: 'https://desearch.ai',
format: 'text',
});Optional response cost metadata
SDK methods return the same raw payload shape by default:
const results = await client.webSearch({ query: 'desearch sdk' });
console.log(results.data);If you want per-request cost visibility, pass { includeMetadata: true } as the second argument. The SDK reads metadata from the same API response headers; it does not make an extra billing or pricing request.
const response = await client.webSearch(
{ query: 'desearch sdk' },
{ includeMetadata: true },
);
console.log(response.data);
console.log(response.metadata.costUsd);
console.log(response.metadata.usageCount);
console.log(response.metadata.service);
console.log(response.metadata.currency);The metadata wrapper works for JSON object, JSON array, and text endpoints such as webCrawl(). Missing or malformed metadata headers are ignored, so successful API calls still resolve normally.
Tech stack
- TypeScript
^5.9.3 undici>=5for HTTP transportdotenv^17.3.1as a runtime dependency inpackage.jsontsup^8.5.1for bundlingvitest^4.0.18for teststypedoc^0.28.17typedoc-plugin-markdown^4.10.0- output targets: CommonJS, ESM, and bundled declaration files
Commands
| Command | Purpose |
| --- | --- |
| npm run build | Build dist/ with tsup using the config in tsup.config.ts |
| npm run build-fast | Build src/index.ts directly into CJS and ESM without the full default tsup command |
| npm test | Run the Vitest test suite |
| npm run generate-docs | Generate markdown API docs from src/index.ts using TypeDoc |
| npm run build:beta | Build for beta publishing |
| npm run version:beta | Bump a beta prerelease version |
| npm run version:stable | Bump a stable patch version |
| npm run publish:beta | Version, build, and publish with the beta npm tag |
| npm run publish:stable | Version, build, and publish as the default release |
| npm run prepublishOnly | Automatic npm hook that runs npm run build before publish |
Architecture overview
Source layout:
src/index.ts, theDesearchclient plus the sharedhandleRequest<T>()transport helpersrc/types.ts, request/response contracts and X entity modelstsup.config.ts, build output configurationpackage.json, scripts, exports, dependency versions, and package metadata
Key design decisions in the current source:
- one shared request helper powers every public method
- GET payloads are serialized through
URLSearchParams - POST payloads are serialized as JSON
- response parsing switches between JSON and text based on
content-type - default calls return the parsed payload directly, preserving the existing SDK response shape
- callers can opt into
{ data, metadata }wrappers with{ includeMetadata: true } webCrawl()returns text while most other methods return JSON-shaped data- the base URL is fixed to
https://api.desearch.ai aiSearch()forcibly disables streaming
See docs/architecture.md for the detailed flow and ADR 0001 for the reasoning behind the current transport design.
Error handling
HTTP failures are thrown as plain Error instances in this format:
HTTP <status>: <response body>Non-HTTP failures are wrapped as:
Unexpected Error: <message>Example:
try {
await client.webSearch({ query: 'desearch' });
} catch (error) {
console.error(error);
}Package outputs
package.json exports:
./dist/index.jsfor CommonJS./dist/index.mjsfor ESM./dist/index.d.tsfor TypeScript declarations
Known limitations
Current limitations include:
- no configurable base URL
- no timeout, retry, or abort controls in the public API
aiSearchalways disables streaming- runtime failures surface as plain
Errorstrings rather than typed SDK errors
Full details: docs/known-issues.md
