npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

netsuiteoauth2

v3.0.0

Published

An easy-to-use OAuth2 authentication for NetSuite.

Readme

NetSuite OAuth2

A small, zero-dependency Node.js library for NetSuite's OAuth 2.0 Authorization Code Grant with PKCE. It gets, refreshes and revokes tokens for RESTlets, REST Web Services and SuiteAnalytics Connect.

It never opens a browser or starts a server: it builds URLs and calls NetSuite's token endpoints. You handle the redirect, so it works the same in a web app, a CLI, a server or CI.

npm install netsuiteoauth2

How it works

1. getAuthorizationUrl()        → url, codeVerifier, state
2. User logs in at `url`        → NetSuite redirects to redirectUrl?code=…&state=…&company=…
3. exchangeAuthorizationCode()  → access_token + refresh_token
4. refreshAccessToken()         → new access_token when the old one expires
5. revokeRefreshToken()         → invalidate the refresh token

Access tokens are short-lived (about 60 min). The refresh token lasts much longer, so you authorize once, store the refresh token, and get new access tokens from it as needed.

Setup

Create an integration record in NetSuite with Authorization Code Grant enabled, then:

import { NSOAuth2, Scope, OAuth2TokenDTO } from 'netsuiteoauth2';

const client = new NSOAuth2({
    clientId: process.env.NS_CLIENT_ID!,
    clientSecret: process.env.NS_CLIENT_SECRET!,
    redirectUrl: 'https://example.com/callback', // must match the integration record
    scopes: [Scope.RESTLETS, Scope.REST_WEB_SERVICES], // also: Scope.SUITE_ANALYTICS_CONNECT
    accountId: '1234567', // optional, see below
});

accountId is optional. If you set it, users log in at that account's URL. If you leave it out, they log in at system.netsuite.com and choose an account. The account they choose comes back as the company query param.

Usage

Authorize (once per user/account)

// Build the login URL and keep codeVerifier and state (for example, in the session).
const { url, codeVerifier, state } = client.getAuthorizationUrl();
// Redirect the user to `url`.

// In your redirectUrl handler, reject the request if req.query.state !== state, then:
const token: OAuth2TokenDTO = await client.exchangeAuthorizationCode(company, code, codeVerifier);

Refresh

// From a stored refresh token (for example, a CI secret). No user interaction.
const token = await client.accessTokenFromRefreshToken(accountId, refreshToken);

// Or renew an existing token. This updates it in place and returns it.
await client.refreshAccessToken(token);

Call NetSuite

fetch(`https://${token.account}.suitetalk.api.netsuite.com/services/rest/record/v1/customer/1`, {
    headers: { Authorization: `Bearer ${token.access_token}` },
});

Revoke

await client.revokeRefreshToken(token);

Token

| Field | Description | |-----------------|-------------------------------------------| | account | NetSuite account id | | access_token | Bearer token for API calls | | refresh_token | Used to get new access tokens | | expires_in | Access token lifetime, in seconds | | issued_at | When the token was issued (ms since epoch) |

To check whether a token has expired: Date.now() > issued_at + expires_in * 1000.

Security

Keep clientSecret and refresh tokens out of source control. Use environment variables or a secrets manager.