Arctic v3 Documentation
website·Indexed Apr 12, 2026
https://arcticjs.dev/Arctic v3 is a lightweight, fully-typed OAuth 2.0 client library supporting the authorization code flow and built on the Fetch API. It provides native support for Node.js 20, Bun, Deno, and Cloudflare Workers, with a Web Crypto API polyfill required for Node.js 18. The library includes a generic OAuth 2.0 client and specific providers for services like GitHub, Discord, Auth0, Apple, and AWS Cognito. Key features include PKCE support, token management (refresh, revoke), and OpenID Connect integration. Installation is performed via npm install arctic.
What's inside Arctic
- Install Arctic using npm. Arctic is a lightweight, fully-typed OAuth 2.0 client library supporting only the authorization code flow, built on the Fetch API. It works with any runtime that provides the Fetch API and Web Crypto API.npm install arctic
OAuth2Tokens overview
OAuth2Tokens is the central reference for OAuth2 authentication providers supported by ArcticJS. It provides access to token management capabilities across 60+ integrated identity providers including GitHub, Google, Discord, Microsoft Entra ID, and many others. Each provider has its own dedicated configuration page with specific setup instructions.Synology OAuth provider prerequisites
To use the Synology OAuth 2.0 provider, install the SSO Server package on your Synology NAS. In the SSO Server configuration: (1) Configure the base URL where SSO Server will be reachable, (2) Enable the OIDC service, (3) Create a new OAuth App. Both the base URL and redirect URI must use HTTPS.Validate TikTok authorization code
Exchange an authorization code for access and refresh tokens usingvalidateAuthorizationCode(code, codeVerifier). ReturnsOAuth2TokenswithaccessToken(),accessTokenExpiresAt(), andrefreshToken()methods. Can throwOAuth2RequestError,ArcticFetchError,UnexpectedResponseError, orUnexpectedErrorResponseBodyError. TikTok also returnsrefresh_expires_inindicating when the refresh token expires.const tokens = await tiktok.validateAuthorizationCode(code, codeVerifier); const accessToken = tokens.accessToken(); const accessTokenExpiresAt = tokens.accessTokenExpiresAt(); const refreshToken = tokens.refreshToken(); // Check for refresh token expiration if ("refresh_expires_in" in tokens.data && typeof tokens.data.refresh_expires_in === "number") { const refreshTokenExpiresIn = tokens.data.refresh_expires_in; }
Fetch Battle.net user profile
Use the Battle.net User Info endpoint with the access token to retrieve user profile data. Include the access token in the Authorization header as a Bearer token.const response = await fetch("https://oauth.battle.net/userinfo", { headers: { Authorization:
Bearer ${accessToken}} }); const user = await response.json();Extract user profile from WorkOS token response
The user profile is included directly in the OAuth2Tokens response data under the 'profile' key. Check for the profile property and validate its type before accessing.const tokens = await workos.validateAuthorizationCode(code); if ( "profile" in tokens.data && typeof tokens.data.profile = "object" && tokens.data.profile ! null ) { const profile = tokens.data.profile; }
Create TikTok authorization URL with PKCE
Generate an authorization URL for user login. UsegenerateState()for CSRF protection andgenerateCodeVerifier()for PKCE. Available scopes includeuser.info.basicandvideo.list. The returned URL should be used to redirect the user to TikTok's consent screen.import * as arctic from "arctic"; const state = arctic.generateState(); const codeVerifier = arctic.generateCodeVerifier(); const scopes = ["user.info.basic", "video.list"]; const url = tiktok.createAuthorizationURL(state, codeVerifier, scopes);
Fetch Strava user profile via API
Retrieve the authenticated user's profile from Strava's API. Use the 'read' scope for basic profile data or 'read_all' scope for private data. Make a GET request to https://www.strava.com/api/v3/athlete with Bearer token authorization.const response = await fetch("https://www.strava.com/api/v3/athlete", { headers: { Authorization:
Bearer ${accessToken}} }); const user = await response.json();Refresh GitHub access tokens
Refresh an expired access token using a refresh token. This feature is only available for GitHub Apps, not OAuth Apps. The behavior and error handling are identical to validateAuthorizationCode().import * as arctic from "arctic";
try { const tokens = await github.refreshAccessToken(refreshToken); const accessToken = tokens.accessToken(); const accessTokenExpiresAt = tokens.accessTokenExpiresAt(); const newRefreshToken = tokens.refreshToken(); } catch (e) { if (e instanceof arctic.OAuth2RequestError) { // Invalid refresh token, credentials, or redirect URI } if (e instanceof arctic.ArcticFetchError) { // Failed to call fetch() } }
Create public OAuth clients with null secret
For providers supporting public OAuth clients, pass null as the clientSecret value in the constructor. This applies to Auth0, Discord, Spotify, and WorkOS.import * as arctic from "arctic";
const keycloak = new arctic.KeyCloak(clientId, null, redirectURI);
Refresh access tokens for DonationAlerts
Use refreshAccessToken() to obtain a new access token using a refresh token. Pass the same scopes used during initial authorization. Returns OAuth2Tokens and throws the same error types as validateAuthorizationCode().const scopes = ["oauth-user-show"]; const tokens = await donationAlerts.refreshAccessToken(refreshToken, scopes); const accessToken = tokens.accessToken(); const accessTokenExpiresAt = tokens.accessTokenExpiresAt();
Validate authorization code and exchange for tokens
Exchange an authorization code for access tokens using validateAuthorizationCode(). Returns OAuth2Tokens containing the access token and expiration time. Handle potential errors: OAuth2RequestError for invalid codes/credentials, ArcticFetchError for network failures, UnexpectedResponseError and UnexpectedErrorResponseBodyError for API issues.const tokens = await fortyTwo.validateAuthorizationCode(code); const accessToken = tokens.accessToken(); const accessTokenExpiresAt = tokens.accessTokenExpiresAt();