typed-rest-client: a typed HTTP and REST client for TypeScript
Node Rest and Http Clients with typings for use with TypeScript
At a glance
- What is it?
- typed-rest-client is a Node HTTP and REST client that ships its own TypeScript typings and leans on generics and async/await instead of a heavier framework. Its distinguishing feature is a REST layer that deserializes a body into a typed object, and a deliberate policy of not throwing on ordinary HTTP error statuses.
- Who is it for?
- Adopt typed-rest-client when you want a small HTTP layer with typings in the same package, need NTLM or client certificates without assembling them yourself, and prefer a REST wrapper that gives you a typed object over a hand-rolled fetch helper. Do not adopt it if you want automatic retries, connection pooling control, or a response model that throws on every failure, since the README states the HTTP client does not throw unless truly exceptional.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 4 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 24, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Typings ship inside the package, which removes version drift
The package describes itself as a lightweight REST and HTTP client optimized for use with TypeScript with generics and async await. The feature list is specific about the reason to choose it over a generic HTTP library: typings are included so there is no need to acquire them separately, which the README calls out as being great for intellisense and no versioning drift.
That last phrase is the real argument. The common pattern with HTTP libraries is a separate `@types/` package maintained on a different cadence from the runtime package, and a mismatch there produces either missing methods or types that describe a version you do not have. Shipping the declarations in the same package removes that class of problem, and the README shows an intellisense screenshot in `docs/intellisense.png` to make the point.
The stack is small, which also matters. The runtime dependencies are `des.js`, `js-md4`, `qs` and `tunnel`, plus a general utility library in the manifest. There is no HTTP framework, no schema validation layer, and no middleware system. The design idea is that you describe the shape of a response with a TypeScript generic and the client hands you that shape back, with the surrounding plumbing kept small enough to read.
One caveat sits in the package manifest. The `main` entry is `./RestClient.js`, so the REST client is the default export, and the REST client is documented as the higher-level component that sits on top of the HTTP client.
Two layers with different failure semantics
The most important design decision in the library is that the HTTP and REST layers do not fail the same way, and the README spells out both.
The HTTP client does not throw unless truly exceptional. A request that successfully executes and results in a 404 or a 500 returns a response object carrying a status code and a body. Redirects in the 3xx range are followed by default.
The REST client is built on the HTTP client, and its stated responsibility is to turn a body into a typed resource object. Its rules are more specific. A 200 is a success. Redirects are followed. A 404 will not throw, but the result object will be null and the result statusCode will be set. Other 4xx and 5xx errors will throw, with the status code attached to the error object, and if a RESTful error object is returned in the shape `{ message: xxx}` then that message becomes the error message, otherwise the error is a generic `Failed Request: (xxx)`.
So a 404 is a normal outcome on the REST side, expressed as a null result with a status code, while a 500 is an exception. That asymmetry is deliberate and it is worth internalizing before you write the calling code, because a `try` block that only catches exceptions will not catch a missing resource. The detailed examples for both layers live in the test files, with `test/tests/resttests.ts` for the REST client and `test/tests/httptests.ts` for the HTTP one.
Authentication, proxies, certificates and redirects without extra packages
The feature list names the transport concerns the library handles itself. Basic, Bearer and NTLM support come out of the box, with extensible handlers for other schemes. Proxy support is built in, certificate support covers self-signed server certificates and client certificates, and redirects are supported.
The NTLM piece is the reason many teams end up here. NTLM is a Windows-centric scheme with a non-trivial handshake, and implementing it by hand is not something most teams want to maintain. The `js-md4` dependency in the manifest is consistent with that, since NTLM requires an MD4 digest. The `tunnel` dependency covers proxying, and `qs` covers query string serialization.
The `des.js` dependency and the general utility library are not explained in the README, and the library does not document how the extensible handler mechanism for other authentication schemes is meant to be used, so a reader who needs something outside Basic, Bearer and NTLM is working without documentation for it.
Redirects being followed by default, on both layers, has a second-order effect. If your service has a redirect that changes the method or the target host, the client will follow it without asking, which matters for a client that carries credentials in headers.
Install, the preview tag, and the Node version split
Installation is a single npm command:
npm install typed-rest-client --saveThere is also a separate channel for previews, which is a dist-tag rather than a version range:
npm install typed-rest-client@preview --saveThe Node support story is where the README gets blunt. Version 2 is listed as current and maintained and supports Node 16 and above. Version 1 is End Of Life, intended for Node below 16, and the README says it contains security vulnerabilities and should be used at your own risk.
That table has drifted from the manifest. The `package.json` in the repository declares `engines` as `node: >= 20.0.0` and a version of `3.1.2`, and the dev dependencies include `@types/node` at `^20.11.0` and a TypeScript at `^5.4.5`. So the current source targets a newer Node than the README's compatibility table describes, and the release history in the repository shows tags through v2.1.0 dated 2024-09-20 while the manifest has moved on to 3.1.2.
For a team choosing a version, that gap is the thing to resolve first. The last push was on 2026-10-17, so the source is moving, but the release tags are older, and the published package and the source tree may not be the same thing.
NODE_DEBUG=http is the debugging path, and there is no other
The README documents exactly one diagnostic facility, and it is the standard one. To enable detailed console logging of all HTTP requests and responses, set the `NODE_DEBUG` environment variable:
export NODE_DEBUG=httpOn Windows the equivalent is:
set NODE_DEBUG=httpThat is convenient, since it needs no change to the library and no wrapper around the client, but it logs at the level of the HTTP client, which means it shows traffic and status codes rather than the deserialized typed object. It will also show traffic for any other library in the same process that uses the same underlying mechanism.
There is no documented request hook, no per-client logger option, and no tracing integration in the README. For an application that needs structured logs with a correlation id attached to each call, the practical options are the environment variable or a wrapper around the client that adds headers, and the library does not provide a first-class place for that.
The samples directory is the place the README points to for complete coding examples, and it is organized by consumer type: `samples/basic/`, `samples/react/`, `samples/webSample/` and `samples/webpack/`. A React sample matters because it shows the client in a browser context, where proxy and certificate features are not available, while the webpack sample is there because bundling a Node package into a browser bundle is a common source of friction.
Building from source uses a make.js script and Azure Pipelines
The repository is built with a plain Node script rather than a conventional bundler, and the scripts in `package.json` all route through it. The build is `node make.js build`, the test run is `node make.js test`, the unit-only run is `node make.js units`, and there are also `bt` for build-and-test, `samples` and `validate` targets.
The commands the README gives are:
$ npm run build$ npm test$ npm run unitsThe test stack is mocha with `nock` for HTTP interception, and `@octokit/rest` and `shelljs` appear in the dev dependencies alongside `semver`, which suggests the build script and the release automation use them. The `@types/mocha` version pinned is `^2.2.44`, which is old relative to the `mocha` at `^10.4.0` it types, another sign of a package where the dependency list has been updated unevenly over time.
Continuous integration runs on Azure Pipelines rather than GitHub Actions, with `azure-pipelines.yml` and a `.azure-pipelines/` directory at the top level. There is also a `.github/` directory, but the build badge in the README points at a DevOps build definition, so the release gate is not on GitHub.
The `overrides` block in the manifest is worth noting for anyone with a security scanner in their pipeline. It pins `serialize-javascript` to `7.0.5`, `js-yaml` to `^4.3.2`, and forces `brace-expansion` to `1.1.18` on the 1.x line and `2.1.4` on the 2.x line. Those are transitive dependency pins made to work around advisories, and they are the kind of thing that has to be revisited when the underlying packages are upgraded.
Where this client stops and another one has to take over
The clearest gap is resilience. Nothing in the README mentions retries, backoff, circuit breaking or connection pooling, and the dependency list has no HTTP agent or pool library in it. A client that neither retries nor pools is a client for a service that either always answers or always fails.
The second gap is the request side of the REST layer. The README describes what the REST client does with a response, namely turn a body into a typed resource object, but says nothing about serializing a typed request body, about content negotiation, or about interceptors. The two documented examples both use GET routes, so the shape of a POST with a payload is not shown in the text available. The test files are the only reference for that, and they are described as detailed examples rather than reproduced in the README.
The third gap is the version story described earlier. A package whose README compatibility table stops at Node 16, whose manifest requires Node 20, and whose published tags end at 2.1.0 while the manifest reads 3.1.2, needs a deliberate check rather than a trust of the version range. The licence is reported as Other, a custom licence GitHub cannot classify, with the terms in the LICENSE file and third-party notices in `ThirdPartyNotice.txt`.
For comparison, a general purpose HTTP library with a plugin ecosystem gives you retries, interceptors, and pooling as installed extras, at the cost of the bundled typings and the NTLM and certificate handling that typed-rest-client provides directly. The choice is between a small client that covers the Microsoft-adjacent enterprise cases and a larger one where you assemble those cases yourself.
Editorial conclusion
Adopt typed-rest-client when you want a small HTTP layer with typings in the same package, need NTLM or client certificates without assembling them yourself, and prefer a REST wrapper that gives you a typed object over a hand-rolled fetch helper. Do not adopt it if you want automatic retries, connection pooling control, or a response model that throws on every failure, since the README states the HTTP client does not throw unless truly exceptional. Verify first that the version you install matches your Node runtime, because the README documents v2 as supporting Node 16 and above while package.json now declares node >= 20.0.0 and a version of 3.1.2.
Frequently asked questions
How do I install typed-rest-client?
Run `npm install typed-rest-client --save` for the stable package, or `npm install typed-rest-client@preview --save` to get the latest preview. The typings are included in the package, so there is no separate types package to install.
Does typed-rest-client throw on HTTP errors?
The HTTP client does not throw unless truly exceptional, so a 404 or 500 returns a response object with a status code and a body. On the REST side a 404 does not throw either, the result object is null and the statusCode is set, while other 4xx and 5xx errors do throw.
Which Node versions does typed-rest-client support?
The README lists v2 as current and maintained, supporting Node 16 and above, and v1 as End Of Life for Node below 16 with known security vulnerabilities. The package manifest in the repository declares `node: >= 20.0.0` and a version of 3.1.2, so check which line you are installing.
How do I enable request and response logging in typed-rest-client?
Set the `NODE_DEBUG` environment variable to `http`, using `export NODE_DEBUG=http` on macOS and Linux or `set NODE_DEBUG=http` on Windows. The README documents this as the way to get detailed console logging of all HTTP requests and responses.
Does typed-rest-client support NTLM authentication and proxies?
Yes. The feature list states that Basic, Bearer and NTLM support are included out of the box with extensible handlers for other schemes, and that proxy support and certificate support for self-signed server and client certificates are also included.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/microsoft-typed-rest-client)Was this useful?