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

@glideidentity/web-client-sdk

v6.0.2

Published

Glide Phone Authentication SDK for web applications

Readme

Glide Web Client SDK

The official web SDK for integrating Glide's carrier-grade phone verification into your web applications.

Features

  • 🚀 Instant Verification - Direct carrier verification without SMS delays
  • 🔐 Fraud Resistant - Can't be intercepted or spoofed like SMS codes
  • 📱 Multi-Platform - Desktop QR codes, iOS App Clips, Android deep links
  • 🎨 Customizable UI - Built-in modal with themes and view modes
  • 🔧 Flexible Architecture - Use the full SDK or just the core types
  • 🌐 Framework Support - React, Vue, Angular, and vanilla JavaScript
  • 📦 Tree-Shakeable - Import only what you need

Installation

npm install @glideidentity/web-client-sdk

Quick Start

High-Level API (Recommended)

The simplest way to integrate phone verification:

import { PhoneAuthClient, USE_CASE } from '@glideidentity/web-client-sdk';

const client = new PhoneAuthClient({
  endpoints: {
    prepare: '/api/phone-auth/prepare',
    process: '/api/phone-auth/process',
  }
});

// Get a phone number
const result = await client.authenticate({
  use_case: USE_CASE.GET_PHONE_NUMBER
});
console.log('Phone:', result.phone_number);

// Or verify a specific number
const verified = await client.authenticate({
  use_case: USE_CASE.VERIFY_PHONE_NUMBER,
  phone_number: '+14155551234'
});
console.log('Verified:', verified.verified);

Granular API

For more control over the authentication flow:

import { PhoneAuthClient, USE_CASE } from '@glideidentity/web-client-sdk';

const client = new PhoneAuthClient({
  endpoints: {
    prepare: '/api/phone-auth/prepare',
    process: '/api/phone-auth/process',
  }
});

// Step 1: Prepare the request
const prepared = await client.prepare({
  use_case: USE_CASE.VERIFY_PHONE_NUMBER,
  phone_number: '+14155551234'
});

// Step 2: Invoke authentication (shows UI based on strategy)
const invokeResult = await client.invokeSecurePrompt(prepared);
const credential = await invokeResult.credential;

// Step 3: Process the credential
const result = await client.verifyPhoneNumber(credential, invokeResult.session);

console.log('Verified:', result.verified);

Configuration

Client Options

const client = new PhoneAuthClient({
  // Required: Your backend endpoints
  endpoints: {
    prepare: '/api/phone-auth/prepare',   // Prepare request endpoint
    process: '/api/phone-auth/process',   // Process credential endpoint
    polling: '/api/phone-auth/status',    // Optional: Status polling endpoint
  },
  
  // Polling configuration
  pollingInterval: 2000,      // Polling interval in ms (default: 2000)
  maxPollingAttempts: 30,     // Max attempts before timeout (default: 30)
  timeout: 30000,             // API request timeout in ms (default: 30000)
  
  // Debug options
  debug: false,               // Enable console logging (default: false)
  devtools: {
    showMobileConsole: false  // Show on-screen console on mobile (default: false)
  }
});

Invoke Options

Customize the authentication UI and behavior:

const result = await client.invokeSecurePrompt(prepared, {
  // Prevent SDK from showing any UI (use your own)
  preventDefaultUI: false,
  
  // Polling configuration (overrides client config)
  pollingInterval: 2000,
  maxPollingAttempts: 30,
  
  // Modal customization (for desktop QR strategy)
  modalOptions: {
    theme: 'auto',              // 'dark' | 'light' | 'auto'
    viewMode: 'toggle',         // 'toggle' | 'dual' | 'pre-step'
    title: 'Scan to Verify',    // Custom title text
    description: '',            // Optional subtitle
    showCloseButton: true,      // Show X button
    closeOnBackdropClick: true, // Close on outside click
    closeOnEscape: true,        // Close on Escape key
  }
});

Modal Customization

The SDK provides a built-in modal for desktop QR code display.

View Modes

| Mode | Description | Best For | |------|-------------|----------| | toggle | Single QR with iOS/Android switch | Clean, minimal UI (default) | | dual | Side-by-side QR codes | Users who may not know their OS | | pre-step | OS selection screen first | Guided experience |

Themes

| Theme | Description | |-------|-------------| | auto | Follows system preference (default) | | dark | Dark background with light text | | light | Light background with dark text |

Custom UI

To use your own UI instead of the built-in modal:

const result = await client.invokeSecurePrompt(prepared, {
  preventDefaultUI: true
});

// For desktop strategy, display your own QR code
if (result.strategy === 'desktop') {
  // Access QR data from the prepare response
  const qrData = prepared.data;
  displayYourQRCode(qrData.ios_qr_image, qrData.android_qr_image);
  
  // Wait for credential
  const credential = await result.credential;
  
  // Or cancel if needed
  result.cancel?.();
}

Authentication Strategies

The SDK automatically selects the best strategy based on the device:

| Strategy | Platform | Description | |----------|----------|-------------| | ts43 | Android Chrome 128+ | Native Digital Credentials API | | link | iOS / Android | App Clip (iOS) or carrier app (Android) | | desktop | Desktop browsers | QR code scanned by mobile |

Strategy-Specific Handling

const result = await client.invokeSecurePrompt(prepared);

switch (result.strategy) {
  case 'ts43':
    // Android: Credential returned directly
    const credential = await result.credential;
    break;
    
  case 'link':
    // iOS: Opens App Clip, polls for completion
    // Android: Opens carrier's privileged app, polls for completion
    const credential = await result.credential;
    // Optionally cancel polling
    result.cancel?.();
    break;
    
  case 'desktop':
    // Desktop: Shows QR modal, polls for completion
    const credential = await result.credential;
    result.cancel?.();
    break;
}

Framework Integration

React

import { usePhoneAuth, USE_CASE } from '@glideidentity/web-client-sdk/react';

function PhoneVerification() {
  const { authenticate, isLoading, error, result } = usePhoneAuth({
    endpoints: {
      prepare: '/api/phone-auth/prepare',
      process: '/api/phone-auth/process',
    }
  });

  const handleVerify = async () => {
    try {
      const result = await authenticate({
        use_case: USE_CASE.VERIFY_PHONE_NUMBER,
        phone_number: '+14155551234'
      });
      console.log('Verified:', result.verified);
    } catch (err) {
      console.error('Failed:', err);
    }
  };

  return (
    <button onClick={handleVerify} disabled={isLoading}>
      {isLoading ? 'Verifying...' : 'Verify Phone'}
    </button>
  );
}

Vue

<script setup>
import { usePhoneAuth, USE_CASE } from '@glideidentity/web-client-sdk/vue';

const { authenticate, isLoading, error, result } = usePhoneAuth({
  endpoints: {
    prepare: '/api/phone-auth/prepare',
    process: '/api/phone-auth/process',
  }
});

const handleVerify = async () => {
  await authenticate({
    use_case: USE_CASE.VERIFY_PHONE_NUMBER,
    phone_number: '+14155551234'
  });
};
</script>

<template>
  <button @click="handleVerify" :disabled="isLoading">
    {{ isLoading ? 'Verifying...' : 'Verify Phone' }}
  </button>
</template>

Vanilla JavaScript (Browser)

<script src="https://unpkg.com/@glideidentity/web-client-sdk/dist/browser/web-client-sdk.min.js"></script>
<script>
  const { PhoneAuthClient, USE_CASE } = GlideWebClientSDK;
  
  const client = new PhoneAuthClient({
    endpoints: {
      prepare: '/api/phone-auth/prepare',
      process: '/api/phone-auth/process',
    }
  });
  
  document.getElementById('verify-btn').onclick = async () => {
    const result = await client.authenticate({
      use_case: USE_CASE.VERIFY_PHONE_NUMBER,
      phone_number: '+14155551234'
    });
    console.log('Verified:', result.verified);
  };
</script>

Advanced Features

Custom HTTP Headers

Add custom headers to all SDK requests:

const client = new PhoneAuthClient({
  endpoints: { ... },
  headers: {
    common: {
      'X-Custom-Header': 'your-value'
    }
  }
});

Custom Logger

Provide your own logger implementation:

const client = new PhoneAuthClient({
  endpoints: { ... },
  logger: {
    debug: (msg, data) => console.debug('[SDK]', msg, data),
    info: (msg, data) => console.info('[SDK]', msg, data),
    warn: (msg, data) => console.warn('[SDK]', msg, data),
    error: (msg, data) => console.error('[SDK]', msg, data),
  }
});

Custom HTTP Client

Bring your own HTTP client for full control:

const client = new PhoneAuthClient({
  endpoints: { ... },
  httpClient: {
    post: async (url, body, options) => {
      const response = await yourHttpLib.post(url, body, options);
      return response.data;
    },
    get: async (url, options) => {
      const response = await yourHttpLib.get(url, options);
      return response.data;
    }
  }
});

Core Package

For advanced use cases, you can import just the types and validators without the full client:

import { 
  // Types
  type PrepareRequest,
  type PrepareResponse,
  type InvokeResult,
  type SessionInfo,
  
  // Constants
  USE_CASE,
  AUTHENTICATION_STRATEGY,
  ERROR_CODES,
  
  // Validators
  validatePhoneNumber,
  validatePlmn,
  
  // Type Guards
  isTS43Strategy,
  isLinkStrategy,
  isDesktopStrategy,
  isAuthError,
} from '@glideidentity/web-client-sdk/core';

// Use validators
const { valid, error } = validatePhoneNumber('+14155551234');

// Use type guards
if (isDesktopStrategy(result)) {
  // TypeScript knows result has desktop-specific properties
}

Error Handling

import { ERROR_CODES, isAuthError } from '@glideidentity/web-client-sdk';

try {
  await client.authenticate({ ... });
} catch (error) {
  if (isAuthError(error)) {
    switch (error.code) {
      case ERROR_CODES.USER_CANCELLED:
        // User closed the modal or cancelled
        break;
      case ERROR_CODES.TIMEOUT:
        // Authentication timed out
        break;
      case ERROR_CODES.NETWORK_ERROR:
        // Network request failed
        break;
      default:
        // Handle other errors
        console.error(error.message);
    }
  }
}

Type Reference

Use Cases

type UseCase = 'GetPhoneNumber' | 'VerifyPhoneNumber';

// Or use the constant
USE_CASE.GET_PHONE_NUMBER    // 'GetPhoneNumber'
USE_CASE.VERIFY_PHONE_NUMBER // 'VerifyPhoneNumber'

Prepare Request

interface PrepareRequest {
  use_case: UseCase;
  phone_number?: string;      // Required for VerifyPhoneNumber
  parent_session_id?: string; // For cross-device flows
}

Invoke Result

interface InvokeResult {
  strategy: 'ts43' | 'link' | 'desktop';
  session: SessionInfo;
  credential: Promise<AuthCredential>;
  cancel?: () => void;  // Available for link and desktop
}

Responses

interface GetPhoneNumberResponse {
  phone_number: string;
}

interface VerifyPhoneNumberResponse {
  phone_number: string;
  verified: boolean;
}

Browser Support

| Browser | Strategy | Requirements | |---------|----------|--------------| | Chrome Android 128+ | TS43 | Digital Credentials API | | Safari iOS | Link | App Clips support | | Chrome/Edge/Firefox Desktop | Desktop | Any modern version |

Support

License

MIT