{"id":26543777,"url":"https://github.com/lumitech-co/lumitech-node-fastify-template","last_synced_at":"2025-03-22T03:15:18.643Z","repository":{"id":283622977,"uuid":"950078984","full_name":"lumitech-co/lumitech-node-fastify-template","owner":"lumitech-co","description":"Lumitech Node.js Fastify Template offers well-defined architectural patterns, ensuring the code remains maintainable, scalable, and testable, especially as the application grows.","archived":false,"fork":false,"pushed_at":"2025-03-21T07:18:14.000Z","size":30,"stargazers_count":4,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-03-21T08:25:22.590Z","etag":null,"topics":["fastify","nodejs","templates","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lumitech-co.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2025-03-17T15:44:02.000Z","updated_at":"2025-03-18T19:10:34.000Z","dependencies_parsed_at":"2025-03-21T08:35:49.284Z","dependency_job_id":null,"html_url":"https://github.com/lumitech-co/lumitech-node-fastify-template","commit_stats":null,"previous_names":["lumitech-co/lumitech-node-fastify-template"],"tags_count":0,"template":true,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lumitech-co%2Flumitech-node-fastify-template","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lumitech-co%2Flumitech-node-fastify-template/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lumitech-co%2Flumitech-node-fastify-template/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lumitech-co%2Flumitech-node-fastify-template/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lumitech-co","download_url":"https://codeload.github.com/lumitech-co/lumitech-node-fastify-template/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244898458,"owners_count":20528341,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["fastify","nodejs","templates","typescript"],"created_at":"2025-03-22T03:15:17.867Z","updated_at":"2025-03-22T03:15:18.633Z","avatar_url":"https://github.com/lumitech-co.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"![image](https://github.com/user-attachments/assets/c5fc1141-7e6c-4603-acd1-ea1e7e99f217)\n\n# Lumitech Node.js Fastify Template \nWelcome to the Lumitech Node.js Fastify Template. This template provides a well-organized starting point for building back-end applications in Node.js, featuring Swagger-based API documentation, ready-to-use Docker configuration, and Awilix for dependency injection. With well-defined architectural patterns, it helps ensure the code remains maintainable, scalable, and testable, especially as the application grows.\n\n### About Lumitech\nLumitech is a custom software development company providing professional services worldwide. We partner with technology businesses globally helping them to build successful engineering teams and create innovative software products. We’re a global team of software engineers, AI and ML specialists, product managers, and technology experts who have achieved a 600% growth rate since 2022. When a rocket launches toward the moon, it doesn’t stop halfway. Neither do we.\n\n## 🛠️ Technology Stack:\n- [TypeScript](https://www.typescriptlang.org/) - programming language;\n- [Node.js](https://nodejs.org/en) - JavaScript runtime;\n- [Fastify](https://fastify.dev/docs/latest/Guides/Getting-Started/) - HTTP framework;\n- [Zod](https://zod.dev) - validation;\n- [Swagger](https://swagger.io/) - API documentation;\n- [Awilix](https://github.com/jeffijoe/awilix) - Dependency Injection container;\n- [PostgreSQL](https://www.postgresql.org/) - relational database;\n- [Prisma](https://www.prisma.io/docs/getting-started) - database ORM.\n\n## 📌 Getting Started\n\n### 🚀 Project Launch\n1. `npm install` - install the dependencies locally;\n2. Create a `.env` file from `.env.example`;\n3. Launch Docker Compose with the `docker compose up` command.\n\n### ⚙️ Running Prisma Migrations\nSince both the Node.js server and PostgreSQL database run inside Docker containers, the database connection uses the [docker compose network](https://docs.docker.com/compose/networking/).\nInside the Node.js container, use `postgresdb` as the database host.\n\nTo run migrations from a host machine:\n1. Launch docker containers - `docker compose up`;\n2. Update the `.env` file, changing `DATABASE_URL` host from `postgresdb` to `localhost`;\n3. Run `npm run prisma:migrate:create` - create SQL migration file;\n4. Name the new migration and verify the SQL code generated;\n5. Run `npm run prisma:migrate:apply` - apply the migration to the database;\n6. Revert the `DATABASE_URL` in `.env`  back to `postgresdb` so that the Node.js container can connect to the database after a rebuild.\n\n## ⚙ Key Features\n\n### 🧩 Dependency Injection\n\nThis template utilizes **Awilix** for Dependency Injection (DI), which helps in managing application dependencies efficiently.\n\n#### Why Use Dependency Injection?\n- **Encapsulation \u0026 Maintainability**: Keeps the code modular and easier to maintain.\n- **Testability**: Improves unit testing by allowing easy mocking of dependencies.\n- **Cleaner Architecture**: Enhances readability and organization.\n- **Implemented Patterns**: Uses Dependency Inversion, Inversion of Control, and Singleton.\n\n#### How Awilix is Used\n\nAwilix is configured as a Fastify plugin, allowing services, handlers, repositories and custom dependencies to be injected dynamically. It enables clean and organized code by managing dependencies automatically. The DI container is registered in `src/plugins/awilix.ts`.\n\n#### DI Usage Example:\n\nDefine an email service abstraction layer in the lib directory.\n\n`src/lib/emails/index.ts`\n```typescript\nexport type EmailService = {\n    sendEmail: (emailRecipient: string, p: EmailOptions) =\u003e Promise\u003cvoid\u003e;\n};\n\nexport const createEmailService = (\n    config: EnvConfig,\n    log: FastifyBaseLogger\n): EmailService =\u003e {\n    const emailProvider = new EmailProvider({ secretKey: config.secretKey });\n\n    return {\n        sendEmail: async (emailRecipient, email) =\u003e {\n            ...\n            await emailProvider.sendEmail(emailRecipient, email);\n            ...\n        },\n    };\n};\n```\nRegister the email service in the DI container.\n\n`src/plugins/awilix.ts`\n```typescript\n// Register dependencies from plugins and libraries\nfastify.di.register({\n    log: asValue(fastify.log),\n    config: asValue(fastify.config),\n    emailService: asFunction(createEmailService),\n});\n```\nUse the email service by specifying its name in the function parameters.\n\n`src/modules/user/user.service.ts`\n```typescript\nexport type UserService = {\n    sendWelcomeEmail: (\n        userId:string,\n    ) =\u003e Promise\u003cUserEventsResponseBody\u003e;\n};\n\nexport const createUserService = (\n    emailService: EmailService,\n): UserService =\u003e ({\n    sendWelcomeEmail: async (userId) =\u003e {\n        ...\n        await emailService.sendEmail(email, {...});\n        ...\n    },\n});\n\naddDIResolverName(createService, \"userService\"); // Define a unique DI container name for automatic loading.\n```\n\n### 🐳 Docker\nThis template provides a `Dockerfile` for building a production-ready Node.js image and a `docker-compose.yml` file for local development. By default, Docker Compose starts two services:\n\n1. **Node.js** – Runs the application inside a container using the provided Dockerfile.\n2. **PostgreSQL** – Spins up a PostgreSQL database.\n\nIs is possible can add more services (for example, Redis) by including them in `docker-compose.yml` and configuring their networking and environment variables. \nThis setup allows to quickly bootstrap a fully containerized development environment without installing any dependencies locally other than Docker itself.\n\n### 📖 REST API Documentation\n\nThis template includes **Swagger** for automatic API documentation generation, making it easy to document REST API endpoints.\n\n#### Automatic Generation\n\n- **Swagger Integration**: The Fastify Swagger plugin automatically generates API documentation from route schemas.\n- **Route Description**: It is possible to categorize endpoints by tags and describe them in the route schema.\n- **Authorization**: Secure the documentation with a password.\n\nExample route with Swagger options:\n```typescript\nfastify.post(\n    \"/sign-up\",\n    {\n        schema: {\n            tags: [\"auth\"], // Categorizes the route under the specified tags.\n            summary: \"Create a new user account\".\n            description: \"Create a new user within the system\",\n            body: signUpBodySchema,\n            response: {\n                200: signUpResponseSchema,\n            },\n        },\n    },\n    authHandler.signUp\n);\n```\n\n### ⚙️ Repository Generation\nThe template provides an automatic repository generator based on the Prisma Schema data model.\nIt includes a set of commonly used CRUD operations for any entity.\n\nThe generator is located in `src/database/repositories/generate.repository.ts`.\n\n```typescript\nconst userRepository = generateRepository(prismaClient, \"User\");\n\nconst user = await userRepository.create({\n    data: {},\n    select: {},\n});\n\n// Methods available: create, update, delete, etc.\nawait userRepository.delete({\n    where: {},\n});\n```\n\n### 📜 Commits Format\n\nWe use Commitlint to ensure that commit messages adhere to the conventional commit format. This standardizes the commit history and simplifies changelog generation.\n\nThe basic format is:\n```sh\ntype(scope?): subject\n```\n\nExamples:\n- `chore: update dependencies`\n- `fix(message): correct API response error`\n- `feat(auth): add JWT authentication`\n\nA more detailed description you can see in [Conventional Commits documentation](https://www.conventionalcommits.org/en/v1.0.0/#examples).\n\n## 📁 Project Structure\nThe project is organized into several parts to promote a modular design and separation of concerns:\n\n#### `src/database`:  \nThis directory manages everything related to data persistence and interaction with the database.  \n- The `prisma` subfolder houses the Prisma schema (`schema.prisma`) and migration files that define the application's data model to the database.  \n- The `repositories` subfolder contains repository modules for each entity. These repositories provide a unified API for CRUD operations (e.g., in `generate.repository.ts`) and custom logic for data access (e.g., `message.repository.ts` for the Message model).\n\n#### `src/modules`:  \nThis directory contains feature-based modules which encapsulate business logic along with the HTTP layer.  \nEach module includes:  \n- **Routes**: Define endpoint paths and attach them to the appropriate handlers (e.g., `message.route.ts` for message-related endpoints).  \n- **Handlers**: Manage request processing and response formatting by invoking corresponding services (e.g., `message.handler.ts`).  \n- **Services**: Implement business logic, coordinate with repositories, and use the necessary third-party libraries from `src/lib` (e.g., `message.service.ts`).\n\n#### `src/plugins`:  \nThe directory is dedicated to Fastify plugins which extend the server capabilities. Each file registers a plugin that adds functionality to the Fastify instance.  \nPlugins included:  \n- **Environment Configuration** (`env.ts`): Loads and validates environment variables.  \n- **Database Management** (`prisma.ts`): Sets up a `PrismaClient` and manages database connection.  \n- **Authentication** (`jwt.ts`): Configures JSON Web Token handling for security.  \n- **API Documentation** (`swagger.ts` and `zod.ts`): Integrates Swagger for API documentation and Zod for schema validation.  \n- **Dependency Injection** (`awilix.ts`): Registers and manages service dependencies using Awilix.  \n- **Error Handling** (`error.ts`): Provides a centralized mechanism for managing application errors.\n\n#### `src/lib`:  \n  This directory serves as an abstraction layer for third-party services and integrations. It is designed to encapsulate interactions with external services such as BullMQ for job processing, Stripe for payment processing, email sending services, file storage providers (e.g. AWS S3, GCP Cloud Storage), and more.  \n  These abstraction layers are registered in the Awilix container and imported by services as needed. Additionally, this folder includes validation schemas using Zod for different modules, as well as utility functions and helpers that support the overall application infrastructure.\n\n#### `src/types`:  \n  Global TypeScript types and declarations used across the project.\n\n#### Project Tree:\n```\n.\n├── commitlint.config.js\n├── docker-compose.yml\n├── Dockerfile\n├── eslint.config.mjs\n├── nodemon.json\n├── package.json\n├── package-lock.json\n├── README.md\n├── src\n│   ├── database\n│   │   ├── prisma\n│   │   │   ├── migrations\n│   │   │   │   └── ...\n│   │   │   ├── prisma.type.ts\n│   │   │   └── schema.prisma\n│   │   └── repositories\n│   │       ├── generate.repository.ts\n│   │       └── ...\n│   ├── lib\n│   │   ├── ...\n│   │   └── validation\n│   │       └── feature\n│   │           ├── index.ts\n│   │           └── feature.schema.ts\n│   ├── modules\n│   │   ├── application.ts\n│   │   └── feature\n│   │       ├── index.ts\n│   │       ├── feature.handler.ts\n│   │       ├── feature.route.ts\n│   │       └── feature.service.ts\n│   ├── plugins\n│   │   ├── awilix.ts\n│   │   ├── cors.ts\n│   │   ├── env.ts\n│   │   ├── error.ts\n│   │   ├── jwt.ts\n│   │   ├── prisma.ts\n│   │   ├── swagger.ts\n│   │   └── zod.ts\n│   ├── types\n│   │   ├── env.type.ts\n│   │   └── index.d.ts\n│   ├── index.ts\n│   └── server.ts\n├── tsconfig.json\n└── tsconfig.tsbuildinfo\n```\n\n## ✨ Inspired by\n- [Fastify example](https://github.com/delvedor/fastify-example) - a brief example of core Fastify features;\n- [Guide to plugins](https://fastify.dev/docs/latest/Guides/Plugins-Guide/) - encapsulation and decorators in Fastify.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flumitech-co%2Flumitech-node-fastify-template","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flumitech-co%2Flumitech-node-fastify-template","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flumitech-co%2Flumitech-node-fastify-template/lists"}