Back to articles

Building a Full-Stack SaaS with React, Node.js, and Serverless Functions

AuthorMajd Muhtaseb06/14/20257 minutes
Building a Full-Stack SaaS with React, Node.js, and Serverless Functions

Introduction

This article provides a streamlined approach to constructing a simple SaaS application. We'll focus on the core components: a React-based frontend, a Node.js backend API, and serverless functions to handle specific tasks efficiently. This architecture allows for scalability and cost-effectiveness.

Technology Stack

  • Frontend: React
  • Backend: Node.js (Express)
  • Serverless: AWS Lambda (or similar like Netlify Functions, Vercel Functions)
  • Database: MongoDB (or any preferred database)

Backend API (Node.js with Express)

First, set up a basic Node.js Express server. Here's a simplified example for user authentication:

const express = require('express');
const bodyParser = require('body-parser');
const app = express();
const port = process.env.PORT || 3001;

app.use(bodyParser.json());

app.post('/api/register', (req, res) => {
  // Basic registration logic (example, no actual db interaction)
  const { username, password } = req.body;
  if (username && password) {
    console.log(`User registered: ${username}`);
    res.status(201).json({ message: 'User registered successfully!' });
  } else {
    res.status(400).json({ error: 'Username and password are required.' });
  }
});

app.listen(port, () => {
  console.log(`Server listening on port ${port}`);
});

React Frontend

Create a React component to interact with the backend API:

import React, { useState } from 'react';

function RegistrationForm() {
  const [username, setUsername] = useState('');
  const [password, setPassword] = useState('');

  const handleSubmit = async (event) => {
    event.preventDefault();
    const response = await fetch('/api/register', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ username, password }),
    });

    if (response.ok) {
      alert('Registration successful!');
    } else {
      alert('Registration failed.');
    }
  };

  return (
    <form onSubmit={handleSubmit}>
      <label>
        Username:
        <input type="text" value={username} onChange={(e) => setUsername(e.target.value)} />
      </label>
      <br />
      <label>
        Password:
        <input type="password" value={password} onChange={(e) => setPassword(e.target.value)} />
      </label>
      <br />
      <button type="submit">Register</button>
    </form>
  );
}

export default RegistrationForm;

Serverless Functions (Example - AWS Lambda)

This section demonstrates using a serverless function for a simple task, such as sending a welcome email.

Assumes you have AWS CLI set up and configured.

  1. Create a Node.js file (e.g., sendEmail.js):
exports.handler = async (event) => {
  // Replace with actual email sending logic (e.g., using Nodemailer and AWS SES)
  console.log('Sending welcome email to:', event.email);

  return {
    statusCode: 200,
    body: JSON.stringify({ message: 'Welcome email sent!' }),
  };
};
  1. Zip the file: zip sendEmail.zip sendEmail.js

  2. Create the Lambda Function (using AWS CLI):

aws lambda create-function \
    --function-name sendWelcomeEmail \
    --zip-file fileb://sendEmail.zip \
    --runtime nodejs18.x \
    --handler sendEmail.handler \
    --role arn:aws:iam::YOUR_ACCOUNT_ID:role/YOUR_LAMBDA_EXECUTION_ROLE

Replace YOUR_ACCOUNT_ID and YOUR_LAMBDA_EXECUTION_ROLE with your actual AWS account ID and IAM role ARN.

  1. Invoke the Function (from your React frontend or Node.js backend):

You'd need to use the AWS SDK in your frontend or backend to invoke this Lambda function. This involves setting up AWS credentials appropriately.

Conclusion

This outlines a basic foundation for building a full-stack SaaS application. Remember to implement robust security measures, proper error handling, and a reliable database connection for production environments. Further development should include features specific to your SaaS offering.