{"id":50999024,"url":"https://github.com/workos/expo-authkit-example","last_synced_at":"2026-06-20T12:34:23.612Z","repository":{"id":339019109,"uuid":"1134453472","full_name":"workos/expo-authkit-example","owner":"workos","description":"An example of using AuthKit in an Expo app.","archived":false,"fork":false,"pushed_at":"2026-02-17T15:45:33.000Z","size":304,"stargazers_count":2,"open_issues_count":2,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-02-17T20:37:17.865Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/workos.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-01-14T18:34:06.000Z","updated_at":"2026-02-17T15:45:30.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/workos/expo-authkit-example","commit_stats":null,"previous_names":["workos/expo-authkit-example"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/workos/expo-authkit-example","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/workos%2Fexpo-authkit-example","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/workos%2Fexpo-authkit-example/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/workos%2Fexpo-authkit-example/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/workos%2Fexpo-authkit-example/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/workos","download_url":"https://codeload.github.com/workos/expo-authkit-example/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/workos%2Fexpo-authkit-example/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34570538,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-20T02:00:06.407Z","response_time":98,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-06-20T12:34:22.909Z","updated_at":"2026-06-20T12:34:23.605Z","avatar_url":"https://github.com/workos.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Expo AuthKit Example\n\nA React Native Expo example demonstrating secure authentication with WorkOS AuthKit using PKCE (Proof Key for Code Exchange).\n\nhttps://github.com/user-attachments/assets/08fa87b3-4b8c-43be-8a70-f85c0ffb23c8\n\n## Features\n\n- 🔐 **Secure PKCE Authentication** - No client secrets in the app\n- 📱 **Native Deep Linking** - Seamless OAuth callback handling\n- 🔒 **Secure Token Storage** - Uses Expo SecureStore (hardware-backed)\n- 🔄 **Automatic Token Refresh** - Transparent session management\n- 🎨 **React Native Paper UI** - Material Design components\n- 🔧 **Uses Official WorkOS SDK** - Full `@workos-inc/node` support via WebCrypto polyfill\n\n## Prerequisites\n\n- [Node.js](https://nodejs.org/) 18+\n- [Expo CLI](https://docs.expo.dev/get-started/installation/)\n- [WorkOS Account](https://workos.com) with AuthKit configured\n- iOS Simulator or Android Emulator (development build required)\n\n## Setup\n\n### 1. Install Dependencies\n\n```bash\nnpm install\n```\n\n### 2. WebCrypto Polyfill (Critical)\n\nThe `@workos-inc/node` SDK uses WebCrypto APIs (`crypto.subtle`) for PKCE. React Native doesn't provide these natively, so we use `react-native-quick-crypto`:\n\n```bash\nnpm install react-native-quick-crypto\n```\n\n**Why is this needed?** The WorkOS SDK's `getAuthorizationUrlWithPKCE()` uses `crypto.subtle.digest()` for SHA-256 hashing. This polyfill provides a native C++/JSI implementation of the full WebCrypto API.\n\n**Important:** The polyfill must be installed before any other code runs:\n\n```typescript\n// index.ts (app entry point)\nimport './src/polyfills'; // Must be FIRST import!\nimport { registerRootComponent } from 'expo';\nimport App from './App';\nregisterRootComponent(App);\n```\n\n```typescript\n// src/polyfills.ts\nimport { install } from 'react-native-quick-crypto';\ninstall();\n```\n\n### 3. Configure WorkOS\n\n1. Copy the environment template:\n\n   ```bash\n   cp .env.example .env\n   ```\n\n2. Add your WorkOS Client ID to `.env`:\n\n   ```\n   EXPO_PUBLIC_WORKOS_CLIENT_ID=client_XXXXXXXXX\n   ```\n\n3. Add the redirect URI to your [WorkOS Dashboard](https://dashboard.workos.com/configuration):\n   ```\n   workos-authkit-example://callback\n   ```\n\n### 4. Create a Development Build\n\n**Important:** A development build is required for two reasons:\n\n1. Expo Go cannot handle custom URL schemes for OAuth callbacks\n2. The `react-native-quick-crypto` polyfill requires native code compilation\n\n```bash\n# iOS\nnpx expo run:ios\n\n# Android\nnpx expo run:android\n```\n\n## Running the App\n\nAfter creating a development build:\n\n```bash\nnpx expo start --dev-client\n```\n\n## Project Structure\n\n```\nexpo-authkit-example/\n├── index.ts                    # Entry point (loads polyfills first!)\n├── App.tsx                     # Main app with navigation\n├── app.json                    # Expo config (scheme defined here)\n├── src/\n│   ├── polyfills.ts           # WebCrypto polyfill for WorkOS SDK\n│   ├── lib/\n│   │   └── auth.ts            # Core auth logic (uses WorkOS SDK)\n│   ├── context/\n│   │   └── AuthContext.tsx    # Shared auth state provider\n│   ├── hooks/\n│   │   └── useAuth.ts         # Re-exports from context\n│   └── components/\n│       ├── SignInButton.tsx   # Sign in/out button\n│       ├── Home.tsx           # Home view\n│       ├── Account.tsx        # Account view (authenticated)\n│       └── Footer.tsx         # WorkOS branding\n```\n\n## How It Works\n\n### Authentication Flow\n\n1. **Sign In**: User taps \"Sign In\" → Opens browser with PKCE-protected WorkOS auth URL\n2. **Authenticate**: User authenticates with their Identity Provider\n3. **Callback**: WorkOS redirects to `workos-authkit-example://callback?code=...`\n4. **Token Exchange**: App exchanges code for tokens using stored PKCE verifier\n5. **Session Storage**: Tokens stored securely in Expo SecureStore\n\n### Key Security Features\n\n| Feature          | Implementation                                             |\n| ---------------- | ---------------------------------------------------------- |\n| No client secret | PKCE flow via WorkOS SDK's `getAuthorizationUrlWithPKCE()` |\n| Secure storage   | Expo SecureStore (Keychain/Keystore)                       |\n| Token refresh    | WorkOS SDK's `authenticateWithRefreshToken()`              |\n| CSRF protection  | State parameter in OAuth flow                              |\n| Native crypto    | `react-native-quick-crypto` (C++/JSI, not JS)              |\n\n## Comparison with Electron Example\n\nThis example mirrors the [electron-authkit-example](../electron-authkit-example) architecture:\n\n| Electron               | Expo                                 |\n| ---------------------- | ------------------------------------ |\n| `electron-store`       | `expo-secure-store`                  |\n| `shell.openExternal()` | `WebBrowser.openAuthSessionAsync()`  |\n| Protocol handlers      | `expo-linking` deep links            |\n| IPC for auth           | Direct function calls                |\n| Native Node.js crypto  | `react-native-quick-crypto` polyfill |\n\n## Troubleshooting\n\n### \"ReferenceError: Property 'crypto' doesn't exist\" or \"Cannot read property 'digest' of undefined\"\n\nThe WebCrypto polyfill isn't loading. Check:\n\n1. `react-native-quick-crypto` is installed\n2. The polyfill import is the **FIRST** line in your entry file (before any other imports)\n3. You've done a native rebuild after installing (`npx expo run:ios`)\n\n```typescript\n// ✅ Correct - polyfill FIRST\nimport './src/polyfills';\nimport { registerRootComponent } from 'expo';\n\n// ❌ Wrong - other imports before polyfill\nimport { registerRootComponent } from 'expo';\nimport './src/polyfills'; // Too late!\n```\n\n### \"Invariant Violation: Linking requires a build-time setting scheme\"\n\nYou need a development build. Expo Go doesn't support custom schemes or native modules:\n\n```bash\nnpx expo run:ios  # or run:android\n```\n\n### OAuth callback not working\n\n1. Verify the redirect URI in WorkOS Dashboard matches `workos-authkit-example://callback`\n2. Ensure `scheme` is set in `app.json`\n3. Check you're using a development build, not Expo Go\n\n### Auth state not updating across components\n\nIf signing in doesn't update all components (e.g., header button still shows \"Sign In\"):\n\n- Ensure all components use `useAuth()` from the same context\n- The app must be wrapped in `\u003cAuthProvider\u003e` (see `App.tsx`)\n\n### Token refresh failing\n\nThe refresh token may have expired. Clear the app data and sign in again.\n\n## Resources\n\n- [WorkOS AuthKit Documentation](https://workos.com/docs/authkit)\n- [react-native-quick-crypto](https://github.com/margelo/react-native-quick-crypto) - WebCrypto polyfill for React Native\n- [Expo SecureStore](https://docs.expo.dev/versions/latest/sdk/securestore/)\n- [Expo WebBrowser](https://docs.expo.dev/versions/latest/sdk/webbrowser/)\n- [Expo Linking](https://docs.expo.dev/versions/latest/sdk/linking/)\n- [OAuth 2.0 PKCE](https://datatracker.ietf.org/doc/html/rfc7636)\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fworkos%2Fexpo-authkit-example","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fworkos%2Fexpo-authkit-example","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fworkos%2Fexpo-authkit-example/lists"}