{"id":18896473,"url":"https://github.com/descope/descope-react-native","last_synced_at":"2025-08-16T16:12:46.845Z","repository":{"id":199491777,"uuid":"698681264","full_name":"descope/descope-react-native","owner":"descope","description":"React Native library used to integrate with Descope","archived":false,"fork":false,"pushed_at":"2025-08-14T15:31:03.000Z","size":2391,"stargazers_count":27,"open_issues_count":50,"forks_count":3,"subscribers_count":13,"default_branch":"main","last_synced_at":"2025-08-14T17:27:22.214Z","etag":null,"topics":["react-native","sdk"],"latest_commit_sha":null,"homepage":"https://www.descope.com/","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/descope.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2023-09-30T16:30:54.000Z","updated_at":"2025-07-30T20:14:14.000Z","dependencies_parsed_at":"2024-05-21T09:29:47.591Z","dependency_job_id":"98391e59-ec74-4b44-a163-62a676c8d616","html_url":"https://github.com/descope/descope-react-native","commit_stats":null,"previous_names":["descope/descope-react-native"],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/descope/descope-react-native","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/descope%2Fdescope-react-native","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/descope%2Fdescope-react-native/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/descope%2Fdescope-react-native/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/descope%2Fdescope-react-native/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/descope","download_url":"https://codeload.github.com/descope/descope-react-native/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/descope%2Fdescope-react-native/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":270735868,"owners_count":24636437,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-16T02:00:11.002Z","response_time":91,"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":["react-native","sdk"],"created_at":"2024-11-08T08:34:06.121Z","updated_at":"2025-08-16T16:12:46.801Z","avatar_url":"https://github.com/descope.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Descope SDK for React Native\n\nThe Descope SDK for React Native provides convenient access to Descope for an application written on top of React Native. You can read more on the [Descope Website](https://descope.com).\n\n## Requirements\n\n- A Descope `Project ID` is required for using the SDK. Find it on the [project page in the Descope Console](https://app.descope.com/settings/project).\n\n## Installing the SDK\n\nInstall the package with:\n\n```bash\nyarn add @descope/react-native-sdk\n# or\nnpm i --save @descope/react-native-sdk\n```\n\nWhen targeting iOS, make sure to navigate into the `ios` folder and install the dependencies:\n\n```bash\npod install\n```\n\n## Usage\n\n### Wrap your app with Auth Provider\n\n```js\nimport { AuthProvider } from '@descope/react-native-sdk'\n\nconst AppRoot = () =\u003e {\n  return (\n    \u003cAuthProvider\n      projectId=\"my-project-id\"\n      // If the Descope project manages the token response in cookies, a custom domain\n      // must be configured (e.g., https://auth.app.example.com)\n      // and should be set as the baseUrl property.\n      // baseUrl = \"https://auth.app.example.com\"\n    \u003e\n      \u003cApp /\u003e\n    \u003c/AuthProvider\u003e\n  )\n}\n```\n\n## Session Management\n\nThe `useSession` hook is used to manage an authenticated user session for an application.\n\nThe session manager takes care of loading and saving the session as well\nas ensuring that it's refreshed when needed. When the user completes a sign\nin flow successfully you should set the `DescopeSession` as the\nactive session of the session manager.\n\n```js\nimport { useDescope, useSession } from '@descope/react-native-sdk'\n\nconst descope = useDescope()\nconst { manageSession } = useSession()\n\nconst resp = await descope.otp.email.verify('andy@example.com', '123456')\nmanageSession(resp.data)\n```\n\nThe session manager can then be used at any time to ensure the session\nis valid and to authenticate outgoing requests to your backend with a\nbearer token authorization header.\n\n```js\nconst { session } = useSession()\n\nconst res = await fetch('/path/to/server/api', {\n  headers: {\n    Authorization: `Bearer ${session.sessionJwt}`,\n  },\n})\n```\n\nWhen the application is relaunched the `AuthProvider` component will automatically load any existing\nsession. Once the `isSessionLoading` flag is `false`, you can check if there's a session available (i.e. an authenticated user).\n\nWhen the user wants to sign out of the application we revoke the\nactive session and clear it from the session manager:\n\n```js\nimport { useDescope, useSession } from '@descope/react-native-sdk'\n\nconst descope = useDescope()\nconst { session, clearSession } = useSession()\n\nawait descope.logout(session.refreshJwt)\nawait clearSession(resp.data)\n```\n\n### Accessing the Session\n\nThe session information can be accessed via the `useSession` hook, but also it might be convenient\nto use the `getCurrentSessionToken()`, `getCurrentRefreshToken()` and `getCurrentUser()` helper functions.\nThese functions are available outside of the component render-lifecycle.\nThis might be useful, for example, to add an authorization header to all authenticated requests.\n\n### Refreshing the Session\n\nThe guiding principal of refreshing the session is the same, regardless of any specific\napp architecture or network framework.\n\nBefore every authenticated request, add your authorization header to the request the way your server\nexpects to receive it. As an optimization it is also possible to call `refreshSessionIfAboutToExpire()`.\nThis async function will preemptively refresh the session token if it is about to expire, or already expired.\nThat code might look something like this:\n\n```js\n// ... before every authenticated request\ntry {\n  // refresh if needed\n  await refreshSessionIfAboutToExpire()\n} catch (e) {\n  // fail silently - as this shouldn't affect the request being performed\n}\n\n// add authorization header\nrequest.headers.Authorization = `Bearer ${getCurrentSessionToken()}`\n```\n\nAfter every error response - if the server responds that the session token is invalid, i.e.\n`401` or your equivalent, try to refresh the session token and repeat the request. Otherwise,\nclear the session and prompt the user to re-authenticate.\nThat code might look something like this\n\n```js\n// ... on every error response\n// assuming 401 is returned ONLY when the session JWT is invalid\nif (error.status === 401) {\n  try {\n    const resp = await descope.refresh(getCurrentRefreshToken())\n    await updateTokens(resp.data.sessionJwt, resp.data.refreshJwt)\n\n    // you can now retry the original request\n    // NEED TO MAKE SURE THAT THIS RETRY IS ONLY PERFORMED ONCE\n    // otherwise, an endless loop of failed requests might occur\n    retryRequest()\n  } catch (e) {\n    // clear the session as the user must re-authenticate\n  }\n}\n```\n\n**IMPORTANT NOTE**: if you find the need to pass a reference to the `refreshSessionIfAboutToExpire()`\n`updateTokens()` and `descope` from the `useSession` hook into some network component, make sure\nit is done in a lifecycle aware method.\nThat code might look something like this:\n\n```js\nconst descope = useDescope()\nconst { isSessionLoading, refreshSessionIfAboutToExpire, updateTokens } = useSession()\n\nReact.useEffect(() =\u003e {\n  if (!isSessionLoading) {\n    setUpNetworkRefresh(refreshSessionIfAboutToExpire, updateTokens, descope)\n  }\n}, [isSessionLoading refreshSessionIfAboutToExpire, updateTokens, descope])\n```\n\n## Running Flows\n\nWe can authenticate users by building and running Flows. Flows are built in the Descope\n[flow editor](https://app.descope.com/flows). The editor allows you to easily\ndefine both the behavior and the UI that take the user through their\nauthentication journey. Read more about it in the Descope\n[getting started](https://docs.descope.com/build/guides/gettingstarted/) guide.\n\n### Setup #1: Define and host your flow\n\nBefore we can run a flow, it must first be defined and hosted. Every project\ncomes with predefined flows out of the box. You can customize your flows to suit your needs\nand host it. Follow\nthe [getting started](https://docs.descope.com/build/guides/gettingstarted/) guide for more details.\nYou can host the flow yourself or leverage Descope's hosted flow page. Read more about it [here](https://docs.descope.com/customize/auth/oidc/#hosted-flow-application).\nYou can also check out the [auth-hosting repo itself](https://github.com/descope/auth-hosting).\n\n### (OPTIONAL) Setup #2.1: Enable App Links for Magic Link and OAuth (social) on Android\n\nSome authentication methods rely on leaving the application's context to authenticate the\nuser, such as navigating to an identity provider's website to perform OAuth (social) authentication,\nor receiving a Magic Link via email or text message. If you do not intend to use these authentication\nmethods, you can skip this step. Otherwise, in order for the user to get back\nto your application, setting up [App Links](https://developer.android.com/training/app-links#android-app-links) is required.\nOnce you have a domain set up and [verified](https://developer.android.com/training/app-links/verify-android-applinks) for sending App Links,\nyou'll need to handle the incoming deep links in your app, and resume the flow.\n\n### (OPTIONAL) Setup #2.2: Support Magic Link Redirects on iOS\n\nSupporting Magic Link authentication in flows requires some platform specific setup:\nYou'll need to [support associated domains](https://developer.apple.com/documentation/xcode/supporting-associated-domains?language=swift).\n\nRegardless of the platform, another path is required to handle magic link redirects specifically. For the sake of this README, let's name\nit `/magiclink`\n\n#### Define deep link handling\n\n_this code example demonstrates how app links should be handled - you can customize it to fit your app_\n\n```js\nimport { FlowView } from '@descope/react-native-sdk'\n\nconst [deepLink, setDeepLink] = useState('')\n\nuseEffect(() =\u003e {\n  Linking.addEventListener('url', async (event) =\u003e {\n    if (event.url === 'https://my-deep-link-for-authenticating.com') {\n      setDeepLink(event.url)\n    }\n  })\n  return () =\u003e {\n    Linking.removeAllListeners('url')\n  }\n})\n```\n\n#### Add a matching Manifest declaration (Android)\n\n```xml\n\u003cactivity\n        android:name=\".MainActivity\"\n        android:exported=\"true\"\n        android:launchMode=\"singleTask\"\n        android:theme=\"@style/LaunchTheme\"\n        android:configChanges=\"orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode\"\n        android:hardwareAccelerated=\"true\"\n        android:windowSoftInputMode=\"adjustResize\"\u003e\n\n    \u003c!-- add the following at the end of the activity tag, after anything you have defined currently --\u003e\n\n    \u003cintent-filter android:autoVerify=\"true\"\u003e \u003c!-- autoVerify required for app links --\u003e\n        \u003caction android:name=\"android.intent.action.VIEW\" /\u003e\n        \u003ccategory android:name=\"android.intent.category.DEFAULT\" /\u003e\n        \u003ccategory android:name=\"android.intent.category.BROWSABLE\" /\u003e\n        \u003c!-- replace with your host, the path can change must must be reflected when running the flow --\u003e\n        \u003c!-- the path should correspond with the routing path defined above --\u003e\n        \u003cdata android:scheme=\"https\" android:host=\"\u003cYOUR_HOST_HERE\u003e\" android:path=\"/auth\" /\u003e\n        \u003c!-- see magic link setup below for more details --\u003e\n        \u003cdata android:scheme=\"https\" android:host=\"\u003cYOUR_HOST_HERE\u003e\" android:path=\"/magiclink\" /\u003e\n    \u003c/intent-filter\u003e\n\n    \u003c!-- Optional: App Links are blocked by default on Opera and some other browsers. Add a custom scheme for that use case specifically --\u003e\n    \u003cintent-filter android:autoVerify=\"true\"\u003e\n        \u003caction android:name=\"android.intent.action.VIEW\" /\u003e\n        \u003ccategory android:name=\"android.intent.category.DEFAULT\" /\u003e\n        \u003ccategory android:name=\"android.intent.category.BROWSABLE\" /\u003e\n\n        \u003c!-- replace with something unique. this will only be used as a backup for Opera and some other browsers. --\u003e\n        \u003cdata android:scheme=\"myapp\" android:host=\"auth\" /\u003e\n    \u003c/intent-filter\u003e\n\u003c/activity\u003e\n```\n\n### Run a Flow\n\nAfter completing the prerequisite steps, it is now possible to run a flow.\nThe flow will run in a dedicated `FlowView` component which receives `FlowOptions`.\nThe `FlowOptions` defines all of the options available when running a flow on both\nAndroid and iOS. Read the component documentation for a detailed explanation.\n\n```js\nimport { FlowView } from '@descope/react-native-sdk'\n\nconst { manageSession } = useSession()\n\nconst flowUrl = 'https://myflowUrl.com'\n\n\u003cFlowView\n  style={styles.fill}\n  flowOptions={{\n      url: flowUrl,\n      androidOAuthNativeProvider: 'google',\n      iosOAuthNativeProvider: 'apple',\n      // any other options go here\n  }}\n  deepLink={deepLink} // the optional deep link we defined earlier via `useState`\n  onReady={() =\u003e {\n    // logic to display the flow when it's ready\n  }}\n  onSuccess={async (jwtResponse) =\u003e {\n    try {\n      await manageSession(jwtResponse)\n    } catch (e) {\n      // handle session management error\n    }\n  }}\n  onError={(error: string) =\u003e {\n    // handle flow errors here\n  }}\n/\u003e\n```\n\n## Use the `useDescope` and `useSession` hooks in your components in order to get authentication state, user details and utilities\n\nThis can be helpful to implement application-specific logic. Examples:\n\n- Render different components if current session is authenticated\n- Render user's content\n- Logout button\n\n```js\nimport { useDescope, useSession } from '@descope/react-native-sdk'\nimport { useCallback } from 'react'\n\nconst App = () =\u003e {\n  // NOTE - `useDescope`, `useSession`, should be used inside `AuthProvider` context,\n  // and will throw an exception if this requirement is not met\n  const { session } = useSession()\n  const { logout } = useDescope()\n\n  const handleLogout = useCallback(() =\u003e {\n    logout()\n  }, [logout])\n\n  if (session) {\n    return (\n      \u003c\u003e\n        \u003cp\u003eHello {session.user.name}\u003c/p\u003e\n        \u003cbutton onClick={handleLogout}\u003eLogout\u003c/button\u003e\n      \u003c/\u003e\n    )\n  }\n\n  return \u003cp\u003eYou are not logged in\u003c/p\u003e\n}\n```\n\n**For more SDK usage examples refer to [docs](https://docs.descope.com/build/guides/client_sdks/)**\n\n## Learn More\n\nTo learn more please see the [Descope Documentation and API reference page](https://docs.descope.com/).\n\n## Contact Us\n\nIf you need help you can email [Descope Support](mailto:support@descope.com)\n\n## License\n\nThe Descope SDK for React Native is licensed for use under the terms and conditions of the [MIT license Agreement](./LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdescope%2Fdescope-react-native","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdescope%2Fdescope-react-native","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdescope%2Fdescope-react-native/lists"}