AppCrumble mascotAppCrumble
AuthBetter AuthGoogle OAuthScope

The Case Against Adding More Login Buttons

Every extra sign-in provider looks like one button on a design file. In production it's a support queue. Here's the math we did before shipping just two.

August 3, 20266 min read

Every starter kit is tempted to list a dozen sign-in providers on its landing page, because a dozen looks more impressive than two. We shipped AppCrumble with exactly two: email and password, or Google. That wasn't a first draft we never got around to finishing - it's the whole decision.

Why two is usually enough

Email and password covers anyone, on any device, with no dependency on a third party being up. Google covers the much larger group who just want to tap one button and get on with their day - it's the single most widely held account most people already have open in another tab. Between the two, you've covered the overwhelming majority of people who will ever try to sign up for a Tuesday- afternoon side project.

What each extra provider actually costs

A third login button reads as free on a Figma file. In production it's a standing commitment: a separate OAuth app to register in that provider's console, a redirect URI allowlist that has to stay in sync across local, staging, and production, and - for providers that gate access behind a review (Google's verification process for sensitive scopes is the well-known example) - a compliance form to fill out before the button can go live for more than a handful of test users. Multiply that by however many providers feel obligatory, and the login screen has quietly become the most externally-dependent part of the app.

Then there's the slow cost: client secrets that need rotating, provider outages that take your sign-in flow down even though your own servers are fine, and a support inbox that eventually gets a message starting with "I can't log in and I don't remember which one I used." None of that shows up on launch day. It shows up later, and it compounds.

The account-linking problem nobody mentions

Here's the gotcha that only shows up once real users touch the system: someone signs up with jane@company.com and a password. Weeks later, on a different machine, she clicks "Continue with Google" - using the same Google account tied to that exact email address. Unless the auth layer is explicitly told what to do here, one of two bad things happens: it silently creates a second, disconnected account with the same email, or it throws an opaque conflict error. Either way, Jane thinks the app lost her data.

Every provider you add multiplies the number of these collision paths. With two providers there's exactly one pair to reason about. With five, there are ten.

What it looks like in code

With Better Auth, saying no to the rest is almost a one-line decision - the config only lists what you actually want to support, and account linking is an explicit choice rather than an accident:

lib/auth.ts
import { betterAuth } from "better-auth";

export const auth = betterAuth({
  emailAndPassword: {
    enabled: true,
  },
  socialProviders: {
    google: {
      clientId: process.env.GOOGLE_CLIENT_ID!,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
    },
  },
  account: {
    accountLinking: {
      // Link a Google sign-in to an existing email/password account when
      // the addresses match and Google has verified it - instead of
      // silently creating a second account for the same person.
      enabled: true,
      trustedProviders: ["google"],
    },
  },
});

When more providers actually earn their place

None of this means two is a universal rule. A developer-tool product whose entire audience already lives on GitHub gains real conversion by adding a GitHub button - the marginal cost is worth it because the overlap with your actual users is close to total, not a hedge against who might show up. An app selling to enterprise buyers eventually needs SSO (SAML or OIDC against the customer's own identity provider), because for that segment it isn't a convenience, it's a procurement requirement. And if you ship an iOS app that offers any other third-party social login, Apple's App Store guidelines require offering "Sign in with Apple" alongside it - that one isn't optional once you've opened the door.

The pattern in all three cases is the same: the provider was added because a specific, known group of users needed it, not because it seemed safer to cover every base on day one.

Note
This is a reversible decision, which is exactly why it's an easy one. If real users ask for GitHub or Microsoft sign-in, add it then - you'll be adding a provider people actually asked for, instead of guessing at launch which five they might want.

The same logic runs through the rest of AppCrumble's v1 scope: no team management, no admin panel, no i18n. Not because those problems aren't real, but because guessing at them before a single user exists just means building the wrong version first.