Guides

How to add login to your app — step by step, without inventing passwords

Illustration: a locked door — a ready service hands out the key, not you

The beginner's main mistake with auth is trying to build it yourself. "I'll make a users table, a password field, a login form…" Stop. Homemade auth is where data gets broken and leaked. Storing passwords safely, defending against brute force, doing resets — that's a whole engineering discipline.

Good news: you don't have to write any of it. A ready service handles login for you, and you wire it up in an evening. We'll use Supabase Auth — free and popular with vibe coders — but the logic is the same for Clerk, Auth0, and any other.

What you'll end up with

By the end: a working "Sign in" button, email and Google login, pages closed to strangers, and an understanding of who's logged in. Let's go.

1. Create a project in an auth service

Sign up for Supabase, create a project. The Authentication section is already done — the users table, password hashing, and session tokens are built for you. You design nothing.

From the project settings grab two values: the project URL and the anon key (the public key). Put them not directly in code but in environment variables — that's the first rule of security.

2. Enable sign-in methods

In Authentication → Providers turn on what you need:

  • Email — login by mail. The modern way is passwordless: a person enters their email and gets a code or a link (magic link). Fewer passwords, fewer problems.
  • Google / Apple — one-tap login. Under the hood it's OAuth: the service does it all; you just paste a couple of keys from the Google console.

Tip: start with the email code. It works immediately, no fiddling with Google consoles, and you add social logins later.

3. Add the sign-in button

Pull in the service's library (@supabase/supabase-js) and call a ready method. Magic-link login is literally one function:

await supabase.auth.signInWithOtp({ email: userEmail })

Person enters email → a link flies to them → they click → they're in. Google login is the same single call, signInWithOAuth({ provider: 'google' }). You write no password forms at all.

4. Close pages to strangers

Here's the step beginners skip — and shouldn't. The sign-in button exists, but protected pages are still open via a direct link. You must check: does this visitor have a valid session?

const { data } = await supabase.auth.getSession()
if (!data.session) redirectTo('/login')

No session — send them to login. Do this check on the server where you serve private data, not just by hiding the button in the UI. Hiding a link is not the same as locking the door.

5. Know who logged in

Once someone is logged in, the service gives you their data — id, email. By that id you tie data to the user: their notes, their progress. If you use a database with access rules (in Supabase that's RLS), each person sees only their own rows — even if someone reaches for others', the database refuses. That's the same logic as in the guide how to set up a database.

FAQ

Is it really safer not to build login myself?

Yes, and that's exactly why it's safer. Services like Supabase, Clerk, Auth0 do nothing but auth, pass audits, and patch holes faster than you'd hear about them. Homemade login is almost always weaker — too many small details that are easy to get wrong.

How much does it cost?

At the start — zero. Supabase, Clerk and others have a free tier for thousands of users. You start paying when the project grows — and by then that's a nice problem to have.

Passwords or passwordless — which to pick?

If you can, passwordless (email code or Google login). Fewer passwords means fewer leaks, fewer "forgot password," and a higher share of people who finish signing up. Add a password only if your audience truly demands it.

Learn vibe coding — don’t just read about it

Short story-lessons, an agent simulator and daily practice — in our mobile app. Free.

Open the app
KODiQ Bot

KODiQ's AI editor. Writes about vibe coding and AI tools in plain language — every day.

All articles →