Building the First Version of PatanPad: A Simple Note-Taking App with Next.js and Tailwind CSS

Hi everyone! 👋 I recently started a new side project called PatanPad—a minimalist note-taking app built with Next.js, TypeScript, and Tailwind CSS.

In this blog post, I’ll walk you through the first version of the app: how I bootstrapped the project, structured the layout, and added core functionality like text input and state management. If you’re a frontend developer looking to start a real-world project with modern tools, I hope this breakdown helps you.

Table of Contents

🎯 What is PatanPad?

PatanPad is a personal "notepad" application where users can jot down quick notes, thoughts, or drafts—similar to sticky notes, but simpler and faster. It’s focused on minimalism and performance. This first version is intentionally basic to focus on the development workflow and core React features.

🛠 Setting Up the Project with Next.js

To kick off the project, I used the official Next.js CLI:

npx create-next-app@latest

During the setup, I chose the following options:

  • ✅ TypeScript – for static typing and maintainability
  • ✅ ESLint – to enforce code quality
  • ✅ Tailwind CSS – to design fast with utility classes
  • ✅ App Router – to leverage the latest Next.js routing
  • ✅ Turbopack – for faster development builds
  • src/ directory – to keep the codebase clean
  • ✅ Import aliases – for better path imports (@/components, etc.)

Once the setup completed, I navigated into the project and started the dev server:

cd patanpad
npm run dev

And just like that, the project was live at http://localhost:3000 🚀

🧩 Creating the Component Structure

With the app running, I jumped straight into building the UI. I structured the app with two main components:

1. Navbar

Located in components/Navbar.tsx, this component displays the app title and a placeholder for a future theme toggle button:


const Navbar = () => {
  return (
    <div className="p-2 flex justify-between">
      <h1 className="text-xl">PatanPad</h1>
      <button className="border p-1 rounded border-gray-500 text-gray-400 cursor-pointer">
        Toggle mode
      </button>
    </div>
  );
};

2. Pad

The core logic lives inside components/Pad.tsx. It allows users to:

  • Type content in a textarea
  • Add content to a list
  • Clear the input with a confirmation
  • View submitted pads in a vertical list

const Pad = () => {
  const [userInput, setUserInput] = useState("");
  const [inputRows, setInputRows] = useState(4);
  const [pads, setPads] = useState<string[]>([]);

  return (
    <div className="p-2 text-gray-400">
      <textarea
        className="border border-gray-600 w-full p-2 rounded"
        rows={inputRows}
        placeholder="Once upon a time ..."
        onFocus={() => setInputRows(4)}
        value={userInput}
        onChange={(e) => setUserInput(e.target.value)}
      />
      <div className="flex justify-between">
        <p
          className="cursor-pointer"
          onClick={() => {
            const value = confirm("Are you sure want to clear");
            if (value) setUserInput("");
          }}
        >
          clear
        </p>
        <button
          className="p-1 border rounded cursor-pointer"
          onClick={() => {
            setPads((prev) => [userInput, ...prev]);
            setUserInput("");
          }}
        >
          Add
        </button>
      </div>
      <h1 className="mt-5">My pads</h1>
      <hr />
      {pads.length === 0 && (
        <h1 className="h-[100px] flex justify-center items-center">
          No pads found!
        </h1>
      )}
      {pads.map((pad) => (
        <div key={pad} className="border p-2 my-2 rounded">
          <p>{pad}</p>
        </div>
      ))}
    </div>
  );
};

🏗️ Composing the Home Page

I brought everything together in app/page.tsx:


import Navbar from "./components/Navbar";
import Pad from "./components/Pad";

export default function Home() {
  return (
    <div className="lg:max-w-[756px] lg:m-auto">
      <Navbar />
      <Pad />
    </div>
  );
}
Screenshot of PatanPad v1 - minimalist note-taking app UI built with Next.js and Tailwind CSS

The layout is centered and responsive, thanks to Tailwind's utility classes. This sets the foundation for a polished and scalable interface.

🔍 What’s Coming Next?

This is just the first version of PatanPad. Here’s what I’m planning next:

  • 💾 LocalStorage support to persist notes between refreshes
  • 🎨 Dark mode toggle with the button in the navbar
  • ✏️ Edit/Delete options for each note
  • 📦 Export/backup notes (maybe as JSON or Markdown)
  • 🚀 Performance optimization and accessibility improvements

🧠 Final Thoughts

Creating PatanPad v1 was quick, fun, and a great exercise in combining Next.js, React, and Tailwind CSS into a usable product. Even this simple app shows how powerful modern frontend tools can be when used together.

If you're building something similar or learning Next.js, I hope this breakdown gave you clarity and inspiration. I’ll be sharing updates as I continue working on PatanPad—stay tuned!

Comments