{"id":31844887,"url":"https://github.com/houkasaurusrex/boilerplate-express-ts-server","last_synced_at":"2026-03-01T22:04:16.842Z","repository":{"id":45483684,"uuid":"257262287","full_name":"HoukasaurusRex/boilerplate-express-ts-server","owner":"HoukasaurusRex","description":"A Best Practices™️ Express.js and Typescript server with clustering and socket.io","archived":false,"fork":false,"pushed_at":"2023-03-04T16:56:17.000Z","size":93425,"stargazers_count":4,"open_issues_count":13,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-10-19T17:31:35.880Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://perfect-express-ts-server.herokuapp.com/","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/HoukasaurusRex.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}},"created_at":"2020-04-20T11:39:51.000Z","updated_at":"2025-08-21T20:03:04.000Z","dependencies_parsed_at":"2023-02-13T12:30:44.127Z","dependency_job_id":null,"html_url":"https://github.com/HoukasaurusRex/boilerplate-express-ts-server","commit_stats":null,"previous_names":[],"tags_count":0,"template":true,"template_full_name":null,"purl":"pkg:github/HoukasaurusRex/boilerplate-express-ts-server","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HoukasaurusRex%2Fboilerplate-express-ts-server","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HoukasaurusRex%2Fboilerplate-express-ts-server/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HoukasaurusRex%2Fboilerplate-express-ts-server/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HoukasaurusRex%2Fboilerplate-express-ts-server/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/HoukasaurusRex","download_url":"https://codeload.github.com/HoukasaurusRex/boilerplate-express-ts-server/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HoukasaurusRex%2Fboilerplate-express-ts-server/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29986242,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-01T21:06:37.093Z","status":"ssl_error","status_checked_at":"2026-03-01T21:05:45.052Z","response_time":124,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":[],"created_at":"2025-10-12T07:52:23.336Z","updated_at":"2026-03-01T22:04:16.835Z","avatar_url":"https://github.com/HoukasaurusRex.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Contributors][contributors-shield]][contributors-url]\n[![Language grade: JavaScript][lgtm-shield]][lgtm-url]\n[![FOSSA Status][fossa-shield]][fossa-url]\n[![David Dependencies Status][dependencies-shield]][dependencies-url]\n[![License: MIT][license-shield]][license-url]\n[![LinkedIn][linkedin-shield]][linkedin-url]\n[![Twitter: HoukasaurusRex][twitter-shield]][twitter-url]\n\n# The Perfect Express-TS Server\n\nPutting years of knowledge gained from working with Node/Express in production environments to work for the benefit of all humanity.\n\nThis application template is designed to be extensible, scalable, and highly opinionated.\nIt should be simple to add and remove functionalities based on your use case.\n\n## Overview\n\n```dir\nsrc/\n  config/\n    - configuration files\n  controllers/\n    - routes with provider functions as callback functions\n  providers/\n    - business logic for controller routes\n  services/\n    - common business logic used in the provider functions\n  migrations/\n    - migration files to alter database schemas\n  models/\n    - database models\n  app.ts\n    - load all of the above\n  db.ts\n    - load all models\n  io.ts\n    - load all sockets\n  migrations.ts\n    - loads migrations/ and runs each one in sequence\n  routes.ts\n    - load all routes\n  server.ts\n    - load the app.ts file and listen on a port\ntest/\n  unit/\n    - unit tests\n  integration/\n    - integration tests\n```\n\n## Features\n\n- CORS configuration\n- Multipart form parsing\n- Basic HTTP security\n- GZip compression\n- JSend response standards\n- REST/OpenAPI API standards\n- Error handling\n- PM2 clustering\n- Password hashing with bcrypt\n- SQL Migrations with Umzug\n\n## Express Server\n\nThe extensible and modular REST king of node frameworks. This repo is a highly opinionated guide\nto working with this relatively unopinionated framework that can be a treasure or trap at every turn.\n\n### App.js\n\nThis is the body of every express application.\nIt's removed from the entrypoint at server.js to keep the application definition separated from its invocation.\nThis is the first place where a new project might go wrong, as the app.js file might be a convenient place in the beginning to put **literally everything**,\nit will quickly make a *don't touch* file thousands of lines long that will increase time to debug.\nThat's why it's good to scope the app.js file to mostly import middlewares and routers from elsewhere and export the configured app.\n\n## Socket.io Server\n\nSocket.io is the most recognizable websockets framework for node (and beyond),\nand despite its quirks from being one of the longest living frameworks,\nis still a powerful and extensible ally in removing a lot of the complexity with creating real-time applications.\n\n### IO.js\n\nIn the same way app.js is the instance of an Express application to be imported and run from server.js,\nio.js is an instance of the socket.io server that imports events from sockets.js.\n\n### Sockets\n\nAll socket events are defined in src/controllers/sockets.js and use the providers in the src/providers folder just like the express routes.\nThis can be extracted if the project scales and served from different folders, but this will suffice for most use cases.\n\n## Sequelize ORM\n\nIt's important to work with SQL databases through an ORM.\nIt will help avoid messy mistakes with malicious user inputs and abstract advanced DB connections and querying.\nSequelize in particular is long-standing with tons of support, battle testing, and compatibility with a wide variety of relational databases.\n\n### DB.js\n\nThis is the entrypoint to the Sequelize database connection instance.\nIt should just load your models and export the database instance.\n\n### Model Definitions\n\nModels are defined in src/models in an OOP-style class structure.\nThis plays nicely with intellisense and typescript, but is also a good way to work with models in general as they generally fit the OOP method.\nThis is where you should add any hooks, relations, or prototypes to your models.\n\n## Mocha/Chai Testing\n\nMocha matches Express in extensibility, and can be tough to get started from scratch.\nA good testing strategy is to test each API with a pass/fail scenario with sensible labels to prevent major regressions.\n\n### Integration vs. Unit Testing\n\nIntegration tests include API testing (implicitly testing route, controller, provider, and model) for Express applications and socket events for Socket.IO.\n\nUnit testing can be services and utility functions that are limited to a simple input/output functional design.\n\n## PM2 Clustering\n\nClustering in node can be powerful, but be wary of your use case and the extra complexities of adding verticle scaling to your application.\nIf you need to use stateful sticky websocket sessions and have sensible horizontal scaling, process clustering may not be worth the extra work.\nOtherwise it can be a quick way to squeeze out additional performance to your application.\n\n### PM2 keymetrics keys\n\nFor pm2 keymetrics monitoring on AWS instances, provide the following env vars\nhttps://pm2.keymetrics.io/docs/tutorials/use-pm2-with-aws-elastic-beanstalk/#integrate-pm2-with-keymetrics\n\nKEYMETRICS_PUBLIC = XXXXX\nKEYMETRICS_SECRET = XXXXX\n\n### Vertical Scaling\n\nVertical scaling is not for every production environment, for example using T2 micro instances in AWS are limited to 1 vCPU and would not benefit,\nhowever many environments including T2 medium and above instances or even Heroku are capable of dishing out multiple cores for you to take advantage of.\nIf an application uses a mixture of horizontal and vertical scaling, it can scale exponentially as opposed to linearly.\n\n## Contributing\n\nIf there are any concepts that should be explained in greater detail or if you have any suggestions,\ncontributions are welcome!\n\n[contributors-shield]: https://img.shields.io/github/contributors/HoukasaurusRex/boilerplate-express-ts-server.svg?style=flat-square\n[contributors-url]: https://github.com/HoukasaurusRex/boilerplate-express-ts-server/graphs/contributors\n[hitcount-shield]: https://hits.dwyl.com/HoukasaurusRex/jthoukspace.svg\n[hitcount-url]: https://hits.dwyl.com/HoukasaurusRex/jthoukspace\n[dependencies-shield]: https://david-dm.org/HoukasaurusRex/boilerplate-express-ts-server.svg\n[dependencies-url]: https://david-dm.org/HoukasaurusRex/boilerplate-express-ts-server\n[linkedin-shield]: https://img.shields.io/badge/-LinkedIn-black.svg?style=flat-square\u0026logo=linkedin\u0026colorB=555\n[linkedin-url]: https://www.linkedin.com/in/jt-houk/\n[product-screenshot]: https://source.unsplash.com/600x300/?nature,water\n[product-url]: https://boilerplate-express-ts-server\n[lgtm-shield]: https://img.shields.io/lgtm/grade/javascript/g/HoukasaurusRex/boilerplate-express-ts-server.svg?logo=lgtm\u0026logoWidth=18\u0026style=flat-square\n[lgtm-url]: https://lgtm.com/projects/g/HoukasaurusRex/boilerplate-express-ts-server/context:javascript\n[fossa-shield]: https://app.fossa.com/api/projects/git%2Bgithub.com%2FHoukasaurusRex%2Fboilerplate-express-ts-server.svg?type=shield\u0026style=flat-square\n[fossa-url]: https://app.fossa.com/projects/git%2Bgithub.com%2FHoukasaurusRex%2Fboilerplate-express-ts-server?ref=badge_shield\n[fossa-scan]: https://app.fossa.com/api/projects/git%2Bgithub.com%2FHoukasaurusRex%2Fboilerplate-express-ts-server.svg?type=large\n[license-shield]: https://img.shields.io/badge/License-MIT-blue.svg?style=flat-square\n[license-url]: ./LICENSE\n[twitter-shield]: https://img.shields.io/twitter/follow/HoukasaurusRex.svg?style=social\n[twitter-url]: https://twitter.com/HoukasaurusRex\n[issues-url]: https://github.com/HoukasaurusRex/boilerplate-express-ts-server/issues","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhoukasaurusrex%2Fboilerplate-express-ts-server","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhoukasaurusrex%2Fboilerplate-express-ts-server","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhoukasaurusrex%2Fboilerplate-express-ts-server/lists"}