Migrate email, SMS, social, passkey, and external-JWT sign-in from the React SDK to the JavaScript SDK.
Non-wallet auth methods carry over, but each becomes an explicit call (or pair of calls) instead of a context that manages the flow for you. This page maps each React SDK API to its JavaScript SDK equivalent and links to the full implementation guide for each.
The React SDK’s useConnectWithOtp bundled sending and verifying. In the JavaScript SDK these are two explicit steps: send the code, then verify it. Sending returns an otpVerification handle that you pass to verifyOTP.
This is the change most likely to break a migration. In the React SDK, OAuth redirect detection was automatic — the SDK inspected the URL on mount and completed sign-in for you. In the JavaScript SDK, you must complete the redirect yourself on every app load, or returning users never finish signing in.
Start sign-in with signInWithSocialRedirect, then on the page the provider returns to, detect and complete the callback.
Passkey sign-in keeps the same hook name. Registration is a separate explicit call.
React SDK
JavaScript SDK
useSignInWithPasskey()
signInWithPasskey() / useSignInWithPasskey()
passkey registration (via sync flow)
registerPasskey() / useRegisterPasskey()
registerPasskey() requests a Credentiallink elevated access token the same way registerTotpMfaDevice() does (see Registering or removing a device needs an elevated token) — expect it to need a checkStepUpAuth({ scope: TokenScope.Credentiallink }) check beforehand if the user doesn’t already hold one.
unlinkSocialAccount() requires a Credentialunlink elevated access token — there’s no legacy fallback, so it 403s (Elevated access token required) if you call it directly. Check with checkStepUpAuth({ scope: TokenScope.Credentialunlink }) first and, if required, re-verify the user with an existing credential (email OTP, TOTP, passkey, or a connected wallet), passing requestedScopes: [TokenScope.Credentialunlink] on that call. See Registering or removing a device needs an elevated token for the full pattern — it’s the same mechanism.
TypeScript
import { checkStepUpAuth, sendEmailOTP, verifyOTP, unlinkSocialAccount, TokenScope,} from '@dynamic-labs-sdk/client';async function unlink(verifiedCredentialId: string) { const { isRequired } = await checkStepUpAuth({ scope: TokenScope.Credentialunlink, }); if (isRequired) { // Re-verify with an existing credential — email OTP shown here. const otpVerification = await sendEmailOTP({ email }); const code = await promptForCode(); // your implementation await verifyOTP({ otpVerification, verificationToken: code, requestedScopes: [TokenScope.Credentialunlink], }); } // The elevated token from above is picked up automatically. await unlinkSocialAccount({ verifiedCredentialId });}
Signing in no longer runs onboarding, MFA, device registration, or wallet creation for you. Run those steps yourself once auth resolves — see Post-login user setup.