A complete reference implementation demonstrating how to build a production-ready MERN stack application with Express Suite.
This example serves as your guide to building secure, scalable, and internationalized web applications using the Express Suite ecosystem. Follow along to see how all the pieces fit together.
This example demonstrates:
- 🔐 Authentication & Authorization - JWT tokens, email verification, backup codes, RBAC
- 🗄️ Database Integration - MongoDB with Mongoose, user management, role system
- 🔒 End-to-End Encryption - ECIES encryption for sensitive data
- 🌍 Internationalization - Multi-language support with i18n-lib
- ⚛️ React Integration - Pre-built auth components, hooks, and providers
- 🎨 Material-UI Theming - Dark/light mode, responsive design
- 🧪 Testing - Unit tests, integration tests, E2E tests with Playwright
- 📦 Monorepo Structure - Nx workspace with shared libraries
This monorepo contains 8 projects demonstrating the complete Express Suite stack:
express-suite-example/
├── express-suite-example-api/ # Express 5 backend with node-express-suite
├── express-suite-example-api-lib/ # Shared API types and utilities
├── express-suite-example-react/ # React 19 frontend with MUI
├── express-suite-example-react-lib/ # Shared React components
├── express-suite-example-lib/ # Shared business logic
├── express-suite-example-inituserdb/ # Database initialization script
├── express-suite-example-api-e2e/ # API integration tests
└── express-suite-example-react-e2e/ # Frontend E2E tests (Playwright)
- Node.js 18+
- MongoDB 6+ (or use in-memory database for development)
- Yarn package manager
# Clone and install
git clone https://github.com/Digital-Defiance/express-suite-example.git
cd express-suite-example
yarn install
# Build all projects
yarn build:dev
# Initialize database with default users and roles
yarn init:db
# Start the API server (http://localhost:3000)
yarn serve:dev
# In another terminal, start the React app (http://localhost:4200)
cd apps/express-suite-example-react
yarn startAfter running yarn init:db, you'll have:
- Admin:
admin@example.com/AdminPassword123! - User:
user@example.com/UserPassword123!
See apps/express-suite-example-api/src/main.ts:
import { Application } from '@digitaldefiance/node-express-suite';
const app = new Application({
port: 3000,
mongoUri: process.env.MONGODB_URI,
jwtSecret: process.env.JWT_SECRET,
defaultLanguage: 'en-US'
});
await app.start();See apps/express-suite-example-api/src/routes/users.ts:
import { requireAuth, requireRole } from '@digitaldefiance/node-express-suite';
router.get('/users',
requireAuth(),
requireRole(['admin']),
async (req, res) => {
// Only admins can list users
}
);See apps/express-suite-example-react/src/App.tsx:
import {
SuiteConfigProvider,
AuthProvider,
LoginFormWrapper
} from '@digitaldefiance/express-suite-react-components';
function App() {
return (
<SuiteConfigProvider baseUrl="http://localhost:3000" routes={{ dashboard: '/dashboard' }}>
<AuthProvider baseUrl="http://localhost:3000">
<LoginFormWrapper />
</AuthProvider>
</SuiteConfigProvider>
);
}See apps/express-suite-example-api-lib/src/services/encryption.ts:
import { ECIESService } from '@digitaldefiance/node-ecies-lib';
const ecies = new ECIESService();
const encrypted = await ecies.encryptWithLength(publicKey, sensitiveData);
const decrypted = await ecies.decryptWithLengthAndHeader(privateKey, encrypted);See apps/express-suite-example-react/src/i18n.ts:
import { PluginI18nEngine, LanguageCodes } from '@digitaldefiance/i18n-lib';
const engine = PluginI18nEngine.createInstance('app', [
{ id: LanguageCodes.EN_US, name: 'English', code: 'en-US', isDefault: true },
{ id: LanguageCodes.FR, name: 'Français', code: 'fr' }
]);Key Files:
src/main.ts- Application entry point with Express Suite setupsrc/routes/- API route definitions with authenticationsrc/middleware/- Custom middleware (logging, error handling)src/services/- Business logic services
Features Demonstrated:
- JWT authentication with refresh tokens
- Email verification flow
- Password reset with tokens
- Backup code generation and validation
- Role-based access control
- MongoDB transactions
- Error handling with i18n
Key Files:
src/App.tsx- Root component with providerssrc/pages/- Page components (Login, Dashboard, Settings)src/components/- Custom componentssrc/hooks/- Custom React hooks
Features Demonstrated:
- Authentication flow (login, register, verify email)
- Protected routes
- User settings management
- Theme switching (dark/light mode)
- Language switching
- API integration with axios
express-suite-example-lib - Business logic shared between API and React:
- User interfaces and types
- Validation schemas
- Constants and enums
express-suite-example-api-lib - API-specific shared code:
- Database models
- API types
- Utility functions
express-suite-example-react-lib - React-specific shared code:
- Reusable components
- Custom hooks
- Context providers
# Unit and integration tests
yarn test:jest
# E2E tests (requires running servers)
yarn test:e2e
# All tests
yarn test:allSee individual project test files:
- API:
apps/express-suite-example-api/src/**/*.spec.ts - React:
apps/express-suite-example-react/src/**/*.spec.tsx - E2E:
apps/express-suite-example-react-e2e/src/**/*.spec.ts
- Define types in
express-suite-example-lib - Create API endpoint in
express-suite-example-api - Add database model in
express-suite-example-api-lib - Build React component in
express-suite-example-react - Write tests for all layers
# 1. Add types
echo "export interface IPost { title: string; content: string; }" > libs/express-suite-example-lib/src/interfaces/post.ts
# 2. Add API route
touch apps/express-suite-example-api/src/routes/posts.ts
# 3. Add model
touch apps/express-suite-example-api-lib/src/models/post.model.ts
# 4. Add React component
touch apps/express-suite-example-react/src/components/PostList.tsx
# 5. Add tests
touch apps/express-suite-example-api/src/routes/posts.spec.ts
touch apps/express-suite-example-react/src/components/PostList.spec.tsxCreate .env files in each app:
apps/express-suite-example-api/.env:
MONGODB_URI=mongodb://localhost:27017/express-suite-example
JWT_SECRET=your-secret-key-here
JWT_EXPIRES_IN=7d
EMAIL_FROM=noreply@example.com
SMTP_HOST=smtp.example.com
SMTP_PORT=587apps/express-suite-example-react/.env:
REACT_APP_API_URL=http://localhost:3000# Build all projects for production
yarn build
# Start API in production mode
yarn serveSee docker-compose.yml for containerized deployment:
docker-compose up -d// React component
import { useAuth } from '@digitaldefiance/express-suite-react-components';
const { token } = useAuth();
const response = await axios.get('/api/users', {
headers: { Authorization: `Bearer ${token}` }
});// Shared validation schema
import * as Yup from 'yup';
export const userSchema = Yup.object({
email: Yup.string().email().required(),
password: Yup.string().min(8).required()
});// API error handler
import { handleError } from '@digitaldefiance/node-express-suite';
app.use((err, req, res, next) => {
handleError(err, req, res);
});# Check MongoDB is running
mongosh
# Or use in-memory database for development
export USE_IN_MEMORY_DB=true# Change port in .env
PORT=3001# Clean and rebuild
yarn clean
yarn install
yarn build:devyarn build- Production build of all projectsyarn build:dev- Development build of all projectsyarn serve:dev- Start API server in development modeyarn serve- Start API server in production modeyarn test:all- Run all tests (Jest + E2E)yarn test:jest- Run Jest tests onlyyarn test:e2e- Run Playwright E2E testsyarn lint:all- Lint all projectsyarn prettier:check- Check code formattingyarn prettier:fix- Fix code formattingyarn init:db- Initialize database with default users
MIT © Digital Defiance