Introduction: Moving Beyond In-Memory Storage

Welcome back! In the last lesson, you learned how to use the Repository Pattern to keep your data logic separate from your business logic. Up until now, you have been storing your data in memory, which means all your tasks disappear every time you restart your app. This is fine for learning, but in real-world applications, you need your data to persist even after the server restarts.

In this lesson, you will learn how to save your data to a file using JSON. This is called file-based persistence. By the end of this lesson, you will know how to read and write your tasks to a JSON file, making your app more like a real backend service.


Recap: Task Data and Project Structure

Let’s quickly remind ourselves of the Task data structure and where our data lives. You have a Task type that looks like this:

Previously, you stored tasks in memory using an array. Now, you will use a file called data/tasks.json to store your tasks. This file will look like this when empty:

This file will grow as you add, update, or delete tasks. The rest of your project structure stays the same, but now your data will be saved in a file instead of just in memory.


Reading and Writing JSON Files in Node.js

To work with files in Node.js, you use the built-in fs/promises module. This module lets you read and write files using promises, which means you can use async and await for cleaner code.

Here’s a simple example of reading and writing a JSON file:

Explanation:

  • fs.readFile reads the file as a string.
  • JSON.parse turns the string into a JavaScript array.
  • fs.writeFile saves the array back to the file as a JSON string.
  • JSON.stringify(tasks, null, 2) makes the JSON file easy to read by adding indentation. The second and third arguments in JSON.stringify(tasks, null, 2) ensure the JSON file is pretty-printed with 2-space indentation, making it easier to inspect manually.

Output Example: If you call writeTasks([{ id: 1, title: "Learn Next.js", completed: false }]), your tasks.json file will look like:


Building the File-Based Task Repository

Now, let’s build a repository that uses the JSON file for storage. Here’s the main code for your file-based repository:

Explanation:

  • read() loads all tasks from the JSON file. It also updates nextId so new tasks get unique IDs.
  • write(tasks) saves the current list of tasks to the file.
  • Each method (getAll, getById, create, , , ) reads the file, makes changes, and writes back if needed.
Swapping the Repository Implementation

One of the main benefits of using the Repository Pattern is how easily you can swap between data sources. In the previous lesson, your taskService.ts used an in-memory repository:

To persist tasks to disk, you simply switch to:

The rest of your service logic — and your entire API — doesn’t change at all. That’s because both mapTaskRepository and fileTaskRepository conform to the same TaskRepository interface. Since the interface defines the expected contract, the service functions can remain the same regardless of the underlying implementation.


Connecting the Repository to the Service Layer

Now, let’s connect your new file-based repository to the service layer. This is where your business logic lives. Here’s how you update your service to use the new repository:

Explanation:

  • The service now uses fileTaskRepository instead of the in-memory one.
  • All your service functions (getAllTasks, createTask, etc.) now work with data stored in the JSON file.
  • This change is invisible to the rest of your app, thanks to the Repository Pattern.

Summary and Practice Preview

In this lesson, you learned how to move from in-memory storage to file-based persistence using JSON files. You saw how to:

  • Read and write JSON files in Node.js using fs/promises
  • Build a repository that saves tasks to a file
  • Connect your service layer to use the new file-based repository

This makes your app more production-ready, as your data will now survive server restarts. In the next practice exercises, you’ll get hands-on experience working with file-based persistence. Great job making it this far — let’s keep going!

Sign up
Join the 1M+ learners on CodeSignal
Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal