expoClient type error in monorepo when used outside of expo app

I have a turborepo with package folder named auth which has better-auth setup to import into my expo and next.js apps.
// mobile-auth-client.ts
import { createAuthClient } from "better-auth/react";
import { expoClient } from "@better-auth/expo/client";
import { phoneNumberClient, usernameClient } from "better-auth/client/plugins";
import * as SecureStore from "expo-secure-store";
import type { BetterAuthClientPlugin } from "better-auth";

interface MobileAuthClientConfig {
baseURL: string;
storagePrefix?: string;
scheme?: string;
}

/**
* Temp compatibility wrapper aligns `expoClient` with the
* `BetterAuthClientPlugin` signature expected
* (adds the unused `options` parameter to `getActions`).
*/
function expoClientCompat(options: Parameters<typeof expoClient>[0]): BetterAuthClientPlugin {
const plugin = expoClient(options);
return {
...plugin,
getActions($fetch, $store, _options) {
// `expoClient`'s getActions ignores the 3rd param; passing only the required ones.
// eslint-disable-next-line @typescript-eslint/no-explicit-any
return (plugin as unknown as { getActions: (f: any, s: any) => Record<string, unknown> }).getActions(
$fetch,
$store,
);
},
} satisfies BetterAuthClientPlugin;
}

export function createMobileAuthClient({
baseURL,
scheme = "betterpuck",
storagePrefix = "betterpuck",
}: MobileAuthClientConfig): ReturnType<typeof createAuthClient> {
const sanitizedBaseURL = baseURL.endsWith("/")
? baseURL.slice(0, -1)
: baseURL;

return createAuthClient({
baseURL: sanitizedBaseURL,
plugins: [
// Expo integration with secure storage
expoClientCompat({
scheme,
storagePrefix,
storage: SecureStore,
}),
// Phone number authentication
phoneNumberClient(),
// Username authentication
usernameClient(),
],
});
}

export type MobileAuthClient = ReturnType<typeof createMobileAuthClient>;
// mobile-auth-client.ts
import { createAuthClient } from "better-auth/react";
import { expoClient } from "@better-auth/expo/client";
import { phoneNumberClient, usernameClient } from "better-auth/client/plugins";
import * as SecureStore from "expo-secure-store";
import type { BetterAuthClientPlugin } from "better-auth";

interface MobileAuthClientConfig {
baseURL: string;
storagePrefix?: string;
scheme?: string;
}

/**
* Temp compatibility wrapper aligns `expoClient` with the
* `BetterAuthClientPlugin` signature expected
* (adds the unused `options` parameter to `getActions`).
*/
function expoClientCompat(options: Parameters<typeof expoClient>[0]): BetterAuthClientPlugin {
const plugin = expoClient(options);
return {
...plugin,
getActions($fetch, $store, _options) {
// `expoClient`'s getActions ignores the 3rd param; passing only the required ones.
// eslint-disable-next-line @typescript-eslint/no-explicit-any
return (plugin as unknown as { getActions: (f: any, s: any) => Record<string, unknown> }).getActions(
$fetch,
$store,
);
},
} satisfies BetterAuthClientPlugin;
}

export function createMobileAuthClient({
baseURL,
scheme = "betterpuck",
storagePrefix = "betterpuck",
}: MobileAuthClientConfig): ReturnType<typeof createAuthClient> {
const sanitizedBaseURL = baseURL.endsWith("/")
? baseURL.slice(0, -1)
: baseURL;

return createAuthClient({
baseURL: sanitizedBaseURL,
plugins: [
// Expo integration with secure storage
expoClientCompat({
scheme,
storagePrefix,
storage: SecureStore,
}),
// Phone number authentication
phoneNumberClient(),
// Username authentication
usernameClient(),
],
});
}

export type MobileAuthClient = ReturnType<typeof createMobileAuthClient>;
No description
No description
No description
1 Reply
jins
jinsOP2mo ago
If I use expoClient in my auth package (outside of the expo app) as outlined in the docs I get a type error. It seems like the expoClient has a type signature incompatibility with BetterAuthClientPlugin: * expoClient.getActions expects 2 parameters: ($fetch, $store) * BetterAuthClientPlugin expects 3 parameters: ($fetch, $store, options) If I setup the auth-client in the expo app exactly like the docs there is no type error. https://www.better-auth.com/docs/integrations/expo actually my workaround also results in getCookie() being removed from the authClient type. Property 'getCookie' does not exist on type '{ signIn: { social: <FetchOptions extends { method?: string | undefined; headers?: (HeadersInit & (HeadersInit | CommonHeaders)) | undefined; cache?: RequestCache | undefined; ... 31 more ...; disableValidation?: boolean | undefined; }>(data_0: Prettify<...>, data_1?: FetchOptions | undefined) => Promise<...>; }; } ...'.

Did you find this page helpful?