{"id":48041088,"url":"https://github.com/m99coder/cloud-native-enterprise-nodejs","last_synced_at":"2026-04-04T14:08:01.585Z","repository":{"id":65313067,"uuid":"483759198","full_name":"m99coder/cloud-native-enterprise-nodejs","owner":"m99coder","description":"Cloud-native Enterprise Node.js","archived":false,"fork":false,"pushed_at":"2025-08-25T16:15:50.000Z","size":2925,"stargazers_count":4,"open_issues_count":2,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-08-25T18:13:33.506Z","etag":null,"topics":["eslint","fastify","grafana","jest","loki","observability","pino","prettier","prometheus","promtail","tempo","ts-node-dev","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/m99coder.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,"zenodo":null}},"created_at":"2022-04-20T17:55:16.000Z","updated_at":"2025-08-25T16:12:16.000Z","dependencies_parsed_at":"2024-09-16T09:38:23.061Z","dependency_job_id":"ef0b8364-6621-4d56-8389-5cdd273ab055","html_url":"https://github.com/m99coder/cloud-native-enterprise-nodejs","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/m99coder/cloud-native-enterprise-nodejs","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/m99coder%2Fcloud-native-enterprise-nodejs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/m99coder%2Fcloud-native-enterprise-nodejs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/m99coder%2Fcloud-native-enterprise-nodejs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/m99coder%2Fcloud-native-enterprise-nodejs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/m99coder","download_url":"https://codeload.github.com/m99coder/cloud-native-enterprise-nodejs/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/m99coder%2Fcloud-native-enterprise-nodejs/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31402278,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-04T10:20:44.708Z","status":"ssl_error","status_checked_at":"2026-04-04T10:20:06.846Z","response_time":60,"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":["eslint","fastify","grafana","jest","loki","observability","pino","prettier","prometheus","promtail","tempo","ts-node-dev","typescript"],"created_at":"2026-04-04T14:08:00.806Z","updated_at":"2026-04-04T14:08:01.569Z","avatar_url":"https://github.com/m99coder.png","language":"TypeScript","readme":"# Cloud-native Enterprise Node.js\n\n\u003e [!NOTE]\n\u003e This is the predecessor of [this project](https://github.com/m99coder/cloud-native-enterprise-nodejs-revamped). Hop over and have a look. It comes with TypeScript, ESM, tsdown Rust bundler, and c8 native V8 code coverage beyond other cutting-edge tools and approaches.\n\n[![Build and Test](https://github.com/m99coder/cloud-native-enterprise-nodejs/actions/workflows/build-and-test.yml/badge.svg)](https://github.com/m99coder/cloud-native-enterprise-nodejs/actions/workflows/build-and-test.yml)\n\n## Configuration\n\nSome formatting settings like format on save using the [ESLint plugin](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) for VSCode:\n\n```json\n{\n  \"editor.formatOnSave\": true,\n  \"editor.formatOnPaste\": false,\n  \"editor.defaultFormatter\": \"dbaeumer.vscode-eslint\",\n  \"editor.codeActionsOnSave\": {\n    \"source.fixAll.eslint\": true\n  },\n  \"eslint.validate\": [\n    \"javascript\",\n    \"javascriptreact\",\n    \"typescript\",\n    \"typescriptreact\",\n  ],\n  \"files.insertFinalNewline\": true\n}\n```\n\nTo support [direnv](https://direnv.net/), everything you need to do is to define an `.envrc` that calls `dotenv` as described [here](https://github.com/direnv/direnv/issues/284#issuecomment-315275436).\n\n## Fastify\n\nThe Fastify web framework comes bundled with Pino by default, as described [here](https://github.com/pinojs/pino/blob/master/docs/web.md#fastify). A pretty-printed variant can be achieved by piping stdout to [pino-pretty](https://github.com/pinojs/pino-pretty):\n\n```shell\nnpm i -g pino-pretty\nnpm run dev | pino-pretty\n```\n\nJay Wolfe has some nice blog posts about using Fastify the right way:\n\n- [Setup Your Fastify Server With Logging The Right Way - No More Express](https://jaywolfe.dev/setup-your-fastify-server-with-logging-the-right-way-no-more-express-2/)\n- [Setup A Fastify App with Jest Tests the Right Way](https://jaywolfe.dev/setup-a-fastify-app-with-jest-tests-the-right-way/)\n\n## Testing\n\nTo make use of the coverage report it’s recommended to install the [Jest plugin](https://marketplace.visualstudio.com/items?itemName=Orta.vscode-jest).\n\n```shell\n# run tests\nnpm test\n\n# run tests and generate coverage report\nnpm run test:coverage\nopen coverage/lcov-report/index.html\n```\n\n## Running\n\n```shell\n# clean compile folder\nnpm run clean\n\n# compile TypeScript to JavaScript\nnpm run build\n\n# run application\nnpm start\n\n# run application in development mode with hot-reloading\nnpm run dev\n\n# lint sources\nnpm run lint\n\n# format sources\nnpm run fmt\n```\n\nEnvironment variables\n\n| Variable    | Type     | Default |\n| ----------- | -------- | ------- |\n| `LOG_LEVEL` | `string` | `info`  |\n| `PORT`      | `number` | 4000    |\n\n## Scaling\n\n### Load Balancing\n\n\u003e [HAProxy](http://www.haproxy.org/) is a free and open source software that provides a high availability load balancer and reverse proxy for TCP and HTTP-based applications that spreads requests across multiple servers.\n\n```shell\n# start 3 server instances\nPORT=4001 npm start\nPORT=4002 npm start\nPORT=4003 npm start\n```\n\n```shell\n# install and start HAProxy\nbrew install haproxy\nhaproxy -f ./haproxy/haproxy.cfg\n```\n\n```shell\n# open the stats dashboard\nopen http://localhost:4000/admin/stats\n\n# call the API\ncurl -i http://localhost:4000\n\n# terminate one of the API servers with `kill \u003cpid\u003e`\n# HAProxy detects that the API is down\n# re-start the API server and HAProxy will include it into load-balancing again\n```\n\nBy default a health check is performed on Layer 4 (TCP). If `haproxy.cfg` defines `option httpchk GET /health` for a backend the health check is changing to be on Layer 7 (HTTP), as you can see in the stats dashboard (`LastChk` column).\n\nIn order to use gzip compression, you need to provide the respective header. The HAProxy configuration file defines the compression to be available for content types `application/json` and `text/plain`.\n\n```shell\ncurl -s http://localhost:4000/ -H \"Accept-Encoding: gzip\" | gunzip\n```\n\nHAProxy can also be configured to close connections as soon as a maximum number of connections is reached to avoid back pressure.\n\n### Load Testing\n\nIn order to load test one instance of the application, we stop HAProxy and start the instance without piping to `pino-pretty`.\n\n\u003e [wrk](https://github.com/wg/wrk) is a modern HTTP benchmarking tool capable of generating significant load when run on a single multi-core CPU.\n\n```shell\nbrew install wrk\n```\n\n```shell\n$ wrk -c10 -d60s --latency http://localhost:4001/health\nRunning 1m test @ http://localhost:4001/health\n  2 threads and 10 connections\n  Thread Stats   Avg      Stdev     Max   +/- Stdev\n    Latency   752.68us    0.85ms  33.52ms   93.70%\n    Req/Sec     7.73k     0.94k    9.52k    74.42%\n  Latency Distribution\n     50%  430.00us\n     75%    0.93ms\n     90%    1.32ms\n     99%    3.45ms\n  923474 requests in 1.00m, 108.33MB read\nRequests/sec:  15388.55\nTransfer/sec:      1.81MB\n```\n\n```shell\n$ haproxy -f ./haproxy/passthrough.cfg\n$ wrk -c10 -d60s --latency http://localhost:4000/health\nRunning 1m test @ http://localhost:4000/health\n  2 threads and 10 connections\n  Thread Stats   Avg      Stdev     Max   +/- Stdev\n    Latency     0.90ms    1.54ms  49.85ms   90.55%\n    Req/Sec    10.08k     2.29k   13.40k    66.08%\n  Latency Distribution\n     50%  347.00us\n     75%  689.00us\n     90%    2.33ms\n     99%    6.89ms\n  1203917 requests in 1.00m, 141.22MB read\nRequests/sec:  20062.58\nTransfer/sec:      2.35MB\n```\n\nBased on these numbers the application – run locally on my specific machine – reaches a throughput of ~15,000 requests/s and a TP99 (top percentile 99%) for latency of ~4 ms, when testing only one instance. Using HAProxy with a passthrough configuration reaches a throughput of ~20,000 requests/s and a TP99 for latency is ~7 ms.\n\n## Observability\n\nThe [Three Pillars of observability](https://grafana.com/blog/2019/10/21/whats-next-for-observability/) are metrics, logs, and traces.\n\n- Metrics: [Prometheus](https://grafana.com/oss/prometheus/), [Grafana Mimir](https://grafana.com/oss/mimir/) for multi-tenant, long-term storage for Prometheus\n- Logs: [Grafana Loki](https://grafana.com/oss/loki/)\n- Traces: [Grafana Tempo](https://grafana.com/oss/tempo/)\n\n```shell\n# install plugin to allow applications to ship their logs to Loki\ndocker plugin install grafana/loki-docker-driver:latest --alias loki --grant-all-permissions\n\n# start observability stack\ndocker compose up -d\n\n# stop observability stack\ndocker compose down\n# stop observability stack and remove volumes\ndocker compose down -v\n```\n\nIn [Grafana](http://localhost:3000/explore?orgId=1\u0026left=%5B%22now-30m%22,%22now%22,%22Loki%22,%7B%22expr%22:%22%7Bcontainer_name%3D%5C%22m99coder-loki%5C%22%7D%20%7C%3D%20%5C%22traceID%5C%22%22%7D%5D) we can query for logs from the Loki container that contain a `traceID` using this query:\n\n```promql\n{container_name=\"m99coder-loki\"} |= \"traceID\"\n```\n\nDrop down any log line of the result and click the “Tempo” link to jump directly from logs to traces.\n\n```shell\nnpm i pino-tee -g\nnpm start | pino-tee info ./logs/api.info.log | tee -a ./logs/api.log | pino-pretty\n```\n\nYou can see the application logs in [Grafana](http://localhost:3000/explore?orgId=1\u0026left=%5B%22now-30m%22,%22now%22,%22Loki%22,%7B%22expr%22:%22%7Bjob%3D%5C%22logs-api%5C%22,filename%3D%5C%22%2Fusr%2Fapi%2Fdata%2Fapi.info.log%5C%22%7D%22%7D%5D).\n\n*Note*: So far the log files are not kept in sync between the host and the container, which results in no updates in Grafana.\n\n### Resources\n\n- [Run Grafana Docker image](https://grafana.com/docs/grafana/latest/installation/docker/)\n- [Install Grafana Loki with Docker or Docker Compose](https://grafana.com/docs/loki/latest/installation/docker/)\n- Getting started with Grafana Loki: [Guide](https://grafana.com/docs/loki/latest/getting-started/), [Code](https://github.com/grafana/loki/tree/main/examples/getting-started), [Scraping](https://grafana.com/docs/loki/latest/clients/promtail/scraping/#file-target-discovery)\n- Grafana Tempo: [Documentation](https://grafana.com/docs/tempo/latest/), [Loki example](https://github.com/grafana/tempo/tree/main/example/docker-compose/loki)\n- [A simple Loki setup with Grafana](https://github.com/livingdocsIO/monitoring)\n- [Loki logging in Node.js using Fastify and Pino](https://skaug.dev/node-js-app-with-loki/)\n- [OpenTelemetry – Grafana Demo](https://github.com/connorlindsey/otel-grafana-demo)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fm99coder%2Fcloud-native-enterprise-nodejs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fm99coder%2Fcloud-native-enterprise-nodejs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fm99coder%2Fcloud-native-enterprise-nodejs/lists"}