Free tools Windows power users keep installed
One-click scans. No signup required.
Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
Use a TypeScript SDK by installing the provider’s package, keeping its credential on your server, making one simple request, inspecting both API and target-page status, and only then adding JavaScript rendering, parsing, retries, or asynchronous jobs. SDKs are provider-specific wrappers: method names, tokens, defaults, response formats, and billing differ. Start with the current reference for the service you selected, then adapt the workflow below.
What a TypeScript scraping SDK actually does
A scraping SDK is a typed (or JavaScript-compatible) client for a hosted HTTP API. It usually handles URL encoding, authentication headers, request construction, and response decoding. It does not make providers interchangeable. A Scrapfly client and a Crawlbase client expose different classes, options, token models, and result objects.
Before choosing a package, define the job:
- one static HTML page;
- a JavaScript-rendered or lazy-loaded page;
- structured fields from a supported site;
- many URLs, a crawl, or a callback-based workflow;
- raw HTML, text, JSON, Markdown, a screenshot, or a PDF.
Compare the provider’s runtime support, package maintenance, authentication, rendering controls, output format, error visibility, concurrency and batch features, pricing, privacy terms, and the target site’s applicable rules. Vendor documentation is the authority for current names and limits.
For examples in this guide, the official Scrapfly TypeScript/JavaScript SDK repository and Crawlbase Node.js SDK documentation are used as provider-specific illustrations. They were not independently tested here; verify the installed version before deploying.
#1 Best Overall
Install the SDK and confirm your runtime
Crawlbase
Crawlbase documents a Node.js SDK for Node.js 16 or later, with both ESM and CommonJS usage. Install the package in your server project:
npm install crawlbase
Use the provider’s current versioned quickstart if your project uses a different module system or package manager.
Scrapfly
Scrapfly lists distribution through npm, JSR, and Deno. Its repository uses the package name scrapfly-sdk:
Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Repair Windows errors before they cause bigger problems3Scan for outdated or missing drivers - takes under a minutenpm install scrapfly-sdk
Check the repository for the current package version, TypeScript compiler settings, and supported runtimes before copying an import.
Keep the package server-side
Do not put a paid scraping key in browser-delivered JavaScript, a mobile bundle, a public repository, or client-visible URL parameters. Load it from server-side environment configuration or a secrets manager, and avoid logging it. Rotate a key that has been committed or exposed.
Make the smallest possible request first
First establish that authentication, DNS, network access, and the provider account work. Use one harmless URL and print the response shape before writing a parser.
Crawlbase: static request
import { CrawlingAPI } from 'crawlbase';
const token = process.env.CRAWLBASE_TOKEN;
if (!token) throw new Error('Set CRAWLBASE_TOKEN on the server');
const api = new CrawlingAPI({ token });
const response = await api.get('https://example.com');
console.log('API status:', response.statusCode);
console.log('Target status:', response.headers?.cb_status);
console.log('Body length:', response.body?.length ?? 0);
if (response.statusCode === 200 && response.headers?.cb_status === '200') {
console.log(response.body);
}
The documented quickstart reads statusCode and body. The additional cb_status check matters because Crawlbase documents a case where the API returns HTTP 200 while the target body is empty and its target status is non-200.
Scrapfly: client and configuration
import { ScrapflyClient, ScrapeConfig } from 'scrapfly-sdk';
const key = process.env.SCRAPFLY_KEY;
if (!key) throw new Error('Set SCRAPFLY_KEY on the server');
const client = new ScrapflyClient({ key });
const response = await client.scrape(
new ScrapeConfig({
url: 'https://example.com',
render_js: true,
}),
);
console.log(response.result.content);
The repository example also shows a country option and an anti-bot option named unblocker; it says asp is a deprecated alias that continues to work. Confirm these names against the package version you install rather than assuming every provider accepts them.
Authenticate without leaking credentials
- Create the key or token in the provider dashboard.
- Store it in a server environment variable such as
CRAWLBASE_TOKENorSCRAPFLY_KEY, or in your deployment platform’s secret store. - Read it when the server process starts or when constructing a client.
- Redact authorization headers, query strings, and SDK error objects in logs.
- Use separate development and production credentials and rotate them periodically.
Crawlbase documents two token types: a Normal Token for static HTML and JSON endpoints, and a JavaScript Token for SPAs, client-rendered content, and lazy-loaded pages. Those names and behaviors are Crawlbase-specific, not a general SDK convention.
Choose static fetching or JavaScript rendering
Start static
A static request is generally the simplest and may be faster or consume fewer resources, depending on the service. Inspect the returned HTML. If the data is present in the source, parse it without a browser.
Render only when the page needs it
Use rendering when the initial HTML is an app shell, content appears only after client-side JavaScript runs, or lazy-loaded sections require scrolling or interaction. Scrapfly demonstrates render_js: true. Crawlbase requires its JavaScript Token for options such as page_wait, ajax_wait, scroll, and css_click_selector.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Do not make a fixed delay your universal solution. Prefer a documented wait-for-selector, network-idle, or provider-specific condition when available, and confirm the additional cost and time for rendered requests. A JavaScript token should be promoted only after a normal response is empty, incomplete, or blocked.
Rank #3
Parse and validate the returned content
Determine whether the SDK returns raw HTML, text, JSON, Markdown, a job object, or a wrapper containing one of those. Then choose a parser appropriate to the format. For HTML, a server-side parser such as Cheerio can select elements; for JSON, validate the schema before using fields.
import * as cheerio from 'cheerio';
function readTitle(html: string): string {
const $ = cheerio.load(html);
const title = $('title').first().text().trim();
if (!title) throw new Error('Required title is missing');
return title;
}
const title = readTitle(response.body);
console.log({ title });
Selectors are an implementation detail of the target page, not a guarantee from the SDK. Check required fields, tolerate optional fields, and send a clear validation error to your queue or monitoring system when the page structure changes. Crawlbase documents built-in scrapers for supported sites; use one only when it supplies the fields and coverage you need. Scrapfly’s example exposes both raw content and selector-based access.
Handle API status and target status separately
There are at least two failure layers:
- Transport or API failure: authentication, quota, malformed parameters, provider outage, or an HTTP error returned by the API.
- Target failure: the destination returned a block page, timeout, empty body, redirect problem, or another non-success result.
Never treat an SDK call that resolved, or an API HTTP 200, as proof that the target was retrieved. Branch on every provider-documented target-status field. In Crawlbase, inspect both response.statusCode and response.headers.cb_status. Other services expose different fields.
Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallfunction isRetryable(status: number): boolean {
return status === 408 || status === 429 || status >= 500;
}
async function withBackoff<T>(work: () => Promise<T>, attempts = 3): Promise<T> {
let lastError: unknown;
for (let n = 0; n < attempts; n++) {
try {
return await work();
} catch (error) {
lastError = error;
if (n === attempts - 1) break;
const delay = Math.min(8000, 500 * 2 ** n) + Math.floor(Math.random() * 250);
await new Promise(resolve => setTimeout(resolve, delay));
}
}
throw lastError;
}
Use bounded exponential backoff with jitter for documented transient failures. Do not blindly retry every 4xx response: a bad key, invalid URL, forbidden option, or exhausted account limit will not be fixed by repetition. Respect provider retry-after headers and account quotas when available. Log a request identifier, status fields, duration, URL hostname, and failure category, but not secrets.
Move recurring work to asynchronous jobs
For a few pages, a synchronous request is easy to reason about. For slow targets, large batches, or recurring crawls, investigate the provider’s async or crawl-job interface. Crawlbase documents an asynchronous request that returns a request ID and callback delivery, and recommends async processing for sustained high-volume submission.
- Submit a job with the smallest set of required options.
- Persist the provider request ID with your own job record.
- Accept callbacks at an authenticated HTTPS endpoint, or poll only at the documented interval.
- Make callback handling idempotent: the same delivery must not create duplicate records.
- Validate the received target status and payload before marking the job complete.
- Record terminal failures and provide a replay path for jobs that failed transiently.
Reuse a client instance when the provider recommends it rather than constructing one for every URL. Check current concurrency, callback, timeout, and quota limits for your account plan. Do not infer comparative speed or capacity from SDK documentation alone.
Batching, concurrency, and cost controls
- Start with a low concurrency limit and increase only after observing provider quotas, target politeness, memory use, and error rates.
- Use static fetching by default and reserve browser rendering for URLs that require it.
- Cache content when freshness permits, with an explicit TTL and an invalidation rule.
- Separate retries from new work so a failing target cannot starve the queue.
- Track requests by outcome: API error, target error, empty content, validation failure, and success.
- Check whether billing counts attempts, rendered requests, bandwidth, tokens, or successful targets; this is provider-specific.
For legal and operational safety, confirm that your collection is permitted by the target’s terms, applicable law, robots directives where relevant, and your intended use. An SDK simplifies HTTP calls; it does not grant permission to collect data.
Common problems and precise fixes
“Authentication failed” or unauthorized responses
Check that the environment variable exists in the running server process, the key belongs to the correct account, and the SDK initialization property matches the provider’s current reference. Rotate a key that was exposed. Do not print the key while debugging.
The request succeeds but the body is empty
Inspect the target-status field, not just API HTTP status. For Crawlbase, check cb_status. If the page is client-rendered, try the documented JavaScript Token and wait or interaction options. Also verify redirects, consent walls, bot challenges, and the requested URL.
Content appears only after scrolling or clicking
Use the provider’s documented scroll or CSS-click option and the required rendering credential. A fixed sleep may finish before the content is available; wait for a meaningful selector when supported.
TypeScript cannot resolve the import
Confirm the installed package name, module system, Node version, and the provider’s current ESM/CommonJS example. Scrapfly lists npm, JSR, and Deno distributions; Crawlbase documents ESM and CommonJS. These are package-specific choices.
The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Retries make the outage worse
Limit attempts, add exponential backoff and jitter, honor retry-after guidance, and stop retrying deterministic client errors. Place a circuit breaker or queue pause around repeated provider failures.
Best Value
Parsing breaks after a site redesign
Validate required fields, keep selectors centralized, store a small diagnostic sample where permitted, and alert on sudden missing-field rates. Do not silently publish partially parsed records.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Or skip the browser setup
If your task is to obtain a clean visual capture rather than parse page data, ScreenshotNeo provides a website screenshot API and MCP server. One GET request returns PNG, JPEG, WebP, or PDF. Its cleanup step accepts cookie or consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each cleanup step can be disabled. Only clean shots are billed: bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and the response identifies the outcome with X-Page-Verdict and X-Billed headers.
Use the API directly from your server. Full option names and authentication details are in the ScreenshotNeo documentation.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
ScreenshotNeo also supports full-page captures with lazy images loaded, CSS-selector element captures, dark mode, 12 device presets plus custom viewports, retina scale, PDF paper and page options, HTML/CSS-to-image, custom JavaScript and CSS, clicks, waits, request and resource blocking, headers, cookies, user agents, authorization, timezone, geolocation, transparent backgrounds, resizing, configurable cache TTLs, signed image links, asynchronous jobs with signed webhooks, bulk capture of up to 100 URLs per call, a usage API, an OpenAPI specification, and parameter names used by other screenshot APIs.
An MCP server exposes take_screenshot, get_page_info, and capture_pdf to Claude, Cursor, and other MCP clients. Plans include 1,000 shots per month free with no card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account to begin.
Provider-specific comparison
| Concern | Scrapfly | Crawlbase | What to verify |
|---|---|---|---|
| Distribution | npm, JSR, and Deno are listed | Node package; ESM and CommonJS documented | Current package version and runtime support |
| Authentication | Client initialized with a key | Normal Token and JavaScript Token | Credential type required for each option |
| Rendering | render_js shown in example |
JavaScript Token with waits, scroll, and CSS click options | Cost, limits, and current option names |
| Result shape | Result content and selector helper shown | Status, body, headers, and target status | Target verdict and error fields |
| Async work | Verify current job features in its docs | Async request ID and callback documented | Concurrency, callback security, and quotas |
Scrapeless is another named option whose official SDK overview lists JavaScript/Node.js tooling. Use its language guide to verify TypeScript support and method details before writing an integration.
Frequently Asked Questions
Can I use a TypeScript SDK in a browser app?
Use it from a trusted server or server-side function. A browser bundle would expose the paid scraping credential.
Recommended Free Tools
Should every scrape use a headless browser?
No. Start with a static request and enable the provider’s documented rendering mode only when the target content requires JavaScript, scrolling, or interaction.
Why is an API 200 response not enough?
The provider may have accepted your request while the target returned a block, timeout, or empty body. Inspect the provider-specific target status as well as the API status.
What should I verify before production?
Confirm package and runtime versions, current option names, quotas, billing, retry guidance, callback security, data handling, and whether collection from the target is permitted.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

