Architecture Overview
Relevant source files
The following files were used as context for generating this wiki page:- README.md
- API_REFERENCE.md
- QUICK_START.md
- mono-repo.md
- package.json
- packages/client/src/index.ts
- packages/core/prisma/schema.prisma
- packages/core/src/api/controllers/messageController.ts
- packages/core/src/api/middleware/authMiddleware.ts
- packages/core/src/index.ts
- packages/core/src/types/apiTypes.ts
- packages/core/src/types/dataModels.ts
- packages/dashboard/package.json
MessageJS is a service that enables developers to send messages via multiple chat platforms like WhatsApp, Telegram, and SMS through a unified API. The architecture is designed to be secure and pluggable, abstracting away the complexity of handling different messaging provider APIs and keeping credentials safe on the backend.
The system is built as a monorepo containing distinct packages for the backend API, frontend SDK, and a management dashboard. The core principle is to provide a simple developer experience, similar to EmailJS or SendGrid, but for chat applications. The backend is built with Node.js and Express, using a PostgreSQL database, while the client-side SDK is a lightweight JavaScript library.
Sources: README.md:10-13, README.md:60-64, package.json:5
Monorepo Structure
The project is organized as a monorepo using npm workspaces, which contains several distinct packages. This structure allows for shared code, streamlined development, and independent package management.
Sources: package.json:6-8, mono-repo.md
The diagram below illustrates the high-level structure of the monorepo and its packages.
The key packages within the monorepo are:
| Package | Description | Source |
|---|---|---|
@messagejs/core | The Node.js/Express backend API that handles authentication, message routing, and communication with third-party services. | README.md:18 |
@messagejs/client | A lightweight frontend SDK for browsers and Node.js environments, providing init() and sendMessage() methods. | README.md:19 |
@messagejs/dashboard | A React/Next.js application for users to manage their projects, connectors, and API keys. | mono-repo.md:13, packages/dashboard/package.json:3 |
@messagejs/shared-types | A package containing shared TypeScript types used across the core, client, and dashboard packages. | README.md:20 |
@messagejs/examples | A collection of example applications (e.g., React, Node.js) demonstrating how to use the @messagejs/client SDK. | mono-repo.md:19, packages/examples/README.md |
Sources: README.md:16-21, mono-repo.md
High-Level System Flow
The fundamental data flow in MessageJS involves the client application using the SDK to make a secure request to the core API, which then processes the request and dispatches the message through the appropriate third-party provider.
This diagram shows the end-to-end message sending flow.
Sources: README.md:62, QUICK_START.md:13-18
Core Components
@messagejs/client SDK
The client SDK is the public-facing library that developers integrate into their applications. It is designed to be simple and lightweight.
Key Functionality
- Initialization: The SDK must be initialized with a project-specific API key using the
init()method. This configures the SDK to communicate with the MessageJS backend. - Message Sending: The
sendMessage()method is the primary function, which takes parameters like the recipient, template, and variables, and sends them to the backend API.
Sources: packages/client/src/index.ts:70-126, QUICK_START.md:65-74
This class diagram shows the public interface of the MessageJS SDK class.
@messagejs/core Backend
The core backend is an Express.js application responsible for all server-side logic.
Sources: packages/core/src/index.ts:7, packages/core/package.json:17
API Server & Message Flow
The backend exposes a REST API. The primary endpoint for the SDK is POST /api/v1/messages. When a request hits this endpoint, it goes through a series of steps:
- Entry Point: The request is received by the Express server defined in
packages/core/src/index.ts. - Authentication: The
validateApiKeymiddleware intercepts the request. It checks for aBearertoken in theAuthorizationheader and validates the API key. If valid, it attaches key details likeprojectIdto the request object. - Controller: Control is passed to the
sendMessagecontroller. This controller is responsible for validating the request body, creating aMessageLogentry in the database with aqueuedstatus, and (in a full implementation) pushing a job to a message queue for asynchronous processing. - Response: The API immediately responds with a
202 Acceptedstatus, confirming the message has been queued for sending. This includes amessageIdfor tracking.
The following sequence diagram illustrates this flow:
Database Schema
The system uses a PostgreSQL database, with the schema managed by Prisma. The data model is designed to support multiple users, projects, and messaging service configurations.
Sources: packages/core/prisma/schema.prisma:8-10, README.md:67
The Entity-Relationship diagram below describes the database tables and their relationships.
This diagram shows the relationships between User, Project, Service, Template, and MessageLog entities.
Sources: packages/core/prisma/schema.prisma:29-106, packages/core/prisma/migrations/20251029214807_init/migration.sql
Data Models
- User: Represents a developer account. A user can own multiple projects.
- Project: A container for connectors, templates, and message logs. Each project has a unique API key.
- Service: Represents a configured third-party messaging provider (e.g., WhatsApp, Twilio). Credentials are encrypted.
- Template: Reusable message content with variables (e.g.,
Hello {{name}}). - MessageLog: A record of every message sent through the system, tracking its status and other metadata.
Sources: packages/core/prisma/schema.prisma:29-106, packages/core/src/types/dataModels.ts:8-100
API & Data Contracts
The system's internal and external boundaries are well-defined using TypeScript interfaces.
apiTypes.ts: Defines the shape of all REST API request bodies and responses, such asSendMessageRequestandApiErrorResponse. This file serves as the public contract for the API.dataModels.ts: Defines the shape of the core database entities, such asUser,Project, andMessage. These types are used throughout the backend application logic.
An example of a key API contract is the SendMessageRequest:
// From packages/core/src/types/apiTypes.ts
export interface SendMessageRequest {
connectorId: string;
templateId: string;
to: string;
variables: Record<string, any>;
metadata?: Record<string, any>;
}
Sources: packages/core/src/types/apiTypes.ts:4-5, packages/core/src/types/apiTypes.ts:32-40, packages/core/src/types/dataModels.ts:4-5
Tech Stack
The project utilizes a modern TypeScript-based stack.
| Category | Technology | Source(s) |
|---|---|---|
| Runtime | Node.js 20+ | package.json:18 |
| Language | TypeScript 5.3+ | package.json:16 |
| Backend Framework | Express.js | packages/core/package.json:17 |
| Database | PostgreSQL | README.md:67 |
| ORM | Prisma | packages/core/package.json:15 |
| Frontend (Dashboard) | React / Next.js | packages/dashboard/package.json:12-14 |
| SDK Bundler | Rollup | packages/client/package.json:23 |
Sources: README.md:65-71
Conclusion
The MessageJS architecture is a well-structured, service-oriented system built within a monorepo. It clearly separates concerns between the client-facing SDK, the core backend logic, and the user-facing dashboard. Key architectural patterns include a unified API gateway, pluggable connectors for extensibility, a robust database schema for multi-tenancy, and clearly defined data contracts using TypeScript. This design provides a secure, scalable, and developer-friendly platform for integrating messaging services.