# got-scraping, a browser-like HTTP client that Apify has retired

> apify/got-scraping extends the got HTTP client with generated browser headers, proxy support and HTTP/2 negotiation so requests blend in with ordinary traffic. The repository now carries an end-of-life notice pointing new projects at impit, which makes this a library to migrate away from rather than to start with.

**apify/got-scraping** — HTTP client made for scraping based on got.

- Repository: https://github.com/apify/got-scraping
- Stars: 775 · Forks: 63
- Language: TypeScript
- License: not declared
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/apify-got-scraping

## The end-of-life notice comes before the documentation

The first thing in the README is a notice that got-scraping is end of life. After many years of development the maintainers decided to deprecate the package, and it will no longer receive updates or support.

The recommendation that follows is specific: for new projects use impit, described as a modern, powerful and flexible HTTP client with a fetch API based on Rust's reqwest library, providing a similar feature set including browser-like request headers and proxy support and more.

That changes how to read the rest of this repository. The documentation is not a specification for something current, it is a description of what a maintained-for-years library did, and the practical questions for an engineering team are different from the usual ones. The first is whether existing code still works, and the second is what migrating to impit will cost. The repository answers the first question and gestures at the second.

The release history shows the maintenance record. Version 4.1.3 came in December 2025, then 4.2.0 and 4.2.1 both in February 2026, and the last push was on 2026-10-21. The package.json carries version 4.2.2 with the repository still receiving occasional commits, so the end-of-life state appears to be a decision about support rather than a sudden freeze.

The licence field on the repository says it is unknown, which is worth resolving before you keep shipping it inside a commercial product.

## What the extension actually adds over plain got

got-scraping is a small extension to the got HTTP client whose purpose is sending browser-like requests out of the box, which the README argues is essential in web scraping to blend in with website traffic.

The mechanics are built on got's own instance extension mechanism, so every feature of got is available and the added behaviour is configuration rather than a different API shape. The basic call is unchanged:

```javascript
import { gotScraping } from 'got-scraping';

gotScraping
    .get('https://apify.com')
    .then( ({ body }) => console.log(body));
```

The first addition is header generation. The useHeaderGenerator option is a boolean defaulting to true, and when it is on, headers are generated for you so that a request looks like it came from a browser rather than a bare HTTP client. The generation is controlled by headerGeneratorOptions, which follows the HeaderGeneratorOptions shape from Apify's fingerprint suite, and the README shows it narrowing browsers by name and version range, devices, locales and operating systems:

```javascript
const response = await gotScraping({
    url: 'https://api.apify.com/v2/browser-info',
    headerGeneratorOptions:{
        browsers: [
            {
                name: 'chrome',
                minVersion: 87,
                maxVersion: 89
            }
        ],
        devices: ['desktop'],
        locales: ['de-DE', 'en-US'],
        operatingSystems: ['windows', 'linux'],
    }
});
```

The second addition is proxy support, where the proxyUrl option takes an HTTP or HTTPS URL and HTTP/2 proxies are supported:

```javascript
gotScraping
    .get({
        url: 'https://apify.com',
        proxyUrl: 'http://usernamed:password@myproxy.com:1234',
    })
    .then(({ body }) => console.log(body));
```

The third is the sessionToken option, which deserves attention because it is easy to miss. It takes a non-primitive unique object describing the current session, and by default it is undefined, which means new headers are generated every time. Headers generated with the same sessionToken never change, so passing a stable object gives you a consistent browser identity across a sequence of requests, which is what makes a session look like a session.

## Proxy protocol detection, ALPN and header casing

The under-the-hood section explains the parts that matter when a request fails in a way that looks like a network problem.

On proxies, the package automatically detects which HTTP protocol the proxy server supports, and after the connection is established it performs another ALPN negotiation for the end server. The reason for matching the browser's protocol is stated plainly: most modern browsers use HTTP/2, and using the same version matters for sites that behave differently depending on it.

On header formatting, HTTP/1.1 headers are always automatically formatted in Pascal-Case, with one exception the README calls out, since x- headers are not modified in any way.

Two parsing and TLS details follow. By default the package uses an insecure HTTP parser, which allows access to websites with non-spec-compliant web servers. And the package ships an updated TLS configuration, because some websites fingerprint the TLS settings and compare them with real browsers; the README notes that while Node.js did not support OpenSSL 3 at the time of writing, the configuration should still work.

The dependency list supports this picture. Alongside got itself there is header-generator, http2-wrapper for the HTTP/2 handling, mimic-response for constructing response objects, ow for argument validation, quick-lru for caching and tslib. The build uses tsup with a separate type check step, and tests run on vitest, with a separate blocking test script that performs live network requests through ts-node.

Node 16 is the stated minimum, and the README gives the reason: lower versions have unstable HTTP/2 support.

## ESM only, JSON mode and the limits of the generated headers

Two practical constraints affect how the package is used in an existing codebase.

The first is that the module is now ESM only, so it has to be imported with an import expression or through import(). The README shows the migration as a diff from require to import, and offers the alternative of importing inside an async context if the project cannot move to ESM:

```javascript
let gotScraping;

async function fetchWithGotScraping(url) {
    gotScraping ??= (await import('got-scraping')).gotScraping;

    return gotScraping.get(url);
}
```

The package.json confirms this shape, with type set to module and exports listing only an import condition pointing at the built index file.

The second constraint is that the generated headers are tuned for a specific case. The README is direct about it: the package can only generate all the standard attributes, you might want to add a referer header yourself, and the generated headers are made for GET requests for HTML documents. For POST requests or GET requests for another content type, the headers should be altered to match your needs, which you can do by passing a headers option or writing a custom got handler. Overriding a header is straightforward:

```javascript
const response = await gotScraping({
    url: 'https://apify.com/',
    headers: {
        'user-agent': 'test',
    },
});
```

JSON mode has the same caveat, since the header generation is done specifically for HTML content type, so parsing JSON works but the headers may not match what a browser would send for an API call:

```javascript
const response = await gotScraping({
    responseType: 'json',
    url: 'https://api.apify.com/v2/browser-info',
});
```

There is also a documented error case worth keeping: a Client network socket disconnected before secure TLS connection was established error can mean the server does not support the provided TLS settings, and the fix is to change the ciphers parameter to either undefined or a custom value.

## What to migrate to, and what to check before you do

The successor named in the README is impit, and the difference in approach is worth being precise about. impit exposes a fetch API rather than got's instance and stream model, and it is built on Rust's reqwest rather than on Node's HTTP stack, which changes the performance and protocol characteristics of the client underneath. The feature overlap the README claims is browser-like request headers, proxy support and more.

For a codebase that uses got-scraping as a thin wrapper, the migration is mostly about the calling convention: the options object becomes a fetch call with a headers object, and the response handling changes from the got promise shape to a fetch Response.

For a codebase that leans on got's advanced features, the move is harder. Streams, retries, hooks and the hook system are got's, and the README does not claim impit reproduces them. If your scraper depends on those, the honest answer is that the migration is a rewrite of the request layer rather than an import change.

Before starting, three things are worth checking. First, whether the proxy behaviour you rely on, including HTTP/2 proxy support and the automatic protocol detection, exists in impit. Second, whether you depend on the sessionToken behaviour for keeping a consistent browser identity across requests, since that is not a standard fetch concept and would need a layer of your own. Third, whether the code is already ESM, since got-scraping is ESM only and that constraint has been in place for a while.

The realistic plan is to keep got-scraping running for existing scrapers, avoid starting new ones on it, and schedule the move to impit with the feature gaps above written down.

## Conclusion

Adopt got-scraping only to keep an existing scraper running while you migrate, because the repository states the package is deprecated and will receive no further updates or support. Do not start new work on it, since Apify recommends impit, a fetch-based HTTP client built on Rust reqwest with browser-like headers and proxy support. Verify first by checking whether the proxy and header-generation behaviour your code depends on exists in the replacement, and by confirming that your existing project can import the package under ESM, since the module is now ESM only and requires Node 16 or newer.

## FAQ

### Is got-scraping still maintained?

No. The README carries an end-of-life notice stating that after many years of development the package was deprecated and will no longer receive updates or support. The last push to the repository was on 2026-10-21 and the package.json shows version 4.2.2.

### What should I use instead of got-scraping?

The README recommends impit, a fetch API based HTTP client built on Rust's reqwest library, which it says provides a similar feature set including browser-like request headers and proxy support.

### How do I keep browser headers consistent across several requests with got-scraping?

Pass the sessionToken option a non-primitive unique object describing the session. Headers generated with the same sessionToken never change, whereas leaving it undefined means new headers are generated every time.

### Can I still use CommonJS require with got-scraping?

Not directly, because the module is now ESM only. The README shows the diff from require to import, and offers importing inside an async context with await import('got-scraping') if the project cannot be migrated to ESM.

### What does got-scraping add on top of the got HTTP client?

It extends got with generated browser-like headers through the header-generator package, proxy support with automatic protocol detection, HTTP/2 negotiation, Pascal-Case header formatting, an insecure HTTP parser and an updated TLS configuration. Every other got feature remains available through got.extend.

## Sources

- [apify/got-scraping on GitHub](https://github.com/apify/got-scraping)
- [Issues](https://github.com/apify/got-scraping/issues)
- [README](https://github.com/apify/got-scraping/blob/master/README.md)
- [Releases](https://github.com/apify/got-scraping/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/apify-got-scraping
