{"id":13764696,"url":"https://github.com/chocolat-chaud-io/stator","last_synced_at":"2025-07-10T21:13:24.012Z","repository":{"id":39373974,"uuid":"298115871","full_name":"chocolat-chaud-io/stator","owner":"chocolat-chaud-io","description":"Stator, your go-to template for the perfect stack. 😍🙏","archived":false,"fork":false,"pushed_at":"2022-11-29T20:23:37.000Z","size":3861,"stargazers_count":300,"open_issues_count":15,"forks_count":19,"subscribers_count":9,"default_branch":"master","last_synced_at":"2024-11-17T01:32:17.470Z","etag":null,"topics":["boilerplate","demo-application","full","full-stack","fullstack","generator","javascript","monorepo","nestjs","nx","postgres","project","react","reactjs","redux-toolkit","stack","stator","template","typeorm","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/chocolat-chaud-io.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-09-23T23:11:20.000Z","updated_at":"2024-11-10T14:45:38.000Z","dependencies_parsed_at":"2023-01-21T23:00:48.646Z","dependency_job_id":null,"html_url":"https://github.com/chocolat-chaud-io/stator","commit_stats":null,"previous_names":[],"tags_count":32,"template":true,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chocolat-chaud-io%2Fstator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chocolat-chaud-io%2Fstator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chocolat-chaud-io%2Fstator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chocolat-chaud-io%2Fstator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chocolat-chaud-io","download_url":"https://codeload.github.com/chocolat-chaud-io/stator/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253480376,"owners_count":21915246,"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":["boilerplate","demo-application","full","full-stack","fullstack","generator","javascript","monorepo","nestjs","nx","postgres","project","react","reactjs","redux-toolkit","stack","stator","template","typeorm","typescript"],"created_at":"2024-08-03T16:00:26.150Z","updated_at":"2025-05-10T20:31:03.046Z","avatar_url":"https://github.com/chocolat-chaud-io.png","language":"TypeScript","funding_links":[],"categories":["Resources","TypeScript","📦 Legacy \u0026 Inactive Projects"],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003ch1\u003eStator\u003c/h1\u003e\n\u003c/div\u003e\n\u003cdiv align=\"center\"\u003e\n  \u003cstrong\u003eStator, your go-to template for the perfect stack.\u003c/strong\u003e\n\u003c/div\u003e\n\u003c/br\u003e\n\n\u003cdiv align=\"center\"\u003e\n  \u003ca href=\"https://badge.fury.io/gh/chocolat-chaud-io%2Fstator\"\u003e\n    \u003cimg src=\"https://badge.fury.io/gh/chocolat-chaud-io%2Fstator.svg\" alt=\"GitHub version\" /\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://github.com/chocolat-chaud-io/stator/actions\"\u003e\n    \u003cimg src=\"https://github.com/chocolat-chaud-io/stator/workflows/stator%20CI/badge.svg\" alt=\"Github action status\" /\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://codecov.io/gh/chocolat-chaud-io/stator\"\u003e\n    \u003cimg src=\"https://codecov.io/gh/chocolat-chaud-io/stator/branch/master/graph/badge.svg?token=3XN225FUIT\" alt=\"Coverage Status\" /\u003e\n  \u003c/a\u003e\n  \u003ca href=\"http://commitizen.github.io/cz-cli/\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/commitizen-friendly-ff69b4.svg\" alt=\"Commitizen friendly\" /\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://renovatebot.com\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/renovate-enabled-blue.svg\" alt=\"Renovate\" /\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://github.com/semantic-release/semantic-release\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg\" alt=\"semantic-release\" /\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://github.com/nestjs/nest\"\u003e\n    \u003cimg src=\"https://raw.githubusercontent.com/nestjsx/crud/master/img/nest-powered.svg?sanitize=true\" alt=\"Nest Powered\" /\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://github.com/juliandavidmr/awesome-nestjs#resources\"\u003e\n    \u003cimg src=\"https://raw.githubusercontent.com/nestjsx/crud/master/img/awesome-nest.svg?sanitize=true\" alt=\"Awesome Nest\" /\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://opensource.org/licenses/MIT\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/License-MIT-yellow.svg\" alt=\"License: MIT\" /\u003e\n  \u003c/a\u003e\n  \u003ca href=\"http://makeapullrequest.com\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/PRs-welcome-brightgreen.svg\" alt=\"PRs Welcome\" /\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://github.com/chocolat-chaud-io/stator\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/Made%20With-Love-orange.svg\" alt=\"Made With Love\" /\u003e\n  \u003c/a\u003e\n\u003c/div\u003e\n\n\u003c/br\u003e\n\n## 🚀 Quick Start\n\nThe interactive CLI will guide you to easily setup your project.\n\n```\nnpm run get-started\n```\n\n\u003c/br\u003e\n\n## 📋 Table of Contents\n\n- [About the Project](#-about-the-project)\n- [Demo Application](#-demo-application)\n  - [Technical Stack](#technical-stack)\n- [Getting Started](#-getting-started)\n  - [Prerequisites](#prerequisites)\n  - [Copy the template](#copy-the-template)\n  - [Make it yours](#make-it-yours)\n  - [Run the application](#run-the-application)\n  - [Continuous Integration](#continuous-integration)\n  - [Deployment](#deployment)\n    - [Digital Ocean App Platform](#digital-ocean-app-platform)\n    - [Kubernetes](#kubernetes)\n- [Implementation](#%EF%B8%8F-implementation)\n  - [Database](#database)\n    - [Postgres](#postgres)\n    - [Mongo](#mongo-not-recommended)\n    - [Data seeding](#data-seeding)\n  - [Backend](#backend)\n  - [Frontend](#frontend)\n  - [General](#general)\n\n\u003c/br\u003e\n\n## 📚 About the Project\n\nHave you ever started a new project by yourself?\u003cbr/\u003e\nIf so, you probably know that it is tedious to set up all the necessary tools.\u003cbr/\u003e\nJust like you, the part I enjoy the most is coding, not boilerplate.\n\nSay hi to stator, a full-stack [TypeScript](https://github.com/microsoft/TypeScript) template that enforces conventions, handles releases, automates deployments and much more!\n\nIf you want more details about how this idea was implemented, I recommend reading the [series of blog articles](https://yann510.hashnode.dev/creating-the-modern-developer-stack-template-part-1-ckfl56axy02e85ds18pa26a6z) I wrote on the topic.\n\n\u003c/br\u003e\n\n## 🦄 [Demo Application](https://www.stator.dev)\n\nThis template includes a demo **todo application** that serves as an example of sound patterns.\nOf course, you won't be creating a todo application for your project, but you can use this as an example of useful patterns and learn how to use the technologies presented in this project.\n\n![demo application](readme-assets/todo-demo.gif)\n\n### Technical Stack\n\nFor a detailed list of all those technologies, you can read this [blog article](https://yann510.hashnode.dev/stator-a-full-stack-template-releases-deployments-enforced-conventions-ckhmnyhr903us9ms1b20lgi3b).\n\n | Deployment                                                                       | Database                                         | Backend                                                       | Frontend                                                      | Testing                                                                          | Conventions                                                                      |\n | -------------------------------------------------------------------------------- | ------------------------------------------------ | ------------------------------------------------------------- | ------------------------------------------------------------- | -------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- |\n | [DigitalOcean App Platform](https://www.digitalocean.com/products/app-platform/) | [Postgres](https://github.com/postgres/postgres) | [Nest](https://github.com/nestjs/nest)                        | [React](https://github.com/facebook/react)                    | [jest](https://github.com/facebook/jest)                                         | [commitlint](https://github.com/conventional-changelog/commitlint)               |\n | [semantic-release](https://github.com/semantic-release/semantic-release)         | [Mongo](https://github.com/mongodb/mongo)        | [Fastify](https://github.com/fastify/fastify)                 | [React Router](https://github.com/ReactTraining/react-router) | [cypress](https://github.com/cypress-io/cypress)                                 | [eslint](https://github.com/eslint/eslint)                                       |\n | [docker-compose](https://github.com/docker/compose)                              | [TypeORM](https://github.com/typeorm/typeorm)    | [Swagger](https://github.com/nestjs/swagger)                  | [Redux](https://github.com/reduxjs/redux)                     |                                                                                  | [prettier](https://github.com/prettier/prettier)                                 |\n |                                                                                  | [NestJs CRUD](https://github.com/nestjsx/crud)   | [ReDoc](https://github.com/Redocly/redoc)                     | [Redux Toolkit](https://github.com/reduxjs/redux-toolkit)     |                                                                                  |                                                                                  |\n |                                                                                  |                                                  |                                                               | [Material UI](https://github.com/mui-org/material-ui)         |                                                                                  |                                                                                  |\n\n\u003c/br\u003e\n\n## 💥 Getting Started\n\n### Prerequisites\n\n- [Docker Compose](https://docs.docker.com/compose/install/)\n- [node.js](https://nodejs.org/en/download/) v14.x\n\n### Copy the template\n\nThis repository is a repository template, which means you can use the `Use this template` button at the top to create your project based on this.\n\n![use template button](readme-assets/use-template.png)\n\n\\*Note: If you have an existing repository, this will require more work. I would recommend using the `use template button` and migrating your current code to the newly created projects.\n\n### Make it yours\n\nYou will now want to make this project yours by replacing all organization and project naming occurrences with your own names.\nThankfully, we have a script just for that:\n\n```\nnpm run rename-project -- --organization {YOUR_ORGANIZATION_NAME} --project {YOUR_PROJECT_NAME}\n```\n\n\\*Note: I highly recommend that the project name is the same as your git repository.\n\nOn completion, you will see the following message:\n\n![project appropriation success](readme-assets/project-appropriation-success.png)\n\n### Run the application\n\nFirst, install the dependencies:\n\n```\nnpm i\n```\n\nThen, run the whole stack:\n\n```\nnpm run postgres\n```\n\n```\nnpm start api\n```\n\n```\nnpm start webapp\n```\n\nFinally, why not test it:\n\n```\nnpm test api \u0026\u0026 npm run e2e webapp-e2e\n```\n\nFor a full list of available commands, consult the `package.json`.\n\n### Continuous Integration\n\nThis templates integrates Github Actions for its Continuous Integration. The existing workflows are under `.github/workflows`. \nCurrently, the CI will ensure all your apps work properly, by building and testing. \nFor your pull requests, it will create a review application which will basically host your whole stack on a VM.\nOnce everything is ready a new comment will be added to your pull request with the deployment URL.\nWhen the PR is closed, your review app will be destroyed as it's purpose will have been served. \nIt's sacrifice will be for the greater good and also your wallet.\nTo have the CI working, you must:\n\n1. (Optional) If you want review apps to work, you should follow the instruction provided by the `get-started` CLI.\n2. (Optional) Link your repository with [Codecov](https://github.com/apps/codecov) by inserting your `CODECOV_TOKEN` in github secrets.\n3. (Optional) Insert your [Nx Cloud](https://nx.app/) access token in github secrets under `NX_CLOUD_TOKEN`. This enables for caching and faster build times.\n\n### Deployment\n\nThe application can be deployed in two different ways, depending on your objectives.\n\n#### Digital Ocean App Platform\n\nFor a simple and fast deployment, the new [App Platform](https://www.digitalocean.com/docs/app-platform/) from Digital Ocean makes it easy to work with monorepos. For our todo app, the config file lies under `.do/app.yaml`. There, you can change the configuration of the different apps being deployed. [The spec can be found here.](https://www.digitalocean.com/docs/app-platform/references/app-specification-reference/)\n\nTo deploy this full stack application yourself, follow the steps below:\n\n1. Create an account on [Digital Ocean Cloud](https://m.do.co/c/67f72eccb557) (this is a sponsored link) and enable Github access\n1. Install [doctl CLI](https://www.digitalocean.com/docs/apis-clis/doctl/how-to/install/)\n1. Run `doctl apps create --spec .do/app.yaml`\n1. View the build, logs, and deployment url [here](https://cloud.digitalocean.com/apps)\n\nOnce done, your app will be hooked to master branch commits as defined in the spec. Therefore, on merge, the application will update. To update the spec of the application, first get the application id with `doctl apps list`, then simply run `doctl apps update \u003capp id\u003e --spec .do/app.yaml`.\n\n\u003c/br\u003e\n\n## ⚙️ Implementation\n\n### Database\n\n#### Postgres\n\nThere are 2 databases available, postgres and mongo.\nTo ensure your developers don't get into any trouble while installing those, they are already pre-configured with `docker-compose.yml` files.\n\n**By default, the project uses postgres.**\nIf this is what you want, you're good to go; everything will work out of the box.\n\n#### Migrations\n\nBy default, the automatic synchronization is activated between your models and the database.\nThis means that making changes on your models will be automatically reflected on your database schemas.\nIf you would like to control your migrations manually, you can do so by setting `synchronize` to false in `orm-config.ts` file. \n\nGenerate migration from your modified schemas:\n\n```\nnpm run typeorm -- migration:generate -n {MIGRATION_NAME}\n```\nThis will check the difference between models for your defined entities and your database schemas. \nIf it finds changes, it will generate the appropriate migration scripts.\n\nRun all pending migrations:\n\n```\nnpm run typeorm -- migration:run\n```\n\nTo get all the information on migrations, consult [typeorm documentation](https://github.com/typeorm/typeorm/blob/master/docs/migrations.md).\n\n#### Mongo [NOT RECOMMENDED]\n\nIf you would like to use mongodb, even though it is absolutely not recommended because it currently doesn't work well with [typeorm](https://github.com/typeorm/typeorm), you can still do that by updating the connection info under `./apps/api/src/config/configuration.ts`.\nYou simply need to replace `type: \"postgres\"` with `type: \"mongo\"`.\nMake sure you run the mongo container using the command: `npm run mongo`.\n\n#### Data seeding\n\nIf you want your database to be pre-populated with that, it is very easy to do so.\nFor postgres add your `sql` statements to `apps/database/postgres/init.sql` file.\nFor mongo add your mongo statements to `apps/database/mongo/mongo-entrypoint/seed-data.js` file.\n\n### Backend\n\nWe are using cutting edge technologies to ensure that you get the best development experience one could hope for.\nTo communicate with the database, we make use of the great [typeorm](https://github.com/typeorm/typeorm).\nWe use the code-first approach, which means defining your models will also represent your tables in your database.\nHere is an example:\n\n```typescript\nimport { Column, Entity } from \"typeorm\"\nimport { RootEntity } from \"./root.entity\"\nimport { MinLength } from \"class-validator\"\n\n@Entity()\nexport class Todo extends RootEntity {\n  @Column()\n  @MinLength(5, { always: true })\n  text: string\n}\n```\n\nTo serve your API requests, we make use of [nest](https://github.com/nestjs/nest) alongside with [fastify](https://github.com/fastify/fastify) to ensure blazing fast [performance](https://github.com/fastify/fastify#benchmarks).\n\nTo reduce the boilerplate commonly found around creating a new entity, we are using the [nestjsx/crud](https://github.com/nestjsx/crud) plugin that will generate all necessary routes for CRUD operations.\n\nHere is an example from our todo app:\n\n```typescript\nimport { Controller } from \"@nestjs/common\"\nimport { Crud, CrudController } from \"@nestjsx/crud\"\nimport { Todo } from \"@stator/models\"\n\nimport { TodosService } from \"./todos.service\"\n\n@Crud({ model: { type: Todo } })\n@Controller(\"todos\")\nexport class TodosController implements CrudController\u003cTodo\u003e {\n  constructor(public service: TodosService) {}\n}\n```\n\nOf course, you're probably wondering if this actually works.\nTo convince you, we have implemented integration tests that perform real requests using [supertest](https://github.com/visionmedia/supertest).\n\n**Can I view the generated endpoints?** Well, of course, you can!\n\nWe now have generated [swagger documentation](https://github.com/fastify/fastify-swagger) that is viewable with the beautiful [redoc](https://github.com/Redocly/redoc).\n\nOnce you navigate to [localhost:3333](http://localhost:3333), you will see this:\n\n![redoc](readme-assets/redoc.png)\n\n### Frontend\n\nFor our webapp, we're using the very popular [react](https://github.com/facebook/react) alongside [redux-toolkit](https://github.com/reduxjs/redux-toolkit) and [react-router](https://github.com/ReactTraining/react-router).\nWe highly recommend that you use [function components](https://reactjs.org/docs/components-and-props.html) as demonstrated in the example.\n\nTo further reduce the boilerplate necessary you can generate hooks based on your API swagger by running `npm run generate-api-redux`.\nWhen you add new entities to your API, you should also add them in the output file property of the `tools/generators/open-api-config.ts` file.\nIf you would like to avoid this, you can generate a single file by removing both properties [`outputFiles`, `filterEndpoints`]\n\nThis script will generate the required [RTK Query](https://redux-toolkit.js.org/rtk-query/overview) code and caching keys so your data remains up to date while performing CRUD operations.\n\nFor a complete example of CRUD operations, consult the `apps/webapp/src/pages/todos-page.tsx` file.\n\nIn our example, we are using [material-ui](https://github.com/mui-org/material-ui), but you could replace that with any other framework.\n\nWe also use [axios](https://github.com/axios/axios) to simplify our requests handling as it works very well with TypeScript.\n\n### General\n\nWe strongly believe that typing helps create a more robust program; thus, we use [TypeScript](https://github.com/microsoft/TypeScript).\n\nTo facilitate and optimize the usage of the monorepo, we make use of [NX](https://github.com/nrwl/nx).\n\n[eslint](https://github.com/eslint/eslint) enforces excellent standards, and [prettier](https://github.com/prettier/prettier) helps you apply them.\n\nCommit messages must abide to those [guidelines](https://www.conventionalcommits.org/en/v1.0.0/). If you need help following them, simply run `npm run commit` and you will be prompted with an interactive menu.\n\nFile and directory names are enforced by the custom-made `enforce-file-folder-naming-convention.ts`.\n\nBranch names are enforced before you even commit to ensure everyone adopts the same standard: `{issue-number}-{branch-work-title-kebab-case}`.\n\nFor end-to-end testing, we use the notorious [cypress](https://github.com/cypress-io/cypress).\n\nWe also have a pre-built CI toolkit for you that will build and run the tests.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchocolat-chaud-io%2Fstator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchocolat-chaud-io%2Fstator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchocolat-chaud-io%2Fstator/lists"}