top of page

Using Server Side Packages in Remult And Next.js

  • Writer: Hadar Hubara
    Hadar Hubara
  • 5 days ago
  • 2 min read

In this article, we will explain how to use server-side packages in Remult, implementing an email sending system in a project integrating Remult and Next.js, utilizing Nodemailer, a server-side package for sending emails.


The Problem - Using Server-Side Packages in Remult


One of the challenges when working with Remult is using packages that operate only on the server side (like Nodemailer or fs). In this article, we will explain how to address this challenge with a simple and elegant design.


Remult allows us to write code that runs both on the server and in the browser. However, when we want to use packages that work only on the server side, we encounter an error.


For example, if we try to use Nodemailer directly in a Controller:





We will encounter an error:


Module not found: Can't resolve 'fs'

This happens because Nodemailer depends on the Node.js 'fs' module, which is not available in the browser environment.


The Solution

Instead of importing the package directly, we will use a pattern called "abstract the call" pattern.

An explanation from Remult's excellent documentation:

"Abstract the call and separate it to backend-only files and inject it only when we are running on the server."


Infrastructure Setup

First, we will define a dedicated Controller for sending emails:


We will define the sendEmailFunc in the Controller. Instead of calling Nodemailer directly, we will define the sendEmailFunc describing what we are trying to do.




The sendEmailFunc we defined serves as a placeholder, which we will define in another file. By declaring it here with proper TypeScript typings, we ensure type safety throughout our application.


Defining the Content of sendEmailFunc

  1. Create a new file in the server directory called sendEmailFunc.ts.

  2. Write the function content, import the relevant function from Nodemailer, and perform the email sending operation.




Setting Up the Remult Route and Importing the File

  1. Navigate to the api/[...remult]/route.ts file

  2. Add the EmailController to our list of controllers

  3. Import the server/sendEmailFunc.ts file



The route.ts file runs only on the server side, so it will not display an error, thus solving our problem.


Implementing the sendEmail BackendMethod in EmailController

Now, we will add our BackendMethod named sendEmail, which will call the sendEmailFunc to send emails.



We're done! And now, thanks to Remult, we can use the sendEmail function and easily send emails from both the client and server sides. 🙂


Creating a Form on the Client Side

Create a form on the client side, and call our BackendMethod responsible for sending emails:



Summary

This pattern allows us to enjoy Remult's advantages - writing code that runs on both sides - while using server-side packages in a clean and secure manner. It provides a good solution to one of the common challenges in development with Remult.


Key points to remember:


  1. Define abstract functions in your controller

  2. Implement those functions in server-only files

  3. Import the implementation in your API route

  4. Add proper TypeScript typings for type safety

  5. Call the BackendMethod from your client components


This approach keeps your code modular, type-safe, and maintainable while effectively separating client and server concerns.


留言


bottom of page