Library / SDK
octokit/rest.js avatar
octokit/rest.js

@octokit/rest: GitHub's own REST client for JavaScript

GitHub REST API client for JavaScript

667 stars75 forksTypeScriptMIT

At a glance

What is it?
@octokit/rest is the officially maintained JavaScript client for the GitHub REST API, and it is assembled from a core package plus three plugins for endpoint methods, pagination and request logging. It is ESM only with conditional exports, which means the TypeScript configuration has to change before anything works, and the package you find on npm is assembled by a build script rather than by hand.
Who is it for?
Adopt @octokit/rest if you are writing JavaScript or TypeScript against the GitHub REST API and want a client that GitHub itself maintains, with pagination and request logging already wired in. Skip it if your work is against the GraphQL API, since this package targets the REST surface, or if your build is CommonJS only, because the package is ESM only and expects a node16 module resolution.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 1 day 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 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

From a 2010 commit to an official package

The credits section of the README is a small history lesson. @octokit/rest was originally created as node-github in 2012 by Mike de Boer from Cloud9 IDE, and the original commit is from 2010, which predates the npm registry. It was adopted and renamed by GitHub in 2017.

The package is MIT licensed, the documentation lives at octokit.github.io/rest.js, and the primary language is TypeScript. The author field in the manifest credits Gregor Martynus, with contributors listed for the earlier node-github era.

The maintenance signals are mixed in an instructive way. The published releases are v22.0.1 on 2025-10-31, v22.0.0 on 2025-05-25 and v20.1.2 on 2025-02-26, so the major version moves roughly yearly. The last push to the repository was on 2026-10-18, which is recent.

What is interesting is the version field inside package.json, which reads 0.0.0-development. That is a placeholder rather than a mistake. The build script and the release tooling replace it at publish time, with a dedicated semantic-release plugin for updating version numbers in files, so the version you install is stamped during release and the repository itself always carries the development placeholder.

One package, a browser build and a Node build

The usage section presents the library twice, once per environment, and the difference is a single import line.

For the browser, the README points at esm.sh, and the loading pattern is a module script:

html
<script type="module">
  import { Octokit } from "https://esm.sh/@octokit/rest";
</script>

For Node, it is an ordinary install and import, with npm install @octokit/rest as the install step:

js
import { Octokit } from "@octokit/rest";

The manifest confirms the shape of the package: the type field is module, and the publishConfig sets public access with provenance enabled, so the published artefact carries build provenance rather than being an unverified upload.

The browser route is worth pausing on. Loading a client straight from a CDN removes the install step entirely, which is attractive for a one-off script or a page, but it also means the version in your page is whatever the CDN serves at the time, and you have no lockfile to pin it. For anything long-lived, the npm route with a pinned version in a lockfile is the more predictable choice.

Conditional exports force a tsconfig change

The README repeats the same important note twice, once after the browser and Node examples and once after the first code sample, which is a hint about how often people hit it.

Because the package uses conditional exports, you need to adapt your tsconfig.json by setting moduleResolution to node16 and module to node16. The README links to the Node documentation on conditional exports, to the TypeScript documentation on package.json exports, and to a guide on transitioning to ESM.

This is the single biggest source of friction for a new user, and it is a consequence of a good decision. Conditional exports let a package serve different entry points to different consumers, for instance a browser build and a Node build, and TypeScript can only honour that if it understands the same resolution algorithm as Node. The cost is that a project on an older moduleResolution setting will not find the types, and the error is famously unhelpful because it looks like a missing package rather than a configuration mismatch.

The package manifest is fully ESM, with type set to module, so there is no CommonJS fallback to switch to. The migration path is to align the TypeScript configuration with Node's resolution rules, not to downgrade the client.

Endpoint methods live under octokit.rest

The call shape is the part of the API worth knowing before you write anything, and the README's example is short:

js
const octokit = new Octokit();

// Compare: https://docs.github.com/en/rest/reference/repos/#list-organization-repositories
octokit.rest.repos
  .listForOrg({
    org: "octokit",
    type: "public",
  })
  .then(({ data }) => {
    // handle data
  });

The constructor takes no arguments in this example, and the endpoints are reached through a rest namespace, then a resource, then a method name that mirrors the REST API documentation. The README even carries a comment pointing at the corresponding page in GitHub's REST reference, which is a good sign for a client whose whole job is to make the documentation and the code line up.

The method returns a promise resolving to an object with data, and the example destructures that data in the then handler.

Two practical notes. The endpoint list is generated rather than hand written, which is why a change in the GitHub API shows up as a version bump here, and why the client can lag the API by a release cycle. And a promise-only interface means there is no callback style to fall back on, so code that expects error handling through callbacks has to be rewritten.

A core package and three plugins

The runtime dependencies in package.json explain the design in four lines. The package depends on @octokit/core at version 7, @octokit/plugin-paginate-rest at 14, @octokit/plugin-request-log at 6 and @octokit/plugin-rest-endpoint-methods at 17.

The endpoint methods plugin is what produces the octokit.rest.repos.listForOrg style surface. The pagination plugin handles the page-based list endpoints that GitHub's REST API exposes, which is the feature you would otherwise write by hand for every list call. The request log plugin records the requests the client makes, which is what makes debugging a script against the API practical. Core is the underlying request layer.

This composition is the reason the package is not a monolith. Each of those concerns is a separate package with its own version, and the majors move independently, which is why a client update can pull in a newer pagination plugin without the REST client itself changing shape. The trade-off is more packages in your dependency tree and a version matrix to reason about when something breaks.

Notice what is not in that list. There is no authentication package among the runtime dependencies, so bringing your own token or auth strategy is part of the job. The authentication packages that do appear in the manifest, @octokit/auth-app and @octokit/auth-action, are development dependencies used by the test suite rather than things the client installs for you.

The repository documents its own build

The top level of the repository is a working document about how the package is produced. Alongside the usual files there is HOW_IT_WORKS.md, a docs/ directory, a scripts/ directory, a test/ directory, src/, assets/, cypress.json and vite.config.js, plus SECURITY.md, CODE_OF_CONDUCT.md and CONTRIBUTING.md.

The build script in package.json is two commands, a node scripts/build.mjs step followed by tsc -p tsconfig.json, so the JavaScript bundling and the type declarations are produced in two distinct stages. The lint script is a Prettier check rather than an ESLint run, and it covers src and test alongside the docs directory and the markdown files, which is a small sign that the documentation is treated as part of the product.

The development dependencies describe how the project is verified. Vitest is the test runner, and alongside it sit nock, fetch-mock and undici for intercepting HTTP, @octokit/fixtures-server for serving fixtures, @octokit/request and @octokit/auth-app and @octokit/auth-action for testing against real request and auth behaviour, esbuild for bundling, and glob and tinyglobby for file discovery. There is a coverage plugin for Vitest, and the release process uses semantic-release with a plugin for updating version numbers in files.

The Cypress configuration and the fixtures server together suggest that the tests run against a local HTTP layer rather than against the live GitHub API, which is what you want in a client whose behaviour depends on headers, status codes and pagination cursors.

Where this client stops

The scope is narrow, and that is a feature rather than a gap, but it does define where you should not reach for it.

It targets the REST API. If your work is against the GraphQL API, this is the wrong surface, because the endpoint methods are generated for REST routes and nothing here gives you a GraphQL client. It also does not carry authentication, so a deployment needs to decide separately how a token is obtained, stored and rotated, and that decision is usually more consequential than the choice of client.

There is a version-coupling issue too. The endpoint methods are generated from the API surface, so a client release and an API change are related, and a version bump here may be exactly the moment your script needs review, rather than a routine dependency update. The semantic-release versioning with a major every year or so reflects that churn.

The alternative approach is worth naming. A project that only needs one or two endpoints, or that needs to run in an environment where a dependency tree is unwelcome, can call the REST API directly over fetch, with the same authentication headers. What that buys is a dependency-free implementation. What it costs is reimplementing pagination, error handling and request logging each time, which is exactly the work the plugins here already do. The decision is less about the API than about how many endpoints and how much paging your project actually needs.

Editorial conclusion

Adopt @octokit/rest if you are writing JavaScript or TypeScript against the GitHub REST API and want a client that GitHub itself maintains, with pagination and request logging already wired in. Skip it if your work is against the GraphQL API, since this package targets the REST surface, or if your build is CommonJS only, because the package is ESM only and expects a node16 module resolution. Before the first call, set moduleResolution and module to node16 in your tsconfig.json, confirm the runtime dependency list has no authentication package and plan how your token reaches the client, and check the current major version, since v22.0.1 was published on 2025-10-31. The last push was on 2026-10-18 and the licence is MIT.

Frequently asked questions

How do I install and import @octokit/rest in Node?

Install it with npm install @octokit/rest and import it with import { Octokit } from "@octokit/rest". In a browser you can instead load it as a module script from esm.sh, importing Octokit from https://esm.sh/@octokit/rest.

Why do I get a missing types error after installing @octokit/rest?

The README states that because the package uses conditional exports, you need to adapt your tsconfig.json by setting moduleResolution to node16 and module to node16. Without that change TypeScript cannot resolve the package the way Node does.

How does @octokit/rest handle pagination?

Pagination is handled by a separate dependency, @octokit/plugin-paginate-rest, which is included in the package's runtime dependencies. Request logging is likewise provided by @octokit/plugin-request-log.

Does @octokit/rest handle authentication for me?

The runtime dependencies listed in the manifest are @octokit/core and the pagination, request log and endpoint methods plugins, with no authentication package among them. The auth packages that appear, @octokit/auth-app and @octokit/auth-action, are development dependencies used by the test suite.

Official sources

  1. License: MIT
  2. octokit/rest.js on GitHub
  3. Project website
  4. README
  5. Releases
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.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/octokit-rest-js.svg)](https://hysenlabs.com/projects/octokit-rest-js)

Was this useful?