JavaScript → TypeScript → Node.js → NestJS
Backend Node.js Roadmap
This is the path I am following, from top to bottom, in three phases and with projects from the industrial sector. The project is the common thread: each stage teaches what the next project needs, and it only ends when its exit criterion is met, not when its topics are checked. Click a topic to see what to study and the circle to mark it as done; your progress is saved only in this browser.
Phase 1 · Relearning to program
From zero to P3. In this phase AI writes no code: turn off autocomplete and use the chat only to explain concepts, never to solve the exercise.
Phase 2 · Employable backend
From P4 to P6, all live, tested and with CI. AI may review what you wrote and explain errors, but it does not write what you could not write yourself. From P5 on, write the requirements before reading the list.
Milestone
From here on, start applying for junior roles, without ever stopping your studies
Phase 3 · Mid-level depth
While you apply. From P7 to P9, with applied AI, architecture and system design, up to the final portfolio project.
Grouped by priority. Mark the ones you have read.
Paid · high priority
Grokking Algorithms
PaidNode.js Design Patterns
PaidDesigning Data-Intensive Applications
PaidUnderstanding Distributed Systems
PaidHead First Design Patterns
PaidThe Pragmatic Programmer
Paid
Paid · medium priority
Clean Code
PaidRefactoring, 2nd ed.
PaidEffective TypeScript
PaidUnit Testing Principles, Practices, and Patterns
PaidSQL Antipatterns
PaidSystem Design Interview, vol. 1
PaidFundamentals of Software Architecture
PaidClean Architecture
PaidLearning Domain-Driven Design
PaidRelease It!
PaidEnterprise Integration Patterns
PaidAI Engineering
Paid
Paid · low priority (later)
Computer Networking: A Top-Down Approach
PaidA Philosophy of Software Design
PaidSystem Design Interview, vol. 2
PaidKafka: The Definitive Guide
PaidObservability Engineering
PaidBuilding Microservices
PaidAPI Design Patterns
PaidA Common-Sense Guide to Data Structures and Algorithms
PaidDatabase Internals
PaidSoftware Architecture: The Hard Parts
PaidWorking Effectively with Legacy Code
Paid
Free
MDN HTTP guide
FreePro Git
FreeEloquent JavaScript
FreeYou Don't Know JS Yet
FreeOperating Systems: Three Easy Pieces
FreeTypeScript Handbook
FreeNode.js documentation
FreeUse The Index, Luke
FreePostgreSQL documentation
FreeStripe article on idempotent APIs
FreeMQTT Essentials (HiveMQ)
FreeMongoDB University
FreeRedis University
FreeRabbitMQ tutorials
FreeOWASP Top 10 (geral, API e LLM)
FreeOpenTelemetry documentation
FreeNestJS documentation
FreeAnthropic and OpenAI documentation
FreeGoogle code review guide
Free
All from the industrial sector and chained: each one feeds the next. Projects P7 and P8 use AI, and P9 brings the previous ones together. From P5 on, you write the requirements before reading the list.
P1OEE calculator (CLI)
Goal
Read a CSV of production shifts and calculate each machine's availability, performance, quality and OEE, straight in the terminal.
Minimum requirements
- Read a CSV file passed as an argument, with columns like machine, shift, planned time, downtime, ideal cycle, parts produced and good parts.
- Calculate availability, performance, quality and OEE (the product of the three) for each row.
- Group by machine and show a readable table in the terminal.
- Warn with a clear message when a CSV row is invalid, without ending the program.
- Separate reading the file from the calculations, in small, pure functions.
- Written without AI, versioned with Git from the first commit and published on GitHub.
Extra challenges
- Filter by period or shift with command-line arguments.
- Generate a ranking of the machines from best to worst OEE.
- Export the result as JSON or CSV.
- Highlight the machines below a configurable minimum OEE.
- Write tests for the calculations, even before learning a testing framework.
Stages it practices
P2Sensor simulator
Goal
Generate temperature, vibration and RPM readings from several machines, with random failures, in TypeScript. It feeds the next projects and also receives the conversion of P1 to TypeScript.
Minimum requirements
- Simulate at least 5 machines, each one with temperature, vibration and RPM readings at regular intervals.
- Model machines and readings with types and interfaces, in strict mode.
- Inject random failures (for example, a temperature spike or abnormal vibration) with a configurable probability.
- Run several machines concurrently, without blocking the program.
- Convert P1 (the OEE calculator) to TypeScript.
Extra challenges
- Generate readings with realistic noise, instead of fully random values.
- Simulate production stops and restarts, to feed the OEE calculation.
- Allow configuring the machines from a file, validated with Zod.
- Accept a seed to reproduce the same sequence of readings.
Stages it practices
P3Telemetry collector in plain Node
Goal
A server using the http module, with no framework, that receives the readings from P2 and writes them to a file. It also processes large files with Streams and fires alerts with EventEmitter.
Minimum requirements
- Receive readings by POST and write them to a file, using only the http module.
- Process a large file of readings with Streams, without loading it whole into memory.
- Emit an alert event with EventEmitter when a reading passes a limit.
- Reproduce a race condition in concurrent writes to the file and fix it, explaining the cause.
- Configure the port and the file path with environment variables.
- ESLint and Prettier configured, commits following Conventional Commits and a README explaining how to run it and the decisions made.
Extra challenges
- Use worker threads to process the large files without freezing the server.
- Apply backpressure explicitly and measure the effect.
- Rotate the output file by size or by day.
- Compare memory consumption with and without Streams.
- Profile the collector under load and document the bottleneck found.
Stages it practices
P4Production orders and batch traceability API
Goal
A REST API with PostgreSQL to manage production orders and trace batches of raw material. It must answer: which raw material batches went into this product?
Minimum requirements
- Model production orders, products, raw material batches and the link between them in PostgreSQL, with migrations.
- Authentication with roles: the operator records, the supervisor approves and queries everything.
- Idempotent production logging with the Idempotency-Key header.
- Optimistic locking, with a version column, on orders updated at the same time.
- Transactions so that a production entry and the material deduction happen together or not at all.
- A route that answers which raw material batches went into a product.
- Integration tests with a real database and Swagger documentation.
- Reviewed against the OWASP API Security Top 10: parameterized queries, passwords with argon2 or bcrypt and no secrets in the code.
- PostgreSQL and the API running with docker-compose, CI on GitHub Actions running lint and tests, and a deploy with a public URL.
- Dates always stored in UTC and displayed in the factory's time zone.
- ESLint and Prettier configured, commits following Conventional Commits and a README explaining how to run it and the decisions made.
Extra challenges
- Traceability in the opposite direction: given a raw material batch, in which products it was used.
- Pagination and filters on the listings.
- Rate limiting on the write routes.
- Load tests to prove that idempotency works with repeated requests.
- A webhook that notifies an external system when a production order is completed.
Stages it practices
P5Real-time machine monitoring
Goal
Receive readings from the simulator over MQTT, pass them through a queue, store them in a time-series database and show the machines' status on a real-time dashboard.
Minimum requirements
Before reading the requirements below, write your own from the goal. Then compare: what your list missed is what you cannot yet see on your own.
- The ingestion service and the dashboard backend are built in NestJS.
- The simulator (P2) publishes the readings over MQTT.
- Ingestion goes through a queue (RabbitMQ or Kafka).
- Consumers are idempotent: processing the same reading twice does not duplicate the data.
- Messages that fail repeatedly go to a dead letter queue.
- The data is written to TimescaleDB.
- A dashboard shows the machines' status, updated over WebSocket.
- ESLint and Prettier configured, commits following Conventional Commits and a README explaining how to run it and the decisions made.
Extra challenges
- Visual alerts when a machine leaves the normal range.
- Real-time OEE calculation per machine.
- Continuous aggregates in TimescaleDB for historical charts.
- Compare RabbitMQ and Kafka in the same flow and note the differences.
Stages it practices
P6Raw material inventory control
Goal
Several production orders reserve the same material at the same time. You reproduce the race condition, fix it in three ways and compare the results.
Minimum requirements
Before reading the requirements below, write your own from the goal. Then compare: what your list missed is what you cannot yet see on your own.
- Built in NestJS.
- Reserve raw material for production orders without letting the stock go negative.
- Reproduce the race condition with a load test in k6 or autocannon.
- Fix it in three ways: pessimistic lock, optimistic lock and a distributed lock with Redis.
- Compare the three in a report: correctness, throughput, latency and complexity.
- Cache-aside with Redis on balance queries.
- Transactional Outbox to publish the 'low stock' event without losing or duplicating it.
- ESLint and Prettier configured, commits following Conventional Commits and a README explaining how to run it and the decisions made.
Extra challenges
- Use fencing tokens in the distributed lock and show the problem they solve.
- Simulate a Redis failure in the middle of the operation and observe the behavior.
- Protect the Redis call with a timeout, retry with backoff and a circuit breaker.
- Reproduce and handle a cache stampede.
Stages it practices
P7Maintenance assistant with RAGAI
Goal
Index machine manuals and the maintenance order history with embeddings in pgvector. The technician describes the symptom and gets checking steps, citing the manual passage used.
Minimum requirements
Before reading the requirements below, write your own from the goal. Then compare: what your list missed is what you cannot yet see on your own.
- Split the manuals into passages and generate embeddings, storing everything in pgvector.
- Also index the maintenance order history.
- Receive a symptom as text (for example, 'press 3 with high vibration') and fetch the most relevant passages.
- Generate checking steps with an LLM, based only on the retrieved passages.
- Cite the manual passage used in each answer.
- Include an evaluation of the answers' quality, with a set of test questions.
- ESLint and Prettier configured, commits following Conventional Commits and a README explaining how to run it and the decisions made.
Extra challenges
- Answer 'I don't know' when no passage is relevant enough.
- Combine vector search and keyword search.
- Compare passage sizes and embedding models using the evaluation.
- Protect against prompt injection inside the indexed documents.
Stages it practices
P8Downtime classification and shift reportAI
Goal
An LLM classifies the reason for a stop from the operator's free text and generates the shift report, with OEE and the main occurrences.
Minimum requirements
Before reading the requirements below, write your own from the goal. Then compare: what your list missed is what you cannot yet see on your own.
- Classify the operator's free text into downtime categories, with JSON output validated by Zod.
- Handle invalid model output, with a retry or a clear error.
- Generate a shift report with OEE and the main occurrences.
- Use tool calling to query real data from the API, and do not let the model make up numbers.
- Run the report generation in the background, through a queue.
- A shift report that respects the time zone and the factory's shift change times.
- ESLint and Prettier configured, commits following Conventional Commits and a README explaining how to run it and the decisions made.
Extra challenges
- Measure the classification accuracy against examples labeled by hand.
- Record the cost and latency of each call.
- Send the report by e-mail or message at the end of the shift.
- Suggest a new category when the text fits none.
Stages it practices
P9Mini-MES in NestJS (final portfolio)
Goal
Bring together P4, P5, P6, P7 and P8 in a modular monolith with hexagonal architecture and DDD. It is the project that shows everything you learned.
Minimum requirements
Before reading the requirements below, write your own from the goal. Then compare: what your list missed is what you cannot yet see on your own.
- A modular monolith in NestJS, with modules for production, inventory, monitoring, maintenance and reports.
- Hexagonal architecture and DDD modeling.
- Communication between modules through events.
- Observability with OpenTelemetry: logs, metrics and traces.
- Docker, CI on GitHub Actions and a working deploy.
- A system design document and ADRs recording the decisions.
- A README with the decisions, the architecture diagram and instructions to run it.
- ESLint and Prettier configured, commits following Conventional Commits and a README explaining how to run it and the decisions made.
Extra challenges
- A Grafana dashboard with the business and infrastructure metrics.
- A load test with a report of the bottlenecks found.
- Extract one module into a separate service and document what changed.
- Record a short video (up to 5 minutes) presenting the project and the architecture decisions, to use in job applications.
Stages it practices