An open API service indexing awesome lists of open source software.

https://github.com/ironexdev/ent-stack

Full-stack TypeScript project starter - Express Next.js TRPC
https://github.com/ironexdev/ent-stack

express monorepo nextjs pnpm starter-kit trpc typescript

Last synced: 8 months ago
JSON representation

Full-stack TypeScript project starter - Express Next.js TRPC

Awesome Lists containing this project

README

          

# ENT Stack



![ent-title](https://github.com/user-attachments/assets/9b4b4cf5-a2ca-4e9b-b498-3362cc7953b1)



[![NPM version][npm-image]][npm-url] [![Setup Guide][setup-guide-image]][setup-guide-url] [![ffn][documentation-image]][documentation-url]

## Table of Contents

- [What is the ENT Stack](#table-of-contents)
- [Features](#features)
- [Getting Started](#getting-started)
- [Documentation](#documentation)
- [Troubleshooting](#troubleshooting)

## What is the ENT Stack?

The ENT Stack is a full-stack TypeScript project starter that integrates **E**xpress 5, **N**ext.js 15, and **T**RPC.

It allows you to build and **share code** between frontend and backend in a single project while maintaining the flexibility to **host them separately**.

## Features

๐ŸŒ€ **PNPM Workspace - Monorepo**

- The stack uses PNPM Workspace because it's simple and painless to use. With its efficient dependency management and shared package architecture, PNPM ensures faster installs and a clean, modular workflow.
- Within the monorepo, each top-level folder plays a distinct role:
- **apps** folder contains both the backend (`apps/backend`) and frontend (`apps/frontend`) codebases.
- **packages** folder contains a `shared` directory (`packages/shared`) that centralizes common configurations, utilities, services type definitions, and translations.
- To maintain uniform code quality, each of these directories includes an `eslint.config.js` file featuring consistent rules. A root-level `tsconfig.json` provides a base set of TypeScript configurations, while each subproject extends these defaults to meet its own requirements.

๐Ÿค **Type-Safe API Layer**

- The stack leverages TRPC to create a type-safe bridge between the frontend and backend. This ensures that your IDE automatically provides type hints and autocompletion for API endpoints, eliminating the need for manual type definitions.

โš™๏ธ **Environment and Configuration**

- Leverages T3 Env type-safe environment variables validation in both backend and frontend
- Contains Shared configuration file `shared-config.ts` that is extended by both Backend `backend-config.ts` and Frontend `frontend-config.ts` files for feature-focused settings

๐Ÿ›ข๏ธ **Database**

- The backend uses Drizzle ORM for interacting with a MySQL database, providing a type-safe and developer-friendly API.
- It also contains Docker Image and a script `bin/docker/run-local-db.sh` to run the database locally.

๐Ÿ”’ **Authentication and Authorization**

- The stack provides passwordless registration and login through short verification PINs, secure JWT access tokens, and UUID-based refresh tokens. Additionally, frontend routes can be marked as protected in `routes.ts`, restricting them to authenticated users - this is evaluated in `middleware.ts`.

๐Ÿชฒ **Validation and Error Handling**

- The stack uses Zod for consistent input validation across the frontend and backend, integrated with TRPC for type-safe error management.
- Input is sanitized to prevent injection attacks.
- Errors are categorized into client, server, and userland types for precise handling.
- Tanstack Query handles errors through a custom handler with callbacks for server, client, and userland errors.

๐Ÿ”„ **State Management**

- Uses Zustand for lightweight, synchronous global state management, delivering a minimal overhead approach for storing and controlling shared data across the application.
- Uses Tanstack Query for asynchronous data fetching and caching, providing an SSR-friendly solution that keeps the UI and server in sync.

๐ŸŒ **Internationalization (i18n) and Localization**

- A custom, lightweight solution handles localization using standalone functions that use ICU message syntax.
- Translation functions can be used anywhere in the stack (both backend and frontend).
- The stack includes two scripts for message import (`pnpm import-messages`) and export (`pnpm export-messages`)
- Frontend routes are fully translatable, defined in standalone .ts file, and dynamically evaluated at runtime through Next.js middleware.

๐Ÿชต **Logging**

- The stack employs Pino for lightweight and efficient logging across both backend and frontend. Its simple API and minimal overhead ensure clear, structured logs without impacting performance.

โœ‰๏ธ **Mailing**

- integrates Resend for developer friendly e-mail sending.
- Backend also contains email test router for email previews and testing.
- Email templates are written in Handlebars.

๐Ÿค– **Testing**

- The stack uses Playwright for unified frontend and backend testing, ensuring consistency and reliability.
- Mailslurp is used for receiving e-mails in tests.

๐Ÿณ **DevOPS - Infrastructure and CI/CD**

- Example Infrastructure and CI/CD for the ENT Stack is in a separate repository.
## Getting Started

Get up and running with the ENT Stack in just two steps:

**Prerequisites**
- Node.js
- PNPM
- Docker CLI (for local MySQL database)
- A Unix-like shell environment (e.g., Bash, Zsh)

๐Ÿ’ก How to install prerequisites on Ubuntu 24

### 1/ ๐Ÿš€ Create your project

```bash
pnpm create ent-stack@latest
```
- Creates a new project (folder) based on specific version of this repository.
- The version used is specified in the description of the npm package.

### 2/ ๐Ÿ”ฅ Setup

```bash
pnpm fire
```
- Installs dependencies
- Starts the local database in a Docker container
- Creates the database and tables
- Runs dev environments for both the backend and frontend

At this point, your application should be up and running locally. But to enable email sending and testing, you need to follow the final step below.

### 3/ ๐Ÿงช Configure Mailing and Run Tests

To enable mailing, you need to do the following:
- **[Sign up for a free Resend account](https://resend.com/signup)** and set **SERVICE_EMAIL**, **SECURITY_EMAIL** and **RESEND_API_KEY** in `apps/backend/.env`
- Serves as a service for sending e-mails



Resend domain


Resend API Key

- **[Sign up for a free MailSlurp account](https://app.mailslurp.com/sign-up)** and set **MAILSLURP_INBOX_ID** and **MAILSLURP_EMAIL** in `apps/backend/.env`
- Serves as a service for receiving e-mails (for testing purposes)



MailSlurp inbox and inbox id


MailSlurp API Key


After that, make sure to **restart dev** environment, and then you can run the tests by executing the following commands:
- Test Backend
```bash
pnpm backend:test
```
- Test Frontend
```bash
pnpm frontend:test
```

Here is the list of values that **MUST BE THE SAME** in both backend and frontend **.env** files:

| Backend | Frontend |
|---------------|---------------------------|
| SITE_NAME | NEXT_PUBLIC_SITE_NAME |
| COOKIE_DOMAIN | NEXT_PUBLIC_COOKIE_DOMAIN |
| BACKEND_URL | NEXT_PUBLIC_BACKEND_URL |
| FRONTEND_URL | NEXT_PUBLIC_FRONTEND_URL |
| JWT_SECRET | JWT_SECRET |

## Documentation

For information about ENT Stack features go to the ๐Ÿ“„ [Documentation](https://ent-stack.com/ent-stack/documentation/)

## Troubleshooting

1/ **IDE issues**
```
- Node interpreter is not set
- Eslint/Prettier is not working on save
- TypeScript highlights non-existent errors
```
- These issues can occur if your IDE is not properly configured. For reference, I'm attaching my PHPStorm (WebStorm) configuration on WSL2 with Ubuntu, showing the settings for ESLint, Prettier, and Node.js.:



Eslint Settings

Prettier Settings

Node.js Settings

2/ **MySQL container name conflict**
```
docker: Error response from daemon: Conflict. The container name "/mysql" is already in use by container
```
- Remove the existing container by running `docker rm mysql`
- Or for more nuclear solution, run `bin/docker/cleanup.sh`
- this script forcefully cleans up Docker by removing all build caches, containers, images, and unused networks to free disk space and reset the environment.

[npm-url]: https://www.npmjs.com/package/create-ent-stack
[npm-image]: https://img.shields.io/npm/v/create-ent-stack?color=b45bf5&logoColor=0b7285

[setup-guide-url]: https://ent-stack.com/ent-stack/setup/
[setup-guide-image]: https://img.shields.io/badge/setup_guide-726fff

[documentation-url]: https://ent-stack.com/ent-stack/documentation
[documentation-image]: https://img.shields.io/badge/documentation-726fff