Skip to main content
For a developer-flavored product, “Continue with GitHub” usually outperforms email sign-up. vibestrap wires GitHub through Better Auth’s social provider — set two env vars and the button shows up on /login and /register.

Prerequisites

  • A GitHub account.
  • Your production domain decided.
  • Five minutes — GitHub’s OAuth flow is the simplest of the three majors.

Step-by-step setup

  1. Open Developer settings. github.com/settings/developers → OAuth Apps → New OAuth App. (For an org-owned app, use github.com/organizations/<org>/settings/applications instead.)
  2. Fill in the form:
    FieldValue
    Application nameYour product name (users see this on the consent screen).
    Homepage URLhttps://your-domain.com
    Authorization callback URLhttps://your-domain.com/api/auth/callback/github
    No trailing slash on the callback URL. Add a second OAuth App for local dev pointing at http://localhost:3000/api/auth/callback/github, or register both URLs by creating dev + prod apps separately.
  3. Generate a client secret. Click Generate a new client secret on the OAuth App page. Copy it now — GitHub only shows it once.
  4. Drop into .env.local:
    GITHUB_CLIENT_ID=Iv1.abc123...
    GITHUB_CLIENT_SECRET=...
    
  5. Enable the button. In src/config/site.ts:
    features: { enableGithubLogin: true, /* ... */ }
    
  6. Restart pnpm dev. Env vars are read at startup.

Scopes

Better Auth requests read:user and user:email by default — enough to populate user.name, user.email, and user.image. You don’t need to ask for repo or anything else unless your product actually uses the GitHub API on the user’s behalf. Asking for more scopes than necessary tanks signup conversion. If you later need a wider scope (say, to read a user’s repos), pass scopes in the provider config in src/lib/auth.ts:
socialProviders.github = {
  clientId: env.GITHUB_CLIENT_ID,
  clientSecret: env.GITHUB_CLIENT_SECRET,
  scopes: ['read:user', 'user:email', 'repo'],
};
Existing users will need to re-authorize for the new scope to take effect.

Verify it works

  1. Visit /login — the “Continue with GitHub” button should be visible.
  2. Click it. You bounce to GitHub’s consent page, hit Authorize, land back on /dashboard.
  3. Inspect the account table — a row with providerId = 'github' should be linked to your user row.
  4. Sign up with email first, then sign in with GitHub using the same email — they merge into a single user (account-linking is on for trusted providers).

Common pitfalls

  • Trailing slash on the callback URL. GitHub matches it character-for-character. …/callback/github/ (with slash) ≠ …/callback/github (without). Use the version without the trailing slash.
  • Single OAuth App for dev + prod. GitHub’s free OAuth Apps only allow one callback URL. Make two apps — MyProduct (dev) and MyProduct (prod) — with separate client IDs.
  • Email permission not granted. Some users have all their GitHub emails set to private. Better Auth still works — it falls back to the noreply email. If you rely on hitting their primary inbox, surface a “please complete your profile” flow on first sign-in.
  • Org-restricted accounts. If a user’s GitHub org enforces SSO, your OAuth App needs to be approved by an org admin before the user can authorize it.
  • Client secret leaked once shown. GitHub does not show secrets twice. If you lost it, regenerate — invalidates the old one immediately.

Official docs