Skip to content
Skip to content
Goodspeed

BUILT INTO EVERY GOODSPEED APP

Authentication

Email/password, Google OAuth, Apple Sign-In, biometric lock, and anonymous-to-permanent account upgrade are all pre-wired via Supabase Auth. Auth state drives the navigation guard automatically.

  • Tier: Core
  • Status: Static
  • Config: features.auth.email

WHY IT MATTERS

Most mobile app projects spend weeks plumbing the same infrastructure before writing a single line of product code. Authentication is one of those cross-cutting concerns that every app eventually needs but almost none get right the first time. Permissions are handled incorrectly, tokens expire silently, or the feature breaks after an OS update nobody tested against.

Goodspeed solves this by shipping authentication as a production-grade, tested implementation inside every generated app. The code follows the patterns in the GAS template - the same 246-feature catalog that powers every app we build. Controlled by `features.auth.email` in gas.config.ts. You own the code from day one, can read every line, and can hire any React Native developer to extend it. The build pipeline verifies the feature compiles and routes resolve before the app lands in your repository, so you are not the one catching the integration error at 2 am before launch.

HOW IT IS WIRED

Real code from the GAS template

The excerpt below is lifted verbatim from services/auth.ts in the gas-template repository. This is the code your generated app gets, not pseudocode, not a description of intent.

// services/auth.ts — anonymous sign-in + account upgrade
export async function signInAnonymously(): Promise<{ userId: string }> {
  return retryWithBackoff(
    async () => {
      const { data, error } = await supabase.auth.signInAnonymously();
      if (error || !data.user) {
        throw new ServiceError('anon_signin_failed', 500, error?.message);
      }
      return { userId: data.user.id };
    },
    { shouldRetry: isTransientNon4xxError },
  );
}

export async function upgradeAnonymousAccount(
  credentials: UpgradeCredentials,
): Promise<UpgradeResult> {
  const { data: userData } = await supabase.auth.getUser();
  if (!userData.user?.is_anonymous) {
    throw new ServiceError('not_anonymous', 400, 'Not an anonymous account');
  }
  // Email path: updateUser; OAuth path: linkIdentity
  if ('email' in credentials) {
    const { error } = await supabase.auth.updateUser({
      email: credentials.email, password: credentials.password,
    });
    if (error) throw new ServiceError('upgrade_failed', 400, error.message);
  }
}

Source: goodspeed-apps/gas-template services/auth.ts

HONEST LIMITS

When Authentication is the wrong choice

For internal enterprise tooling behind SSO (SAML/OIDC), the template's Supabase Auth is a mismatch. Those apps need enterprise identity provider integration which is outside the template's scope.

Tier: Core · Static

  1. Evaluate your use case

    Check whether authentication aligns with your target audience, platform constraints, and regulatory environment before enabling it.

  2. Audit the config

    The `features.auth.email` flag controls this feature. Set it to false in gas.config.ts to disable the feature entirely with no residual code paths.

  3. Seek alternatives

    If the built-in implementation does not fit, the generated codebase is standard React Native + Expo code. Any library in the Expo ecosystem can replace the default.

APPS USING THIS FEATURE

Apps built with Authentication

These apps were generated by Goodspeed and use authentication as a core part of their experience. Each link goes to the full app marketing page.

CAPABILITIES

Authentication capability breakdown

Concrete dimensions of what the built-in authentication implementation covers. These reflect the actual template code, not a marketing summary.

ItemDescriptionStrength
ProvidersEmail/password, magic link, Google OAuth, Apple Sign-In are all pre-wired. Twitter, LinkedIn, and TOTP are config-toggled.4 built in
Anonymous modesignInAnonymously() creates a session without credentials. upgradeAnonymousAccount() migrates data on signup.Built in
Session refreshSupabase auto-refreshes the JWT 60 seconds before expiry. The navigation guard listens to onAuthStateChange.Automatic
Biometric lockFace ID / Touch ID re-authentication gate on app foreground. Controlled by features.auth.biometric.enabled.Config-toggled
Password resetDeep-linked reset flow via Supabase email. The callback route is pre-registered at app.scheme + ://auth/callback.Built in

GET IT BUILT INTO YOUR APP

Score your idea and get authentication wired in from day one