The inferred type of 'auth' cannot be named without a reference to '.pnpm/jose@6.1.0/node_modules/jose'. This is likely not portable. A type annotation is necessary.ts(2742) #1926

Closed
opened 2026-03-13 09:12:56 -05:00 by GiteaMirror · 9 comments
Owner

Originally created by @bernardoforcillo on GitHub (Sep 14, 2025).

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

  1. create a monorepo project where betterauth client (server) is istantiated from a package(ie, core)
  2. add to it plugins
  3. use in any other package

Current vs. Expected behavior

So for not throw the syntax error i need to infer like this betterauth const auth: ReturnType<typeof betterAuth> = betterAuth({...}) but with this i lose betterauth typed with choosed plugins...

What version of Better Auth are you using?

1.3.9

System info

{
  "system": {
    "platform": "linux",
    "arch": "x64",
    "version": "#1 SMP PREEMPT_DYNAMIC Sat Aug 23 17:02:17 UTC 2025",
    "release": "6.16.3-200.fc42.x86_64",
    "cpuCount": 8,
    "cpuModel": "AMD Ryzen 5 3500U with Radeon Vega Mobile Gfx",
    "totalMemory": "6.69 GB",
    "freeMemory": "1.05 GB"
  },
  "node": {
    "version": "v24.3.0",
    "env": "development"
  },
  "packageManager": {
    "name": "pnpm",
    "version": "10.15.1"
  },
  "frameworks": null,
  "databases": null,
  "betterAuth": {
    "version": "0.0.0",
    "config": null
  }
}

Which area(s) are affected? (Select all that apply)

Backend

Auth config (if applicable)

import { database } from '@monorepo/database/client';
import { betterAuth } from 'better-auth';
import { drizzleAdapter } from 'better-auth/adapters/drizzle';
import { admin, jwt } from 'better-auth/plugins';
import { accessControl, roles } from '~/configs/permissions';

const auth = betterAuth({
  appName: '',
  database: drizzleAdapter(database, {
    provider: 'pg',
    usePlural: true,
  }),
  logger: {
    level: 'debug',
  },
  advanced: {
    cookiePrefix: '',
  },
  plugins: [
    admin({
      accessControl,
      roles: {
        ...roles,
      },
      defaultRole: 'user',
      adminRoles: ['admin'],
    }),
    jwt({
      jwks: {
        keyPairConfig: {
          alg: 'EdDSA',
          crv: 'Ed25519',
        },
      },
      jwt: {
        definePayload(session) {
          return {
            sub: session.user.id,
            email: session.user.email,
            session: session.session.id,
            role: session.user.role,
            banned: session.user.banned,
          };
        },
        expirationTime: '7d',
      },
    }),
  ],
  emailAndPassword: {
    enabled: true,
    // TODO: send reset password email with Better Auth generated URL
    async sendResetPassword({ user, url /*, token*/ }, request) {
      console.log(`Sending reset password email to: ${user.email}`);
      console.log(url);
    },
    async onPasswordReset({ user }, request) {
      // optional: log or trigger side-effects
      console.log(`Password reset for: ${user.email}`);
    },
  },
});

export { auth };

Additional context

I want roles (or any additioan plugin addon to user) in getSession output and related.

Originally created by @bernardoforcillo on GitHub (Sep 14, 2025). ### Is this suited for github? - [ ] Yes, this is suited for github ### To Reproduce 1) create a monorepo project where betterauth client (server) is istantiated from a package(ie, core) 2) add to it plugins 3) use in any other package ### Current vs. Expected behavior So for not throw the syntax error i need to infer like this betterauth `const auth: ReturnType<typeof betterAuth> = betterAuth({...})` but with this i lose betterauth typed with choosed plugins... ### What version of Better Auth are you using? 1.3.9 ### System info ```bash { "system": { "platform": "linux", "arch": "x64", "version": "#1 SMP PREEMPT_DYNAMIC Sat Aug 23 17:02:17 UTC 2025", "release": "6.16.3-200.fc42.x86_64", "cpuCount": 8, "cpuModel": "AMD Ryzen 5 3500U with Radeon Vega Mobile Gfx", "totalMemory": "6.69 GB", "freeMemory": "1.05 GB" }, "node": { "version": "v24.3.0", "env": "development" }, "packageManager": { "name": "pnpm", "version": "10.15.1" }, "frameworks": null, "databases": null, "betterAuth": { "version": "0.0.0", "config": null } } ``` ### Which area(s) are affected? (Select all that apply) Backend ### Auth config (if applicable) ```typescript import { database } from '@monorepo/database/client'; import { betterAuth } from 'better-auth'; import { drizzleAdapter } from 'better-auth/adapters/drizzle'; import { admin, jwt } from 'better-auth/plugins'; import { accessControl, roles } from '~/configs/permissions'; const auth = betterAuth({ appName: '', database: drizzleAdapter(database, { provider: 'pg', usePlural: true, }), logger: { level: 'debug', }, advanced: { cookiePrefix: '', }, plugins: [ admin({ accessControl, roles: { ...roles, }, defaultRole: 'user', adminRoles: ['admin'], }), jwt({ jwks: { keyPairConfig: { alg: 'EdDSA', crv: 'Ed25519', }, }, jwt: { definePayload(session) { return { sub: session.user.id, email: session.user.email, session: session.session.id, role: session.user.role, banned: session.user.banned, }; }, expirationTime: '7d', }, }), ], emailAndPassword: { enabled: true, // TODO: send reset password email with Better Auth generated URL async sendResetPassword({ user, url /*, token*/ }, request) { console.log(`Sending reset password email to: ${user.email}`); console.log(url); }, async onPasswordReset({ user }, request) { // optional: log or trigger side-effects console.log(`Password reset for: ${user.email}`); }, }, }); export { auth }; ``` ### Additional context I want roles (or any additioan plugin addon to user) in getSession output and related.
Author
Owner

@dosubot[bot] commented on GitHub (Sep 14, 2025):

Hi @bernardoforcillo! I'm Dosu and I’m helping the better-auth team.

Yes, this issue is suited for GitHub—it's a known TypeScript problem in monorepo setups with Better Auth, especially when using plugins like admin or jwt. The error happens because TypeScript tries to infer a type that references internal modules (like jose), which aren't portable across package boundaries. This is common when declaration: true and composite: true are set in your tsconfig.json 1 2 3.

Using ReturnType<typeof betterAuth> as a workaround will suppress the error, but you lose plugin-specific typings—so fields added by plugins (like roles in getSession) won't be reflected in the type system 4.

Workarounds and best practices:

  • Explicitly type your config with satisfies BetterAuthOptions and cast the result:
    const authConfig = { ... } satisfies BetterAuthOptions;
    export const auth = betterAuth(authConfig) as ReturnType<typeof betterAuth<typeof authConfig>>;
    
    This helps preserve more type info than a plain ReturnType<typeof betterAuth> 2.
  • If you need declaration files, consider moving your auth config to a separate package with declaration: false and declarationMap: false, then import it in your main app 2.
  • Disabling composite or declaration in your tsconfig.json will avoid the error, but you lose type sharing or declaration files 2 3.
  • If you need to export types for use in other packages, use helpers like BetterAuthType<typeof auth> to preserve plugin augmentations [notes].

This is a TypeScript limitation with complex generics and plugin architectures, and maintainers are aware and working on improvements. For now, all solutions involve some trade-off between type safety and portability 3 4.

To reply, just mention @dosu.


How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other  Chat with Dosu Join Discord Share on X

@dosubot[bot] commented on GitHub (Sep 14, 2025): <!-- Greeting --> Hi @bernardoforcillo! I'm [Dosu](https://go.dosu.dev/dosubot) and I’m helping the better-auth team. <!-- Answer --> Yes, this issue is suited for GitHub—it's a known TypeScript problem in monorepo setups with Better Auth, especially when using plugins like `admin` or `jwt`. The error happens because TypeScript tries to infer a type that references internal modules (like `jose`), which aren't portable across package boundaries. This is common when `declaration: true` and `composite: true` are set in your `tsconfig.json` [1](https://github.com/better-auth/better-auth/issues/4250) [2](https://github.com/better-auth/better-auth/issues/3493) [3](https://github.com/better-auth/better-auth/issues/2036#issuecomment-3211343929). Using `ReturnType<typeof betterAuth>` as a workaround will suppress the error, but you lose plugin-specific typings—so fields added by plugins (like `roles` in `getSession`) won't be reflected in the type system [4](https://github.com/better-auth/better-auth/issues/2036#issuecomment-3211343929). **Workarounds and best practices:** - Explicitly type your config with `satisfies BetterAuthOptions` and cast the result: ```ts const authConfig = { ... } satisfies BetterAuthOptions; export const auth = betterAuth(authConfig) as ReturnType<typeof betterAuth<typeof authConfig>>; ``` This helps preserve more type info than a plain `ReturnType<typeof betterAuth>` [2](https://github.com/better-auth/better-auth/issues/3493). - If you need declaration files, consider moving your auth config to a separate package with `declaration: false` and `declarationMap: false`, then import it in your main app [2](https://github.com/better-auth/better-auth/issues/3493). - Disabling `composite` or `declaration` in your `tsconfig.json` will avoid the error, but you lose type sharing or declaration files [2](https://github.com/better-auth/better-auth/issues/3493) [3](https://github.com/better-auth/better-auth/issues/2036#issuecomment-3211343929). - If you need to export types for use in other packages, use helpers like `BetterAuthType<typeof auth>` to preserve plugin augmentations [notes]. This is a TypeScript limitation with complex generics and plugin architectures, and maintainers are aware and working on improvements. For now, all solutions involve some trade-off between type safety and portability [3](https://github.com/better-auth/better-auth/issues/2036#issuecomment-3211343929) [4](https://github.com/better-auth/better-auth/issues/2036#issuecomment-3211343929). <!-- Dosu Comment Footer --> *To reply, just mention [@dosu](https://go.dosu.dev/dosubot).* --- <sup>How did I do? [Good](https://app.dosu.dev/response-feedback/8414182e-d7c7-404b-8d1a-6a5e014ad125?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/8414182e-d7c7-404b-8d1a-6a5e014ad125?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/8414182e-d7c7-404b-8d1a-6a5e014ad125?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/8414182e-d7c7-404b-8d1a-6a5e014ad125?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/8414182e-d7c7-404b-8d1a-6a5e014ad125?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/8414182e-d7c7-404b-8d1a-6a5e014ad125?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/8414182e-d7c7-404b-8d1a-6a5e014ad125?feedback_type=other)</sup>&nbsp;&nbsp;[![Chat with Dosu](https://dosu.dev/dosu-chat-badge.svg)](https://app.dosu.dev/cdda13d9-dd27-4d31-b09a-5d8bec92de21/ask?utm_source=github)&nbsp;[![Join Discord](https://img.shields.io/badge/join-5865F2?logo=discord&logoColor=white&label=)](https://go.dosu.dev/discord-bot)&nbsp;[![Share on X](https://img.shields.io/badge/X-share-black)](https://twitter.com/intent/tweet?text=%40dosu_ai%20helped%20me%20solve%20this%20issue!&url=https%3A//github.com/better-auth/better-auth/issues/4654)
Author
Owner

@Kinfe123 commented on GitHub (Sep 15, 2025):

force asserting will make you lose some type. just for context can you please share me your tsconfig please

@Kinfe123 commented on GitHub (Sep 15, 2025): force asserting will make you lose some type. just for context can you please share me your tsconfig please
Author
Owner

@himself65 commented on GitHub (Sep 15, 2025):

yes, in the meantime can you try reinstall the node_modules?

@himself65 commented on GitHub (Sep 15, 2025): yes, in the meantime can you try reinstall the node_modules?
Author
Owner

@rjmohammad commented on GitHub (Sep 18, 2025):

The error happens predominantly in monorepos using PNPM.

I resolved it by installing jose and @simplewebauthn/server as dev dependencies (both were causing errors for me).
Then I updated my tsconfig.json with the following:

"types": [
  "node",
  "./node_modules/@simplewebauthn/server/esm/index.d.ts",
  "./node_modules/jose/dist/types/index.d.ts"
]

Update:

I just discovered there’s another way as well
The fix I shared here also addresses this issue: https://github.com/better-auth/better-auth/issues/3408#issuecomment-3305533354

@rjmohammad commented on GitHub (Sep 18, 2025): The error happens predominantly in monorepos using PNPM. I resolved it by installing `jose` and `@simplewebauthn/server` as dev dependencies (both were causing errors for me). Then I updated my `tsconfig.json` with the following: ```json "types": [ "node", "./node_modules/@simplewebauthn/server/esm/index.d.ts", "./node_modules/jose/dist/types/index.d.ts" ] ``` **Update:** I just discovered there’s another way as well The fix I shared here **_also_** addresses this issue: https://github.com/better-auth/better-auth/issues/3408#issuecomment-3305533354
Author
Owner

@bernardoforcillo commented on GitHub (Sep 22, 2025):

force asserting will make you lose some type. just for context can you please share me your tsconfig please

  {
  "extends": "@monorepo/tsconfig/base.json",
  "compilerOptions": {
    "outDir": "dist",
    "baseUrl": ".",
    "paths": {
      "~/*": ["./src/*"]
    }
  },
  "include": ["src/**/*", "*.ts"],
  "exclude": ["node_modules"]
}
{
 "$schema": "https://json.schemastore.org/tsconfig",
 "display": "Default",
 "compilerOptions": {
   "composite": false,
   "declaration": true,
   "declarationMap": true,
   "esModuleInterop": true,
   "forceConsistentCasingInFileNames": true,
   "inlineSources": false,
   "isolatedModules": true,
   "module": "esnext",
   "moduleResolution": "bundler",
   "noUnusedLocals": false,
   "noUnusedParameters": false,
   "preserveWatchOutput": true,
   "skipLibCheck": true,
   "strict": true
 },
 "exclude": ["node_modules"]
}
@bernardoforcillo commented on GitHub (Sep 22, 2025): > force asserting will make you lose some type. just for context can you please share me your tsconfig please ```ts { "extends": "@monorepo/tsconfig/base.json", "compilerOptions": { "outDir": "dist", "baseUrl": ".", "paths": { "~/*": ["./src/*"] } }, "include": ["src/**/*", "*.ts"], "exclude": ["node_modules"] } ``` ```ts { "$schema": "https://json.schemastore.org/tsconfig", "display": "Default", "compilerOptions": { "composite": false, "declaration": true, "declarationMap": true, "esModuleInterop": true, "forceConsistentCasingInFileNames": true, "inlineSources": false, "isolatedModules": true, "module": "esnext", "moduleResolution": "bundler", "noUnusedLocals": false, "noUnusedParameters": false, "preserveWatchOutput": true, "skipLibCheck": true, "strict": true }, "exclude": ["node_modules"] } ```
Author
Owner

@bernardoforcillo commented on GitHub (Sep 22, 2025):

yes, in the meantime can you try reinstall the node_modules?

I already did it, and rebuilt the packages some times

@bernardoforcillo commented on GitHub (Sep 22, 2025): > yes, in the meantime can you try reinstall the node_modules? I already did it, and rebuilt the packages some times
Author
Owner

@john-rtr commented on GitHub (Sep 26, 2025):

I ran into the same issue. In my case, the problem was that my app had jose 6.1.0 installed, but my version of better-auth was outdated and still depended on jose 5.10.0.

This commit from 3 weeks ago updated better-auth to jose 6.1.0:
9833a7edee

So you may just need to update better-auth—otherwise your project might still be pulling in jose 5.10.0

@john-rtr commented on GitHub (Sep 26, 2025): I ran into the same issue. In my case, the problem was that my app had jose 6.1.0 installed, but my version of better-auth was outdated and still depended on jose 5.10.0. This commit from 3 weeks ago updated better-auth to jose 6.1.0: https://github.com/better-auth/better-auth/commit/9833a7edeef38e6d287badc4b8d11fe598ad55be So you may just need to update better-auth—otherwise your project might still be pulling in jose 5.10.0
Author
Owner

@himself65 commented on GitHub (Oct 15, 2025):

I think we already fixed this in 1.4

@himself65 commented on GitHub (Oct 15, 2025): I think we already fixed this in 1.4
Author
Owner

@himself65 commented on GitHub (Oct 15, 2025):

We're not gonna support Jose 5.x. Closing

@himself65 commented on GitHub (Oct 15, 2025): We're not gonna support Jose 5.x. Closing
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#1926