Build a Notes App with Next.js
Last Updated :
23 Jul, 2025
Note-taking App is a simple web application that allows users to create, edit, and delete text notes. The app provides a user-friendly interface for managing notes, making it easy to add new notes, update existing notes, and delete notes when they are no longer needed. The app provides a way for users who need a quick and convenient way to write down notes and keep track of important information. In this article, we will be building a note-taking app using NextJS.
Output Preview: Let us have a look at how the final output will look like.
.png)
Prerequisites:
Approach to Build a Note-Taking App with Next JS
- Setup the Project by Creating a new Next JS project and installing required dependencies.
- Create functional components such as NoteList and Note. These components will be responsible for displaying form for adding/editing notes and displaying individual notes respectively.
- We will be utilizing React Hook(useState) for state management.
- Implement functionality to delete and edit an existing note.
- We will use Bootstrap to style the application.
Steps to create a Note-Taking App
Step 1: Create a application of NextJS using the following command.
npx create-next-app note-taker
Step 2: Navigate to project directory
cd note-taker
Step 3: Install the necessary packages in your project using the following command.
npm install bootstrap
npm install react-icons --save
Project Structure
.png)
The updated dependencies in package.json file will look like:
"dependencies": {
"bootstrap": "^5.3.3",
"next": "14.1.0",
"react": "^18",
"react-dom": "^18",
"react-icons": "^5.0.1"
}
Example: Below are the components which describes the basic implementation of the Note-Taking App.
JavaScript
// page.js
'use client';
import React, { useState } from 'react';
import NoteList from './components/NoteList';
import 'bootstrap/dist/css/bootstrap.min.css';
const IndexPage = () => {
const [notes, setNotes] = useState([
{
id: 1,
title: 'Meeting',
description: 'Review project, assign task',
important: false,
},
{
id: 2,
title: 'Grocery',
description: 'Milk, Sugar, Apples, eggs',
important: false,
},
]);
const deleteNote = (id) => {
setNotes(notes.filter((note) => note.id !== id));
};
return (
<div className="container col-md-9 mb-3 mt-5 bg-light border border-dark">
<div className="col text-center">
<h2 className="text-success mt-3">
GeekForGeeks
</h2>
<h4>Note Taking App</h4>
</div>
<NoteList notes={notes} setNotes={setNotes} onDelete={deleteNote} />
</div>
);
};
export default IndexPage;
JavaScript
// NoteList.js
import React, { useState } from 'react';
import Note from './Note';
import 'bootstrap/dist/css/bootstrap.min.css';
const NoteList = ({ notes, setNotes, onDelete }) => {
const [newTitle, setNewTitle] = useState('');
const [newDescription, setNewDescription] = useState('');
const [newImportant, setNewImportant] = useState(false);
const [editingNoteId, setEditingNoteId] = useState(null);
const handleAddNote = () => {
const newNote = {
id: notes.length + 1,
title: newTitle,
description: newDescription,
important: newImportant,
};
setNotes([...notes, newNote]);
setNewTitle('');
setNewDescription('');
setNewImportant(false);
};
const onMarkImportant = (id) => {
setNotes(
notes.map((note) =>
note.id === id ? {
...note,
important: !note.important
} : note
)
);
};
const handleUpdateNote = (id, updatedTitle, updatedDescription, updatedImportant) => {
const updatedNotes = notes.map((note) =>
note.id === id ? {
...note,
title: updatedTitle,
description: updatedDescription,
important: updatedImportant
} : note
);
setNotes(updatedNotes);
setEditingNoteId(null);
setNewTitle('');
setNewDescription('');
setNewImportant(false);
};
return (
<div className='container'>
<div className="row mb-3">
<div className="col">
<input
type="text"
className="form-control"
placeholder="Note Title"
value={newTitle}
onChange={(e) => setNewTitle(e.target.value)}
/>
</div>
<div className="col">
<input
type="text"
className="form-control"
placeholder="Note Description"
value={newDescription}
onChange={(e) => setNewDescription(e.target.value)}
/>
</div>
</div>
<div className="row mb-3">
<div className="col">
<div className="form-check">
<input
type="checkbox"
className="form-check-input"
id="importantCheck"
checked={newImportant}
onChange={(e) => setNewImportant(e.target.checked)}
/>
<label className="form-check-label" htmlFor="importantCheck">
Mark as Important
</label>
</div>
</div>
<div className="col">
{editingNoteId ? (
<button
className="btn btn-success"
onClick={() => handleUpdateNote(
editingNoteId,
newTitle,
newDescription,
newImportant
)}
>
Save
</button>
) : (
<button className="btn btn-primary" onClick={handleAddNote}>
Add Note
</button>
)}
</div>
</div>
<div className="row">
{notes.map((note) => (
<div key={note.id} className="col-md-4 mb-3">
<Note
note={note}
onMarkImportant={onMarkImportant}
onDelete={onDelete}
onEdit={() => {
setNewTitle(note.title);
setNewDescription(note.description);
setNewImportant(note.important);
setEditingNoteId(note.id);
}}
/>
</div>
))}
</div>
</div>
);
};
export default NoteList;
JavaScript
// Note.js
import { FaTrash, FaEdit, FaStar } from 'react-icons/fa';
import 'bootstrap/dist/css/bootstrap.min.css';
const Note = ({ note, onDelete, onEdit, onMarkImportant }) => {
const { id, title, description, important } = note;
return (
<div className={`card ${important ? 'border-dark' : 'border-dark'} mb-3`} style={{ maxWidth: '18rem' }}>
<div className="card-body d-flex justify-content-between align-items-center">
<div>
<FaStar
className={`me-2 ${important ? 'text-warning' : 'text-secondary'}`}
onClick={() => onMarkImportant(id)}
/>
<h5 className="card-title">{title}</h5>
<p className="card-text">{description}</p>
</div>
<div>
<button
className="btn me-2 text-danger"
onClick={() => onDelete(id)}
style={{ backgroundColor: 'transparent', fontSize: '1rem' }}
>
<FaTrash style={{ fontSize: '1rem' }} />
</button>
<button
className="btn text-primary"
onClick={() => onEdit(id)}
style={{ backgroundColor: 'transparent' }}
>
<FaEdit style={{ fontSize: '1rem' }} />
</button>
</div>
</div>
</div>
);
};
export default Note;
Start your application using the following command.
npm run dev
Output: Naviagate to the URL http://localhost:3000.