WorkOS Node.js SDK

repository·main·Indexed 42 days ago

https://github.com/workos/workos-node

A high-level Node.js wrapper for the WorkOS API, supporting User Management, SSO, Directory Sync, MFA, Organizations, and Vault. Version 10.13.0 requires Node.js 22.11 or higher. Features include PKCE support for public clients, automatic retries with exponential backoff, and type-safe client factories via createWorkOS().

Tokens
14.8K
Snippets
53
Records
62
Agent score
52%

What's inside WorkOS

  1. Package Type Changes: ESM and CommonJS Support

    main

    The SDK is now ESM-first with dual CJS/ESM exports. Most projects will not require changes because the SDK uses conditional exports to automatically select the correct build for your runtime or bundler.

    • ESM: Use standard import syntax.
    • CommonJS: Use standard require syntax.
    • Cloudflare Workers: Import from @workos-inc/node/worker.

    Warning on Deep Imports: Internal file structures have changed. You must stop using deep imports (e.g., importing from @workos-inc/node/lib/...) and instead use the public API surface.

    // ESM - works
    import { WorkOS } from '@workos-inc/node';
    
    // CommonJS - still works
    const { WorkOS } = require('@workos-inc/node');
    
    // Cloudflare Workers - use /worker
    import { WorkOS } from '@workos-inc/node/worker';
  2. Install the WorkOS Node.js Library

    main

    Install the @workos-inc/node package using npm. This library provides access to the WorkOS API for server-side JavaScript applications.

    Requirements

    • Node.js 22.11 or higher.
    npm install @workos-inc/node
  3. Migrate Widgets getToken to createToken

    main

    The widgets.getToken method was renamed to widgets.createToken in v9, and its return type changed from a string to an object containing the token.

    Before (v8): const token: string = await workos.widgets.getToken(options);

    After (v9): const { token }: { token: string } = await workos.widgets.createToken(options);

    // After (v9)
    const { token } = await workos.widgets.createToken({
      organizationId: 'org_123',
      userId: 'user_123',
      scopes: ['widgets:users-table:manage'],
    });
  4. Migrate Directory Sync to v8

    main

    In v8, DirectoryUser fields have moved to customAttributes to align with the API structure. Additionally, the getPrimaryEmail() utility has been removed.

    Changes:

    • Access user fields like emails, username, and jobTitle via the customAttributes object.
    • Manually access the primary email from the emails array (e.g., user.customAttributes?.emails?.[0]).
    // After (v8):
    const user = await workos.directorySync.getUser({ user: 'directory_user_123' });
    
    console.log(user.customAttributes?.emails); // Array of emails
    console.log(user.customAttributes?.username); // Username
    console.log(user.customAttributes?.jobTitle); // Job title
    
    // Manual primary email access:
    const primaryEmail = user.customAttributes?.emails?.[0];
  5. Migrate Authorization list endpoints to standardized pagination

    main

    In v9, all authorization list endpoints follow a standardized pagination flow. This includes a change in default behavior:

    • The default order is now descending.
    • Cursor behavior now matches the shared SDK paginator.

    If your code relied on the previous default cursor direction, you must explicitly pass the order parameter to maintain the same traversal order.

    Example (v9):

    const page = await workos.authorization.listOrganizationMembershipRoleAssignments({
      organizationMembershipId: 'om_123',
      order: 'desc',
    });
  6. Migrate Multi-Factor Auth and Admin Portal renames

    main

    Resource clients and their accessors have been renamed for consistency in v9.

    Class and Accessor Renames:

    FeatureOld Accessor (v8)New Accessor (v9)
    Multi-Factor Authworkos.mfaworkos.multiFactorAuth
    Admin Portalworkos.portalworkos.adminPortal

    Import Path Renames:

    • @workos-inc/node/mfa/... $\rightarrow$ @workos-inc/node/multi-factor-auth/...
    • @workos-inc/node/portal/... $\rightarrow$ @workos-inc/node/admin-portal/...
    // After (v9)
    await workos.multiFactorAuth.enrollFactor({
      type: 'totp',
      issuer: 'My App',
      user: 'user_123',
    });
    
    await workos.adminPortal.generateLink({
      organization: 'org_123',
      intent: 'sso',
    });
  7. Migrate User Management methods to v8

    main

    Several deprecated methods in the User Management module have been removed or replaced in v8.

    Method Replacements:

    • sendMagicAuthCode() $\rightarrow$ createMagicAuth()
    • sendPasswordResetEmail() $\rightarrow$ createPasswordReset()
    • refreshAndSealSessionData() $\rightarrow$ Use loadSealedSession() to get a CookieSession, then call .refresh() on that session.
    • listOrganizationMemberships() now requires either a userId or an organizationId.
    • getAuthorizationUrl(): The context field is removed; use the state parameter for client-side data instead.
    // Magic Auth
    await workos.userManagement.createMagicAuth({ email: 'user@example.com' });
    
    // Password Reset
    await workos.userManagement.createPasswordReset({ email: 'user@example.com' });
    
    // Session Refresh
    const session = workos.userManagement.loadSealedSession({
      sessionData: encryptedSession,
      cookiePassword: 'secret',
    });
    const result = await session.refresh({ organizationId: 'org_123' });
    // result.sealedSession contains the new sealed session data
    
    // List Memberships
    const memberships = await workos.userManagement.listOrganizationMemberships({
      userId: 'user_123',
    });
  8. Handle User Management GitHub provider normalization

    main

    In v9, the SDK now normalizes the GitHubOAuth provider casing during deserialization. While the WorkOS API returns GithubOAuth (lowercase 'h'), the SDK returns GitHubOAuth (uppercase 'H') to ensure compatibility with getAuthorizationUrl.

    If your code performs manual string comparisons against the provider name, update them to use the uppercase version.

    Example (v9):

    const identities = await workos.userManagement.getUserIdentities(userId);
    const github = identities.find((i) => i.provider === 'GitHubOAuth');
    
    if (github) {
      const url = workos.userManagement.getAuthorizationUrl({
        provider: github.provider,
        redirectUri: 'https://example.com/callback',
      });
    }
    const identities = await workos.userManagement.getUserIdentities(userId);
    const github = identities.find((i) => i.provider === 'GitHubOAuth');
    
    // The provider value can now be passed directly to getAuthorizationUrl
    const url = workos.userManagement.getAuthorizationUrl({
      provider: github.provider,
      redirectUri: 'https://example.com/callback',
    });
  9. Migrate to WorkOS Node SDK v9

    main

    To upgrade from v8 to v9, follow these steps:

    1. Upgrade Node.js: Ensure your environment is running Node.js 22.11.0 or newer. v9 drops support for Node.js 20.
    2. Update Package: Install the v9 version of the SDK:
      npm install @workos-inc/node@9
    3. Remove Legacy FGA: Delete any code that uses the legacy fga client.
    4. Update Method Names: Rename methods that have been moved or renamed to align with the OpenAPI specification (see specific module breaking changes in the full guide).

    If your application uses workos.authorization instead of workos.fga and does not rely on legacy authorization pagination behavior, the migration is primarily a search-and-replace task.

    npm install @workos-inc/node@9
  10. Migrate Organizations configuration to v8

    main

    Several fields have been removed from CreateOrganizationOptions and UpdateOrganizationOptions in v8.

    Changes:

    • allowProfilesOutsideOrganization: Removed. Use API settings instead.
    • domains: Removed. Use domainData instead.
    • OrganizationDomainState enum: LegacyVerified has been removed. Use verified instead.
    await workos.organizations.createOrganization({
      name: 'Acme Corp',
      domainData: [{ domain: 'example.com', state: 'verified' }],
    });
  11. Migrate methods moved to different resource clients

    main

    In v9, several methods were relocated to more appropriate resource clients. If you are upgrading, ensure you update the client accessor and check for signature changes.

    Moved from organizations

    MethodNew Client (v9)Signature Change
    listOrganizationRolesworkos.authorizationNow takes a positional organizationId string instead of an options object
    listOrganizationFeatureFlagsworkos.featureFlagsNo change
    listOrganizationApiKeysworkos.apiKeysNo change
    createOrganizationApiKeyworkos.apiKeysNo change

    Moved from userManagement

    MethodNew Client (v9)
    enrollAuthFactorworkos.multiFactorAuth.createUserAuthFactor
    listAuthFactorsworkos.multiFactorAuth.listUserAuthFactors
    listUserFeatureFlagsworkos.featureFlags.listUserFeatureFlags
    // Example: listOrganizationRoles signature change
    // After (v9)
    const roles = await workos.authorization.listOrganizationRoles('org_123');
    
    // Example: relocated method
    // After (v9)
    await workos.apiKeys.createOrganizationApiKey({
      organizationId: 'org_123',
      name: 'CI key',
    });
  12. Use Public Client Mode (Browser/Mobile/CLI)

    main

    For environments that cannot securely store secrets (like mobile apps or CLI tools), you can initialize the WorkOS client using only a clientId. This mode uses PKCE (Proof Key for Code Exchange) for secure authentication.

    Workflow

    1. Generate Authorization URL: Use getAuthorizationUrlWithPKCE to get a URL and a codeVerifier.
    2. Secure the Verifier: Store the codeVerifier securely on-device (e.g., iOS Keychain, Android Keystore, or OS credential storage) as it must survive app restarts.
    3. Exchange Code for Tokens: After the user authenticates, use authenticateWithCode with the code and the stored codeVerifier to retrieve tokens.
    import { WorkOS } from '@workos-inc/node';
    
    // Initialize without an API key
    const workos = new WorkOS({ clientId: 'client_...' });
    
    // 1. Generate auth URL with automatic PKCE
    const { url, codeVerifier } =
      await workos.userManagement.getAuthorizationUrlWithPKCE({
        provider: 'authkit',
        redirectUri: 'myapp://callback',
        clientId: 'client_...',
      });
    
    // 2. After user authenticates, exchange code for tokens
    const { accessToken, refreshToken } =
      await workos.userManagement.authenticateWithCode({
        code: authorizationCode,
        codeVerifier,
        clientId: 'client_...',
      });