Build a Modern Login/Signup Form with Tailwind CSS and React
In this article, you'll learn how to instantly build great-looking authentication forms for Login and Signup using Tailwind CSS in React. You'll also understand how to make these forms functional using the third-party Authentication service LoginRadius.

Table of Contents
- What is Tailwind CSS?
- Why Tailwind CSS Better or Worse Than the Others?
- What You'll Build Today?
- Project Setup
- Install Tailwind CSS
- Configuring Tailwind CSS
- Frontend Architecture and Boilerplate
- Component Architecture
- Directory Structure
- Components Boilerplate Code
- Form Fields Constants
- Set Up Routing
- The Header Component
- The Input Component
- The Login Component
- Wrapping Up the Login Page
- The Signup Page
- Use LoginRadius Authentication APIs
- Conclusion
What is Tailwind CSS?
Web design and CSS have come a long way. And today, modern websites have everything you could wish for alongside stunning designs. Then why should your website's login and signup forms look boring?
The web ecosystem has tons of reliable third-party libraries and frameworks to help you build intuitive designs even if you're not a design wizard. Amidst the plethora of libraries comes a utility first CSS framework called Tailwind CSS.
So in this post, you'll learn:
- what Tailwind CSS is;
- why it's awesome; and,
- how you can use it in a React app.
I'll then walk you through step by step how to use it to create a modern login and signup form with routing in React.
Finally, you'll see how to make these forms functional using LoginRadius Authentication APIs docs/references/api/authentication).
What is Tailwind CSS?
If you've heard of Materialize and Bootstrap, Tailwind CSS is much similar in what it offers. It's a CSS framework that helps developers build layouts, components, themes, and whatnot, without writing all the CSS themselves.
However, unlike Bootstrap and Materialize, it doesn't give you built-in components out of the box. Instead, it gives you a wide range of fully customizable utility classes that you can use to style your pages.
Why Tailwind CSS Better or Worse Than the Others?
The community loves Tailwind. For most developers, the key takeaway is that it gives you more freedom on how you want your components or elements to look. So in many cases, when developers use component-based CSS frameworks like Bootstrap, they have a hard time changing the way they want their website to look.
Being utility first, it's the most customization-friendly CSS framework!
Also, it's pretty easy to integrate with modern frontend frameworks like React, NextJS, VueJS, Angular, Svelte, etc. I'll also explore that shortly when we add Tailwind to our React app.
On the downside, Tailwind might make your HTML bloated with loads of CSS classes for small and specific rules. However, you can control it with a framework like React by building smaller reusable components and using JSX bindings for long class names for more maintainability and readability.
In fact, we'll take this optimal approach in building our Login form, so you'll understand some best practices you can use to avoid bloated HTML templates in your React app.
What You'll Build Today?
We'll create a simple yet modern looking login and signup form that looks like this:
It will be interactive using React state, can route to different pages, and we'll also, in the end, talk about how we can make it functional from a backend standpoint.
Sounds good? Let's start by understanding how we can add TailwindCSS to our React app.
Project Setup
Inside a directory of your choice, create a new React project by running:
Next, move inside the project and install react-router-dom by running:
Install Tailwind CSS
Now, add Tailwind to your React project by following the steps given here.
First, install Tailwind CSS and its related dependencies by running the following command in the root directory:
Next, generate some configurational files by running the following command in the root directory:
That should generate a file and file for you as shown:
Awesome!
Configuring Tailwind CSS
Now, go ahead and update the file to support templates for your React component files as shown:
Almost there! We'll now add some necessary Tailwind directives to your file present in the root directory:
Each of the above directives represents a layer of Tailwind's utility classes that you can use in your project. Their declaration allows using these utility classes anywhere in your project.
Finally, we'll kickstart your React project by spinning a local development server:
You're now ready to start using Tailwind CSS to create some awesome-looking UI for your React app!
Frontend Architecture and Boilerplate
We'll break down the entire page into small, reusable components to ensure that your code is readable and maintainable and doesn't have bloated HTML templates.
Component Architecture
For instance, you can have a component that takes care of the page's heading and displays a link to navigate to another page.
Similarly, you can have a reusable custom component that can be used inside the form. All in all, here's what your frontend architecture would look like:
Directory Structure
So first, let's go ahead and create these files and folders. You'll develop corresponding files for the Signup page as well. Create the following files and folders inside your root directory:
For perspective, here's how we'll use those components to build your entire Login Page:
Makes sense? Great!
Components Boilerplate Code
While we're at it, let's also create some component boilerplate for all these files except the .
For the Login.js files (), you can put down the following code:
Similarly, you can create such boilerplates for the rest of the files.
Form Fields Constants
You've created a file earlier. This file will hold all the input fields related constants like placeholder, value, name, field type, etc. Inside this file, add the following code:
The above file has two arrays: one each for your login form fields and signup form fields. Each array contains an object that contains attributes for the input fields.
The field names should be self-explanatory as to what they represent. Here's a quick summary of that:
- : The label for an input field
- : The value that associates a label to the input field via an id attribute on the input field
- , , , and : Respective attributes on the input field
- : If you want to make an input field mandatory, in this case, all our input fields for form submission will be mandatory
Later, we'll use this array to cycle through each input field and render a custom component that you'll create shortly.
Set Up Routing
As you already have your components boilerplates in place, let's first set up routing for your app.
By default, when a user opens the app, we'll direct them to a Login page. Then, if the route changes to /signup, we'll direct them to a Signup page.
Head over to your file and add the following code:
Notice that you have two containers wrapped around your with some long classnames.
The first container gives a minimum height of 100% and sets a fixed height of the container to 100vh via the and classes. Then, it centers everything via , to vertically center all the flex child elements, and to center them horizontally.
Finally, we have some padding classes prefixed with . For top and bottom padding, we use the prefix followed by some value. We also have some responsive padding on small and large screen devices prefixed with and respectively. You can learn more about these padding and margin properties to see other similar classes you can use.
Similarly, the second container sets some width for its child elements and provides some spacing via the respective Tailwind classes.
The Header Component
Now, let's create the component that you can render on both the login and signup pages for quick information and navigation.
Head over to , and add the following code:
Your component takes four props:
- a dynamic that it displays on the top;
- then some additional text as ;
- a to display which page it will redirect the user to; and,
- its corresponding path as .
Using the ' justify-center ' class, we place all these elements inside a flexbox container and horizontally center them. There is also an outer container that simply gives the header some bottom margin using the class.
Then, we give our header image some fixed height and width using the and classes, respectively.
Finally, our text and links have some typography classes for font-size, font-colour, hover effect, and font-weight.
Let's now go ahead and render the component with all the props inside the Login page ():
Here's what the login page should now look like:
Let's now start building the rest of the Login page form.
The Input Component
We'll now create our reusable and great looking component that you'll use to build your Login form.
Head over to the file, and add the following code:
Remember all those fields' key-value pairs you set earlier in your constants file?
Those are all the props your component will take. It will also take a and a prop since we want this to be a controlled component linked to some state.
Notice how the HTML markup of this component looks very clean. How is that possible? Are you not using any Tailwind classes here?
As there are a lot of Tailwind classes for styling this input field, we have created a constant for it — called . It contains all the essential styling classes for the input field.
We also take a prop that will append any custom Tailwind class you want to pass to the input field for customizations. How cool is that?!
The Login Component
Next, create the component inside , where the entire Login form will be rendered. This component will also be responsible for owning any state or event handlers passed down as props to other child components.
Based on your from your constants, we programmatically generate an initial value for your .
Then we have a event handler to update the state whenever an event is fired from the nested component.
Then we simply loop through the array and render an component that you've created in the previous section.
Before seeing how the login form looks, you need to render it inside your Login page.
So render the above component inside file as shown:
Now, if you go back to your React app, you should see your Login page input fields appear as follows:
Excellent, it looks like you're almost there!
Now add the final pieces to the Login page by writing the and components.
Wrapping Up the Login Page
The component holds the template and styles for a simple "Remember me" functionality.
Inside file, add the following code:
Again here we're using some Tailwind typography and flexbox classes to style and structure the layout of the UI.
Let's go to the file and create a submit button for the Login form.
Add the following code inside this file:
Notice that you also have loads of CSS classes inside our element to style it. It makes our HTML appear bloated and difficult to read. We can follow the same approach of using a constant and a prop against the for the as we previously did to combat this.
At last, we'll put everything together inside file as follows:
And once we do that, we should have a stunning, modern looking login page appear right in front of us:
The Signup Page
You've created so many reusable components. Now, it's straightforward to use them to build the Signup page further.
Feel free to take this as a challenge and build it yourself based on what you've learned.
Here's a quick walkthrough of the steps and how you can use the same approach to build the Signup page in minutes.
First, create a main component inside file similar to the component you've completed in the previous section. It will render the signup form fields and attach state and event handlers to it.
Here's how the entire code looks like:
Then, render this component inside alongside the components with some modified props for the signup page.
And that's it! That's all there is to build a great looking signup page that looks as follows:
Don't worry; if you got stuck somewhere, feel free to refer to the entire codebase for this tutorial here.
Use LoginRadius Authentication APIs
You can use LoginRadius to quickly set up an authentication backend for your frontend application.
First, set up an account, and get your API key from your Account Dashboard.
Then, you can use their login endpoint to authenticate users.
The endpoint takes an email and password as parameters and validates them against the correct credentials. If we were to integrate this endpoint in our previously built component (), here's what the method would look like:
Similarly, you can use the Signup endpoint to create users without managing a complete backend database yourself.
Curious to learn more?
I did a full-fledged guide on authenticating Svelte apps with LoginRadius here.
Conclusion
In this tutorial, you have learned to create beautiful registration and authentication forms for your web app with Tailwind CSS. You also learned the advantages and disadvantages of Tailwind CSS and understood how Tailwind CSS works better with React.

Featured Posts
How to Implement JWT Authentication for CRUD APIs in Deno
Multi-Factor Authentication (MFA) with Redis Cache and OTP
Introduction to SolidJS
Build a Modern Login/Signup Form with Tailwind CSS and React
Implement HTTP Streaming with Node.js and Fetch API
NestJS: How to Implement Session-Based User Authentication
NestJS User Authentication with LoginRadius API
How to Authenticate Svelte Apps
Flutter Authentication: Implementing User Signup and Login
How to Secure Your LoopBack REST API with JWT Authentication
Node.js User Authentication Guide
Your Ultimate Guide to Next.js Authentication
Local Storage vs. Session Storage vs. Cookies
How to Secure a PHP API Using JWT
Using JWT Flask JWT Authentication- A Quick Guide
Build Your First Smart Contract with Ethereum & Solidity
What are JWT, JWS, JWE, JWK, and JWA?
How to Build an OpenCV Web App with Streamlit
32 React Best Practices That Every Programmer Should Follow
How to Build a Progressive Web App (PWA) with React
Bootstrap 4 vs. Bootstrap 5: What is the Difference?
JWT Authentication — Best Practices and When to Use
What Are Refresh Tokens? When & How to Use Them
How to Upgrade Your Vim Skills
How to Implement Role-Based Authentication with React Apps
How to Authenticate Users: JWT vs. Session
How to Use Azure Key Vault With an Azure Web App in C#
How to Implement Registration and Authentication in Django?
11 Tips for Managing Remote Software Engineering Teams
Implementing User Authentication in a Python Application
Add Authentication to Play Framework With OIDC and LoginRadius