Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
f091454
feat!: replace axios with native fetch for cross-platform support
rhamzeh Mar 31, 2026
744a80e
chore: refactor to replace `any` with proper types
rhamzeh Mar 31, 2026
ae61409
chore(tests): add some tests for fetch-based HTTP client layer
rhamzeh Mar 31, 2026
1946a49
chore: update changelog & documentation
rhamzeh Mar 31, 2026
33d64f3
chore(deps): refresh package-lock.json after dropping axios
rhamzeh Mar 31, 2026
ef3a638
fix: fixes and refinements to the httpclient
rhamzeh Mar 31, 2026
79ee8af
fix: skip implicit timeout for responseType: "stream", default to "GE…
emilic Apr 6, 2026
76cb2af
fix: Remove dead Axios-era $response unwrapping from streamedListObje…
emilic Apr 6, 2026
e2e8878
fix: construct proper FgaApiAuthenticationError instead of mutating e…
emilic Apr 6, 2026
04ba14f
Merge branch 'main' into feat/drop-axios
rhamzeh May 7, 2026
8f515c6
chore: Revert "fix: construct proper FgaApiAuthenticationError instea…
rhamzeh May 7, 2026
61258b3
refactor: replace tiny-async-pool with native implementation
rhamzeh Apr 17, 2026
15938e6
refactor: move self-contained utils into utils/utils-lite
rhamzeh Apr 17, 2026
043257c
fix: use Math.random as a fallback for environments without crypto su…
rhamzeh Apr 17, 2026
6f6831d
chore: output CJS to dist/cjs/
rhamzeh Apr 17, 2026
09f6c2a
feat: add ESM build alongside CJS allowing for dual resolution
rhamzeh Apr 17, 2026
0f237f4
Merge branch 'main' into feat/drop-axios
emilic May 8, 2026
cb5f6cd
Merge branch 'feat/drop-axios' into feat/esm-modules
emilic May 8, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@

* Correctly set authorization model id when calling batch checks ([#372](https://github.com/openfga/js-sdk/issues/372)) ([bbc8bde](https://github.com/openfga/js-sdk/commit/bbc8bdec04475b7707542b09be4e31fa9666dd2f))

- feat!: replace axios with native `fetch` for cross-platform support (Node.js, browsers, Deno, Cloudflare Workers, Vercel Edge).
- **BREAKING**: `AxiosResponse` is no longer exposed on `$response`. The new type is `FgaResponse<T>` (with `status`, `statusText`, `headers`, `data`).
- **BREAKING**: `AxiosInstance` injection is replaced by the `HttpClient` interface (`{ fetch, defaultHeaders, defaultTimeout }`).
- Timeouts now use `AbortSignal.timeout()`.
- chore: all `options?: any` parameters in the API layer are now properly typed as `RequestBuilderOptions`.

## v0.9.4

### [v0.9.4](https://github.com/openfga/js-sdk/compare/v0.9.3...v0.9.4) (2026-03-31)
Expand Down
79 changes: 71 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ This is an autogenerated JavaScript SDK for OpenFGA. It provides a wrapper aroun
- [Getting Started](#getting-started)
- [Initializing the API Client](#initializing-the-api-client)
- [Custom Headers](#custom-headers)
- [Custom HTTP Client](#custom-http-client)
- [Get your Store ID](#get-your-store-id)
- [Calling the API](#calling-the-api)
- [Stores](#stores)
Expand Down Expand Up @@ -84,7 +85,17 @@ Using [yarn](https://yarnpkg.com):
yarn add @openfga/sdk
```

#### Supported Node.js Versions
### Supported Runtimes

The SDK ships with both CommonJS and ES Module builds, and should work out of the box in Node.js, Deno, Cloudflare Workers, and modern bundlers.

```javascript
// CommonJS
const { OpenFgaClient } = require("@openfga/sdk");

// ES Modules
import { OpenFgaClient } from "@openfga/sdk";
```

For details on the supported Node.js versions and our support policy, see [SUPPORTED_RUNTIMES.md](./SUPPORTED_RUNTIMES.md).

Expand All @@ -94,14 +105,14 @@ For details on the supported Node.js versions and our support policy, see [SUPPO

[Learn how to initialize your SDK](https://openfga.dev/docs/getting-started/setup-sdk-client)

We strongly recommend you initialize the `OpenFgaClient` only once and then re-use it throughout your app, otherwise you will incur the cost of having to re-initialize multiple times or at every request, the cost of reduced connection pooling and re-use, and would be particularly costly in the client credentials flow, as that flow will be performed on every request.
We strongly recommend you initialize the `OpenFgaClient` only once and then re-use it throughout your app, otherwise you will incur the cost of having to re-initialize multiple times or at every request, and would be particularly costly in the client credentials flow, as that flow will be performed on every request. In Node.js, connection pooling is handled automatically by the runtime's native `fetch` implementation.

> The `OpenFgaClient` will by default retry API requests up to 3 times on 429 and 5xx errors.

#### No Credentials

```javascript
const { OpenFgaClient } = require('@openfga/sdk'); // OR import { OpenFgaClient } from '@openfga/sdk';
import { OpenFgaClient } from '@openfga/sdk';

const fgaClient = new OpenFgaClient({
apiUrl: process.env.FGA_API_URL, // required
Expand All @@ -113,7 +124,7 @@ const fgaClient = new OpenFgaClient({
#### API Token

```javascript
const { OpenFgaClient, CredentialsMethod } = require('@openfga/sdk'); // OR import { OpenFgaClient, CredentialsMethod } from '@openfga/sdk';
import { OpenFgaClient, CredentialsMethod } from '@openfga/sdk';

const fgaClient = new OpenFgaClient({
apiUrl: process.env.FGA_API_URL, // required
Expand All @@ -131,7 +142,7 @@ const fgaClient = new OpenFgaClient({
#### Client Credentials

```javascript
const { OpenFgaClient, CredentialsMethod } = require('@openfga/sdk'); // OR import { OpenFgaClient, CredentialsMethod } from '@openfga/sdk';
import { OpenFgaClient, CredentialsMethod } from '@openfga/sdk';

const fgaClient = new OpenFgaClient({
apiUrl: process.env.FGA_API_URL, // required
Expand All @@ -156,7 +167,7 @@ const fgaClient = new OpenFgaClient({
You can set default headers that will be sent with every request during client initialization:

```javascript
const { OpenFgaClient } = require('@openfga/sdk'); // OR import { OpenFgaClient } from '@openfga/sdk';
import { OpenFgaClient } from '@openfga/sdk';

const fgaClient = new OpenFgaClient({
apiUrl: process.env.FGA_API_URL,
Expand Down Expand Up @@ -189,6 +200,58 @@ const result = await fgaClient.check({
});
```

### Custom HTTP Client

The SDK uses the native `fetch` API by default. You can provide a custom `HttpClient` to control the underlying HTTP behavior.

```javascript
import { OpenFgaClient } from '@openfga/sdk';

const fgaClient = new OpenFgaClient(
{
apiUrl: process.env.FGA_API_URL,
storeId: process.env.FGA_STORE_ID,
},
{
fetch: globalThis.fetch.bind(globalThis), // or a custom fetch implementation
defaultHeaders: {
"X-Custom-Header": "value",
},
defaultTimeout: 15000, // timeout in milliseconds (default: 10000)
}
);
```

The `HttpClient` interface accepts:

| Property | Type | Description |
| --- | --- | --- |
| `fetch` | `typeof globalThis.fetch` | The fetch function to use for HTTP requests |
| `defaultHeaders` | `Record<string, string>` | *(Optional)* Headers to include with every request |
| `defaultTimeout` | `number` | *(Optional)* Default request timeout in milliseconds |

#### Response Type

Most SDK methods that are a direct call to the API return an `FgaResponse<T>` on the `$response` property:

```typescript
interface FgaResponse<T> {
status: number;
statusText: string;
headers: Record<string, string>;
data: T;
}
```

You can access it via the `$response` property on the method's return value:

```javascript
const res = await fgaClient.getStore();
const { headers, status } = res.$response;
```

Methods that have custom logic, such as `clientBatchCheck`, `listRelations` and non-transactional `write` operations, will not contain this field.

### Get your Store ID

You need your store id to call the OpenFGA API (unless it is to call the [CreateStore](#create-store) or [ListStores](#list-stores) methods).
Expand Down Expand Up @@ -901,7 +964,7 @@ This is useful when:
#### Example: Calling a Custom Endpoint with POST

```javascript
const { OpenFgaClient } = require('@openfga/sdk');
import { OpenFgaClient } from "@openfga/sdk";

const fgaClient = new OpenFgaClient({
apiUrl: process.env.FGA_API_URL,
Expand Down Expand Up @@ -1003,7 +1066,7 @@ To customize this behavior, create an object with `maxRetry` and `minWaitInMs` p
Apply your custom retry values by setting to `retryParams` on the configuration object passed to the `OpenFgaClient` call.

```javascript
const { OpenFgaClient } = require('@openfga/sdk'); // OR import { OpenFgaClient } from '@openfga/sdk';
import { OpenFgaClient } from '@openfga/sdk';

const fgaClient = new OpenFgaClient({
apiUrl: process.env.FGA_API_URL, // required
Expand Down
16 changes: 11 additions & 5 deletions SUPPORTED_RUNTIMES.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
## Node.js Support Policy for OpenFGA JS SDK
## Runtime Support Policy for OpenFGA JS SDK

### Node.js Support

The OpenFGA JavaScript SDK follows the upstream [Node.js release policy](https://nodejs.org/en/about/previous-releases). We support Node.js versions that are currently in **LTS** or **Maintenance** status.

### Currently Supported Versions
#### Currently Supported Versions

| Node.js Version | Upstream Support Status | Tested in CI/CD Pipelines |
|:----------------|:------------------------|:-------------------------:|
Expand All @@ -11,12 +13,16 @@ The OpenFGA JavaScript SDK follows the upstream [Node.js release policy](https:/
| **24** | LTS | Yes |
| **25** | Current | Yes |

### Support Details
#### Support Details

#### Best-Effort Support
##### Best-Effort Support

We will make a best effort to maintain compatibility with Node.js versions that have reached End-of-Life (EOL), but **we will not test** against them in our CI/CD pipelines. This means you may be able to use the JS SDK with older versions of Node.js (with yarn you can use the `--ignore-engines` flag), but you may not be able to run tests (because many of our testing dependencies have dropped support for EOL versions).

#### Long-term plan
##### Long-term plan

This best-effort support will not continue indefinitely. We plan to modernize our JS SDK, adopt more functionality now native to the language, and add support for alternate runtimes such as Deno, Cloudflare Workers, and Vercel Edge.

### Alternate Runtimes

Support for alternate runtimes such as Deno, Cloudflare Workers, and Vercel Edge is being gradually added. We will provide updates on our progress in the future.
Loading
Loading