GuidesSCRAPING APIS

Firecrawl alternatives for JavaScript

If you only need the HTML or readable text of public pages, you do not need Firecrawl credits: https://proxy.cors.dev/ plus DOMParser and Readability does it on the free cors.dev tier: no signup or key, GET and HEAD, about 600 requests a minute per IP, responses up to 6 MiB. Firecrawl is the right tool when pages need JavaScript rendering, crawling or anti-bot handling, and its free key gives 1,000 credits a month at 1 credit per page. On 28 October 2026 its /v2/scrape endpoint also answered a browser origin with no key at all, with CORS headers, under a daily per-IP cap.

What Firecrawl does that fetch does not

Firecrawl turns a URL into Markdown or structured data. Its docs say it handles JavaScript rendering, dynamic content, proxies, anti-bot measures and PDFs, and it also gives you whole-site crawl, URL mapping (map), search and LLM-based JSON extraction.

A plain browser fetch only gets the raw response bytes, assuming CORS doesn't block the request first. When you use Firecrawl, you're paying for the headless browser and proxy work on their servers.

Firecrawl's pricing page, checked 28 October 2026:

  • A free key gives you 1,000 credits a month with no card required, capped at 10 requests a minute on /scrape, /map and /search, 2 requests a minute on /crawl, and 2 concurrent browsers.
  • Paid plans run $19 a month for 5,000 credits (Hobby), $99 for 100,000 (Standard), $399 for 500,000 (Growth), and $749 for 1,000,000 (Scale).
  • Scrape, crawl and map cost 1 credit per page, and using the JSON format adds 4 credits per page.
  • A scrape that returns no result isn't charged, but a page that answers 403 or 404 still costs 1 credit.

Firecrawl from browser JavaScript

Call Firecrawl directly from browser code, no proxy needed. On 28 October 2026 a keyless POST https://api.firecrawl.dev/v2/scrape with Content-Type: application/json and {"url": ..., "formats": ["markdown"]} answered 200 with Access-Control-Allow-Origin: * in about 0.6 seconds. It returned 1,806 bytes of JSON for example.com and 16,058 bytes for news.ycombinator.com, with the Markdown in data.markdown.

Keyless requests are free and capped per IP address per day by a request count and a credit count that Firecrawl doesn't publish, returning 429 once you go over. Without a key, only search, scrape, parse and interact work, while crawl, map, extract and batch scrape require a key.

Firecrawl serves a cached copy when one is newer than maxAge, which defaults to 2 days (172,800,000 ms). Pass maxAge: 0 for a fresh scrape; cached results still cost 1 credit per page.

Call Firecrawl /v2/scrape from the browser, with or without a key
async function firecrawlMarkdown(pageUrl, apiKey) {
  const headers = { 'Content-Type': 'application/json' };
  if (apiKey) headers.Authorization = `Bearer ${apiKey}`;

  const res = await fetch('https://api.firecrawl.dev/v2/scrape', {
    method: 'POST',
    headers,
    body: JSON.stringify({ url: pageUrl, formats: ['markdown'] }),
  });

  const body = await res.json();
  if (!res.ok || !body.success) {
    throw new Error(`Firecrawl HTTP ${res.status}: ${body.error ?? 'scrape failed'}`);
  }
  return body.data.markdown;
}

const markdown = await firecrawlMarkdown('https://example.com/');

Firecrawl's preflight answers 204 and allows the Authorization and Content-Type headers, so browser code can also send an fc- key, which every visitor can then read in DevTools. Do not route Firecrawl through the free cors.dev proxy: it already sends CORS headers, and the free tier answers POST with 405 method_not_allowed and Authorization with 400 header_not_allowed.

Pick the tool by the job

The right tool depends on whether the target site sends its content in the initial HTML and whether you need site-wide crawling or anti-bot bypass.

Which tool for which scraping job, checked October 2026
JobToolCostLimit to know
Raw HTML of a public pageproxy.cors.devFree, no key6 MiB, about 600 requests a minute per IP
Title, links and meta tagsproxy.cors.dev plus DOMParserFree, no keyOnly what the server HTML contains
Readable article textproxy.cors.dev plus ReadabilityFree, no keyOnly what the server HTML contains
Markdown for an LLM promptJina Reader or Firecrawl without a keyFree20 a minute on Jina, a daily per-IP cap on Firecrawl
Pages built by JavaScriptFirecrawl with a free key1 credit per page1,000 credits a month
A whole siteFirecrawl crawl and map1 credit per pageKey required, 2 crawl requests a minute on the free key
Structured JSON from a pageFirecrawl JSON format5 credits per page200 pages a month on the free key
Sites behind bot protectionA scraping API with premium proxies10 to 25 credits a request on ZenRowsCompare free tiers first

If a page is server-rendered HTML and does not block plain requests, do not spend Firecrawl credits on it. Fetch the HTML through https://proxy.cors.dev/ and parse it with DOMParser and @mozilla/readability, or call Jina Reader directly for Markdown.

When a page builds its content with JavaScript or sits behind bot protection, a CORS proxy cannot help: it forwards the server's response as-is. That is where Firecrawl or another scraping API earns its credits; 9 free scraping API tiers are compared here.

Readable text with proxy.cors.dev and Readability

For articles, documentation and other server-rendered pages, fetch the raw HTML through the free cors.dev proxy and strip menus and footers in the browser. Readability (@mozilla/readability version 0.6.0, the library behind Firefox Reader View) loads in the browser as an ES module from esm.sh or jsDelivr, since both CDNs answer with Access-Control-Allow-Origin: *.

  1. Fetch the raw HTML

    prefix the public URL with https://proxy.cors.dev/. The free tier needs no signup or key and allows about 600 GET or HEAD requests a minute per IP, up to 20 redirects, and uncached responses up to 6 MiB (6,291,456 bytes) within a 30-second upstream deadline.

  2. Parse the HTML string

    pass the response text to the browser's built-in DOMParser to build a DOM document, then insert a <base> element with the page URL so relative links resolve to the original site.

  3. Run Readability

    pass the document to new Readability(doc).parse() to get back an object with the title, plain text content and cleaned HTML.

Extract the article from a public page with Readability
import { Readability } from 'https://esm.sh/@mozilla/readability@0.6.0';

async function readArticle(pageUrl) {
  const res = await fetch('https://proxy.cors.dev/' + pageUrl);
  if (!res.ok) {
    throw new Error(`HTTP ${res.status}: ${res.headers.get('X-Cors-Error') ?? 'upstream error'}`);
  }

  const doc = new DOMParser().parseFromString(await res.text(), 'text/html');
  const base = doc.createElement('base');
  base.href = pageUrl;
  doc.head.prepend(base);

  const article = new Readability(doc).parse();
  if (!article) throw new Error('No readable article found');
  return { title: article.title, text: article.textContent, html: article.content };
}

const article = await readArticle('https://en.wikipedia.org/wiki/Cross-origin_resource_sharing');
console.log(article.title, article.text.length);

On 28 October 2026 the English Wikipedia article on CORS came through proxy.cors.dev as 172,477 bytes of HTML, and Readability extracted 9,669 characters of article text from it. news.ycombinator.com came through as 34,286 bytes and example.com as 577 bytes.

Markdown from Jina Reader

If you specifically want Markdown rather than cleaned HTML or plain text, Jina Reader (GET https://r.jina.ai/TARGET) returns the page as Markdown text with Title:, URL Source: and Markdown Content: lines. Direct browser calls answer 200 with CORS headers, returning 1,465 bytes for example.com and 16,530 bytes for news.ycombinator.com.

Call r.jina.ai directly, not through proxy.cors.dev: through the proxy it answered 429 (Per IP rate limit exceeded), because proxy traffic shares IP addresses. Without a key Jina allows 20 requests a minute; a free key raises that to 500 and includes 10 million free tokens. Jina lists an average latency of 7.9 seconds.

Limits of the free route

Fetching through https://proxy.cors.dev/ and parsing in the browser costs nothing, but compared with a scraping API:

  • The free tier returns the HTML exactly as the server sends it, with no JavaScript rendering and no anti-bot bypass.
  • Only GET and HEAD requests are allowed, so POST answers 405 with X-Cors-Error: method_not_allowed.
  • Browser cookies are never forwarded to the target server.
  • Request headers Authorization and X-Api-Key are refused with 400 header_not_allowed, and other unsupported headers are dropped and listed in the X-Cors-Dropped-Headers response header.
  • API keys in the query string are forwarded as-is, and any key in browser code is visible to every visitor in DevTools. Keep production keys on a backend; browser keys fit internal tools, prototypes and bring-your-own-key apps.
  • Proxy errors carry an X-Cors-Error response header that your browser code can inspect.

Good questions.

Can I use Firecrawl from JavaScript without an API key?

Yes, POST https://api.firecrawl.dev/v2/scrape answers browser requests with Access-Control-Allow-Origin: * even without an API key. Keyless usage only supports search, scrape, parse and interact, and it's capped per IP per day by an unpublished request and credit count before returning 429. If you need crawl, map, extract or batch scrape, you'll have to pass a key.

Is Firecrawl free to use?

Signing up gives you a free key with 1,000 credits a month and no credit card required. Scrape, crawl and map cost 1 credit per page (including cached hits and pages that return 403 or 404), while JSON extraction adds 4 credits per page. The free tier is rate-limited to 10 requests a minute on /scrape, /map and /search, 2 a minute on /crawl, and 2 concurrent browsers.

How do I extract article text from a URL in the browser without a backend?

Fetch the target URL through https://proxy.cors.dev/, parse the returned HTML string with DOMParser, add a <base> tag with the original URL, and pass the document to @mozilla/readability. Readability strips the page chrome and returns the article's title, cleaned HTML and plain text content. If you want Markdown instead and can wait for a listed average latency of 7.9 seconds, call GET https://r.jina.ai/TARGET directly from the browser.

Does Mozilla Readability run in the browser without a bundler?

Yes, @mozilla/readability (version 0.6.0) loads directly in the browser as an ES module from CDNs like esm.sh or jsDelivr, both of which send Access-Control-Allow-Origin: *. You pair it with the browser's native DOMParser so there's nothing to install or bundle.

When should I pay for a scraping API instead of using a CORS proxy?

Use a scraping API when the target page renders its content with client-side JavaScript or sits behind anti-bot protection that blocks plain requests. A CORS proxy only forwards raw server HTML, whereas scraping APIs run headless browsers and residential or premium proxies (for example, ZenRows charges 5 credits with JavaScript rendering, 10 with premium proxies and 25 with both). You also need an API like Firecrawl if you want whole-site crawling, URL mapping or LLM-based JSON extraction.