Written by Muhammed Ali✏️
StackAuth is a powerful, open source alternative to Auth0, designed to offer seamless authentication solutions without the need for costly service subscriptions. With support for multiple authentication methods, including traditional email/password logins and third-party OAuth providers like Google, StackAuth enables Next.js developers to maintain control over their authentication systems while leveraging modern security standards.
This guide covers how to configure StackAuth in a Next.js application with three authentication sources: email/password, GitHub, and Google. We’ll also explore the benefits, use cases, and key differences between StackAuth and Auth0.
To follow along, you should have at least a foundational understanding of Next.js.
Benefits of using StackAuth
Auth0 is a popular, cloud-based authentication platform that simplifies application authentication and authorization. It offers features like Single Sign-On (SSO), Multi-Factor Authentication (MFA), and social logins (e.g., Google, Facebook).
While Auth0 is widely used, it comes with several pain points that can make it less appealing for certain use cases, including its high costs, limited customization, data ownership concerns, vendor lock-in, complexity for advanced use cases, and more.
StackAuth addresses these pain points by offering a powerful, open source, and self-hosted authentication solution. Reasons to consider StackAuth as an alternative to Auth0:
- No subscription fees or hidden costs
- Comes with a user management dashboard
- Tailor authentication experiences to specific requirements
- Maintain complete control over user data
- Handles permissions
- Deploy on your own servers for maximum security
Key differences between StackAuth and Auth0
Feature | StackAuth | Auth0 |
---|---|---|
Cost | Free, open source | Subscription required |
Customization | Full control over authentication | Limited to service APIs |
Hosting | Self-hosted | Cloud-based |
Data Ownership | Complete control | Managed by Auth0 |
Supported Frameworks | Next.js (app router) | Multiple frameworks |
StackAuth is ideal for:
- Startups and small businesses seeking a budget-friendly authentication solution
- Developers who want full control over user authentication
- Teams running on a limited time schedule; StackAuth enables you to get authentication up and running in five to 10 minutes
- Organizations concerned with data privacy and security
Implementing authentication with StackAuth
To get started, create a Next.js app and make sure your project uses the App Router, as StackAuth doesn't support the Page Router:
npx create-next-app@latest stack-next-app --typescript
cd stack-auth-app
Now, install and configure StackAuth using the setup wizard:
npx @stackframe/init-stack@latest
The wizard detects your project structure and sets up StackAuth automatically. After the setup is completed, you will be redirected to the browser to create a handler account if you don’t already have one.
After that, you will be redirected to a page to select the authentication options you want to use on your application. Give your project a name, and select Email password, Google, and GitHub by toggling them on. Then, click the Create project button: You will now be provided with API keys that will enable you to authenticate your application. Keep these secure:
Copy the environment variables into a
.env.local
file:
NEXT_PUBLIC_STACK_PROJECT_ID=<your-project-id>
NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY=<your-publishable-client-key>
STACK_SECRET_SERVER_KEY=<your-secret-server-key>
In the src/app/page.tsx
file, paste in the following code:
"use client";
import { UserButton, useUser } from "@stackframe/stack";
export default function Home() {
const user = useUser();
const loggedIn = user !== null;
return (
<div className="flex flex-col gap-4 m-4">
<p>
Welcome to the Stack Auth demo!
</p>
<p>
Are you logged in? {loggedIn ? "Yes" : "No"}
</p>
<div>
<UserButton />
</div>
</div>
);
}
This code uses the useUser
Hook to retrieve the current user object and checks if the user is logged in by verifying that the user is not null
. It dynamically displays whether the user is logged in and includes the UserButton
component, which serves as an interactive avatar with options to manage account settings or sign out. This setup provides basic authentication feedback and user management capabilities that can be used on an application.
Stack is now successfully configured in your Next.js project! Start your Next.js app by running npm run dev
.
Now navigate to http://localhost:3000/handler/signup on your browser to access the Stack sign-up page: Now you can access your Stack dashboard, and you will be able to access the newly created accounts:
Adding StackAuth to your app
Now that authentication is set up, this section will walk through setting up StackAuth authentication and building a simple note-taking app where users can create and view notes after signing in. In the app/page.tsx
file, we will create a page that will:
- Check if the user is logged in
- If not logged in, display the authentication button
- Allow users to add notes
-
Display the notes
"use client"; import { useUser } from "@stackframe/stack"; import { useState } from "react"; export default function Home() { const user = useUser(); const [notes, setNotes] = useState<string[]>([]); const [note, setNote] = useState(""); if (!user) { return ( <div className="flex flex-col items-center justify-center min-h-screen"> <h1 className="text-xl">Please Sign In</h1> <a href="/signin" className="text-blue-500 underline"> Go to Sign In </a> </div> ); } return ( <div className="max-w-xl mx-auto mt-10"> <h1 className="text-2xl">Welcome, {user.email}!</h1> <div className="mt-4"> <input type="text" value={note} onChange={(e) => setNote(e.target.value)} className="border p-2 w-full" placeholder="Write a note..." /> <button onClick={() => { if (note.trim()) { setNotes([...notes, note]); setNote(""); } }} className="bg-blue-500 text-white px-4 py-2 mt-2 rounded" > Add Note </button> </div> <ul className="mt-4"> {notes.map((n, index) => ( <li key={index} className="border p-2 mt-2"> {n} </li> ))} </ul> </div> ); }```
This code is a Next.js client-side component that creates the note-taking app.
The app first checks if a user is logged in by using the useUser
Hook from @stackframe/stack
. If no user is logged in, it displays a message asking the user to sign in and shows the UserButton
component, which allows the user to log in or sign up. This ensures that only authenticated users can access the note-taking features.
If a user is logged in, the app welcomes them by displaying their name (user.displayName
). It provides an input field where users can type notes, and the current input value is stored in the note
state variable using the useState
Hook. When the user clicks the Add Note button, the note is added to the notes
array (also stored in state) if it's not empty. The input field is then cleared, allowing the user to add more notes.
Now, when you run your application and navigate to the home page, you will see that authentication is required before accessing the note-taking features: After logging in, you will be able to create notes using the form:
In
app/handler/[...stack]/page.tsx
, StackAuth automatically provides pre-built pages for sign-up, sign-in, and account management, but you can customize your sign-in page and create a custom app/signin/page.tsx
file.
Here’s an example of a custom profile page that displays user information and allows users to sign out:
'use client';
import { useStackApp } from "@stackframe/stack";
export default function CustomOAuthSignIn() {
const app = useStackApp();
return (
<div>
<h1>My Custom Sign In page1</h1>
<button onClick={async () => {
// this will redirect to the OAuth provider's login page
await app.signInWithOAuth('google');
}}>
Sign In with Google
</button>
</div>
);
}
The same can be done for the sign-up page.
Now you can tell the Stack app in stack.tsx
to use the sign-in page you just created:
export const stackServerApp = new StackServerApp({
// ...
// add these three lines
urls: {
signIn: '/signin',
}
});
Preparing for production
Before deploying your application, it’s need to configure StackAuth for production to ensure security and optimal performance.
Domain configuration
In production, you must specify your domain to prevent unauthorized callback URLs. Navigate to the Domain & Handlers tab in the Stack dashboard and add your domain (e.g., https://your-website.com
). Disable the Allow all localhost callbacks for development option to enhance security.
OAuth providers
Replace the shared OAuth keys used in development with your own OAuth credentials. For each provider (e.g., Google, GitHub), create an OAuth app and configure the callback URL. Then, enter the client ID and client secret in the Stack dashboard under Auth Methods.
Email server
For production, set up your own email server to send emails from your domain. In the Stack dashboard, navigate to the Emails section, switch from the shared email server to a custom SMTP server, and enter your SMTP configurations.
Enable production mode
Once all configurations are complete, enable production mode in the Project Settings tab of the Stack dashboard. This ensures your application runs securely with StackAuth in a production environment.
Conclusion
With its open source nature, StackAuth offers full control over user data, great customization options, and the ability to self-host for enhanced privacy and security.
By following the steps outlined in this tutorial, you can set up authentication, configure environment variables, and leverage StackAuth’s pre-built and customizable components.
For production use, consider additional measures like rate limiting and token management to further enhance security. For more advanced use cases and detailed documentation, refer to the StackAuth SDK documentation.
LogRocket: Full visibility into production Next.js apps
Debugging Next applications can be difficult, especially when users experience issues that are difficult to reproduce. If you’re interested in monitoring and tracking state, automatically surfacing JavaScript errors, and tracking slow network requests and component load time, try LogRocket.
LogRocket is like a DVR for web and mobile apps, recording literally everything that happens on your Next.js app. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred. LogRocket also monitors your app's performance, reporting with metrics like client CPU load, client memory usage, and more.
The LogRocket Redux middleware package adds an extra layer of visibility into your user sessions. LogRocket logs all actions and state from your Redux stores.
Modernize how you debug your Next.js apps — start monitoring for free.
Top comments (0)