Using Server Side Packages in Remult And Next.js
- 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
Create a new file in the server directory called sendEmailFunc.ts.
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
Navigate to the api/[...remult]/route.ts file
Add the EmailController to our list of controllers
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:
Define abstract functions in your controller
Implement those functions in server-only files
Import the implementation in your API route
Add proper TypeScript typings for type safety
Call the BackendMethod from your client components
This approach keeps your code modular, type-safe, and maintainable while effectively separating client and server concerns.
留言