{"id":15026140,"url":"https://github.com/ishtms/learn-nodejs-hard-way","last_synced_at":"2025-05-15T15:06:20.083Z","repository":{"id":187898330,"uuid":"677773874","full_name":"ishtms/learn-nodejs-hard-way","owner":"ishtms","description":"Learn NodeJS and master the art of server-side programming by creating a backend framework with 0 dependencies.","archived":false,"fork":false,"pushed_at":"2024-10-09T17:23:06.000Z","size":15785,"stargazers_count":1490,"open_issues_count":7,"forks_count":86,"subscribers_count":29,"default_branch":"master","last_synced_at":"2025-05-10T08:08:57.812Z","etag":null,"topics":["api","backend","backend-development","book","coding","javascript","learn","learn-to-code","learning","learning-by-doing","learning-exercise","node","nodejs","programming","programming-fundamentals","server","training-materials"],"latest_commit_sha":null,"homepage":"https://github.com/ishtms/learn-nodejs-hard-way","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ishtms.png","metadata":{"files":{"readme":"Readme.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.txt","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-08-12T15:40:42.000Z","updated_at":"2025-05-07T23:42:44.000Z","dependencies_parsed_at":"2023-11-17T03:29:18.184Z","dependency_job_id":"2098c685-523e-4ac6-af4a-a23d91e46e3c","html_url":"https://github.com/ishtms/learn-nodejs-hard-way","commit_stats":null,"previous_names":["ishtms/learn-nodejs-hard-way"],"tags_count":26,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ishtms%2Flearn-nodejs-hard-way","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ishtms%2Flearn-nodejs-hard-way/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ishtms%2Flearn-nodejs-hard-way/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ishtms%2Flearn-nodejs-hard-way/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ishtms","download_url":"https://codeload.github.com/ishtms/learn-nodejs-hard-way/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254364270,"owners_count":22058878,"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":["api","backend","backend-development","book","coding","javascript","learn","learn-to-code","learning","learning-by-doing","learning-exercise","node","nodejs","programming","programming-fundamentals","server","training-materials"],"created_at":"2024-09-24T20:03:52.360Z","updated_at":"2025-05-15T15:06:20.057Z","avatar_url":"https://github.com/ishtms.png","language":"JavaScript","readme":"# Learn Node.js by building a backend framework - [Velocy](https://github.com/ishtms/velocy)\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"./assets/imgs/cover.jpg\" alt=\"Learn nodejs the hard way\" width=\"500\"\u003e\n\u003c/p\u003e\n\nYou can access the current version of the book in the [chapters directory](/chapters) or in PDF format (both Light and Dark modes are available) by [clicking here](https://github.com/ishtms/learn-nodejs-hard-way/releases). Note that this version includes the current release of the content, and is not the final version.\n\n\u003e This book is still in a very early stage. It contains an insignificant portion of the total content that the book is supposed to cover. There’s going to be 0 dependencies for our [backend framework](https://github.com/ishtms/velocy), as well as our [logging library](https://github.com/ishtms/logtar). Everything will be done using vanilla Node.js, the hard-way (the best way to learn).\n\n---\n\n## Note\n\nIf you're not familiar with javascript, you may also check out my other repository - [Learn Javascript - The Easy Way](https://github.com/ishtms/learn-javascript-easy-way) that takes you on a deep and a fun journey into Javascript - from the very basics to the advanced concepts that you'd ever need, without diving into too much theory. Only practical code examples.\n\n---\n\nTo master a new concept, it's often best to begin from the ground up. This isn't just another Node.js guide; it's a comprehensive, code-along experience aimed at building a real world product that may be used by thousands of developers. The product that we're going to build will be a backend framework, that too from scratch.\n\nYou won't just learn how Node.js works, but also why it operates in a particular way. The guide also includes discussions on relevant data structures and design patterns.\n\nThe book also includes a wide range of exercises specifically created to challenge you, that may require commitment and consistent effort on your part. The first exercises start from [chapter 7](/chapters/ch06.5-ex-implementing-a-trie.md)\n\nThis guide goes beyond the basics. We're focused on delivering a modular, optimized backend framework that is close to being production-ready. Topics like performance optimization, security measures, and various testing approaches will be covered to ensure the framework is both reliable and extendable.\n\nI highly recommend actively coding alongside this guide, rather than just reading through it, for a full understanding of Node.js and its more intricate aspects.\n\nThe repo for our backend framework- [Velocy](https://github.com/ishtms/velocy). (W.I.P)\n\n[![Read Next](/assets/imgs/next.png)](/chapters/ch01.0-what-is-a-web-server-anyway.md)\n\n# Table of contents\n\n- [(Optional) Node.js is way faster than you think](chapters/ch00-nodejs-faster-than-you-think.md#-optional-node-js-is-way-faster-than-you-think)\n  - [Contenders for the test](chapters/ch00-nodejs-faster-than-you-think.md#contenders-for-the-test)\n    - [Elysia - Bun](chapters/ch00-nodejs-faster-than-you-think.md#elysia-bun)\n    - [Axum - Rust](chapters/ch00-nodejs-faster-than-you-think.md#axum-rust)\n    - [Express - Node.js](chapters/ch00-nodejs-faster-than-you-think.md#express-node-js)\n    - [Velocy - Node.js](chapters/ch00-nodejs-faster-than-you-think.md#velocy-node-js)\n  - [The benchmark](chapters/ch00-nodejs-faster-than-you-think.md#the-benchmark)\n  - [Source code](chapters/ch00-nodejs-faster-than-you-think.md#source-code)\n    - [Elysia - Bun](chapters/ch00-nodejs-faster-than-you-think.md#elysia-bun)\n    - [Axum - Rust](chapters/ch00-nodejs-faster-than-you-think.md#axum-rust)\n    - [Express - Node.js](chapters/ch00-nodejs-faster-than-you-think.md#express-node-js)\n    - [Velocy - Node.js](chapters/ch00-nodejs-faster-than-you-think.md#velocy-node-js)\n  - [Results - Typical benchmark](chapters/ch00-nodejs-faster-than-you-think.md#results-typical-benchmark)\n    - [Result: Elysia - Bun/Zig (149,047 req/s)](chapters/ch00-nodejs-faster-than-you-think.md#result-elysia-bun-zig-149-047-req-s-)\n    - [Result: Axum - Rust (208,938 req/s)](chapters/ch00-nodejs-faster-than-you-think.md#result-axum-rust-208-938-req-s-)\n    - [Result: Express - Node.js (28,923 req/s)](chapters/ch00-nodejs-faster-than-you-think.md#result-express-node-js-28-923-req-s-)\n  - [Result: Velocy - Node.js (83,689)](chapters/ch00-nodejs-faster-than-you-think.md#result-velocy-node-js-83-689-)\n  - [Graphs](chapters/ch00-nodejs-faster-than-you-think.md#graphs)\n    - [Latency](chapters/ch00-nodejs-faster-than-you-think.md#latency)\n    - [Requests/sec](chapters/ch00-nodejs-faster-than-you-think.md#requests-sec)\n    - [Idle memory](chapters/ch00-nodejs-faster-than-you-think.md#idle-memory)\n    - [Memory under constant load](chapters/ch00-nodejs-faster-than-you-think.md#memory-under-constant-load)\n    - [Verdict - Typical benchmark](chapters/ch00-nodejs-faster-than-you-think.md#verdict-typical-benchmark)\n  - [The real benchmark](chapters/ch00-nodejs-faster-than-you-think.md#the-real-benchmark)\n    - [Updating our code](chapters/ch00-nodejs-faster-than-you-think.md#updating-our-code)\n    - [Elysia](chapters/ch00-nodejs-faster-than-you-think.md#elysia)\n    - [Express](chapters/ch00-nodejs-faster-than-you-think.md#express)\n  - [Velocy](chapters/ch00-nodejs-faster-than-you-think.md#velocy)\n  - [Results - A real-world use-case](chapters/ch00-nodejs-faster-than-you-think.md#results-a-real-world-use-case)\n    - [Result: Express - Node (50,275 req/sec)](chapters/ch00-nodejs-faster-than-you-think.md#result-express-node-50-275-req-sec-)\n    - [Result: Velocy - Node (138,956 req/sec)](chapters/ch00-nodejs-faster-than-you-think.md#result-velocy-node-138-956-req-sec-)\n    - [Latency](chapters/ch00-nodejs-faster-than-you-think.md#latency)\n    - [Latency without `max latency` bar](chapters/ch00-nodejs-faster-than-you-think.md#latency-without-max-latency-bar)\n    - [Requests/sec](chapters/ch00-nodejs-faster-than-you-think.md#requests-sec)\n    - [Idle memory](chapters/ch00-nodejs-faster-than-you-think.md#idle-memory)\n    - [Memory under constant load](chapters/ch00-nodejs-faster-than-you-think.md#memory-under-constant-load)\n  - [Final Verdict](chapters/ch00-nodejs-faster-than-you-think.md#final-verdict)\n- [What the heck is a web server any way?](chapters/ch01.0-what-is-a-web-server-anyway.md#what-the-heck-is-a-web-server-any-way-)\n  - [Parts of a Web Server:](chapters/ch01.0-what-is-a-web-server-anyway.md#parts-of-a-web-server-)\n    - [Navigating the World of Protocols: A Quick Overview](chapters/ch01.0-what-is-a-web-server-anyway.md#navigating-the-world-of-protocols-a-quick-overview)\n    - [The Relationship Between HTTP and TCP: Ensuring Reliable Web Communication](chapters/ch01.0-what-is-a-web-server-anyway.md#the-relationship-between-http-and-tcp-ensuring-reliable-web-communication)\n    - [1. Data Integrity and Order](chapters/ch01.0-what-is-a-web-server-anyway.md#1-data-integrity-and-order)\n    - [2. Acknowledgment Mechanism](chapters/ch01.0-what-is-a-web-server-anyway.md#2-acknowledgment-mechanism)\n    - [3. Complex Interactions](chapters/ch01.0-what-is-a-web-server-anyway.md#3-complex-interactions)\n    - [4. Transmission Overhead](chapters/ch01.0-what-is-a-web-server-anyway.md#4-transmission-overhead)\n  - [Asking and Getting: How Web Servers Respond to Your Requests](chapters/ch01.0-what-is-a-web-server-anyway.md#asking-and-getting-how-web-servers-respond-to-your-requests)\n    - [The Request:](chapters/ch01.0-what-is-a-web-server-anyway.md#the-request-)\n    - [The Response:](chapters/ch01.0-what-is-a-web-server-anyway.md#the-response-)\n- [Your first `node.js` program](chapters/ch02.0-your-first-nodejs-program.md#your-first-node-js-program)\n  - [What exactly is node or nodejs?](chapters/ch02.0-your-first-nodejs-program.md#what-exactly-is-node-or-nodejs-)\n  - [Your first node.js program](chapters/ch02.0-your-first-nodejs-program.md#your-first-node-js-program)\n    - [How does `console.log()` work in Node.js?](chapters/ch02.0-your-first-nodejs-program.md#how-does-console-log-work-in-node-js-)\n    - [The **`process` Object**:](chapters/ch02.0-your-first-nodejs-program.md#the-process-object-)\n    - [The `stdout` **property of the `process` object**:](chapters/ch02.0-your-first-nodejs-program.md#the-stdout-property-of-the-process-object-)\n- [Working with files](chapters/ch03.0-working-with-files.md#working-with-files)\n    - [What will the logging library do](chapters/ch03.0-working-with-files.md#what-will-the-logging-library-do)\n    - [How do you work with files anyway?](chapters/ch03.0-working-with-files.md#how-do-you-work-with-files-anyway-)\n    - [Let’s get back to `files`](chapters/ch03.0-working-with-files.md#let-s-get-back-to-files-)\n    - [A little more about file descriptors](chapters/ch03.0-working-with-files.md#a-little-more-about-file-descriptors)\n    - [Creating our first file](chapters/ch03.0-working-with-files.md#creating-our-first-file)\n    - [`path` argument](chapters/ch03.0-working-with-files.md#-path-argument)\n    - [`flag` argument](chapters/ch03.0-working-with-files.md#-flag-argument)\n    - [`mode` argument](chapters/ch03.0-working-with-files.md#-mode-argument)\n  - [Reading from a file](chapters/ch03.0-working-with-files.md#reading-from-a-file)\n  - [A small primer on `for..of` and `for await..of` in javascript](chapters/ch03.0-working-with-files.md#a-small-primer-on-for-of-and-for-await-of-in-javascript)\n    - [`for..of`](chapters/ch03.0-working-with-files.md#-for-of-)\n    - [`for await..of`](chapters/ch03.0-working-with-files.md#-for-await-of-)\n  - [Reading the `json` file](chapters/ch03.0-working-with-files.md#reading-the-json-file)\n  - [Buffers](chapters/ch03.0-working-with-files.md#buffers)\n    - [Parsing the `json` file](chapters/ch03.0-working-with-files.md#parsing-the-json-file)\n- [`logtar` our own logging library](chapters/ch04.0-logtar-our-logging-library.md#-logtar-our-own-logging-library)\n  - [Initializing a new project](chapters/ch04.0-logtar-our-logging-library.md#initializing-a-new-project)\n  - [A little about `SemVer`](chapters/ch04.0-logtar-our-logging-library.md#a-little-about-semver-)\n  - [Creating a `LogLevel` class](chapters/ch04.0-logtar-our-logging-library.md#creating-a-loglevel-class)\n  - [The `Logger` class](chapters/ch04.0-logtar-our-logging-library.md#the-logger-class)\n    - [Encapsulation with `private` fields](chapters/ch04.0-logtar-our-logging-library.md#encapsulation-with-private-fields)\n  - [The `LogConfig` class](chapters/ch04.0-logtar-our-logging-library.md#the-logconfig-class)\n  - [Design patterns](chapters/ch04.0-logtar-our-logging-library.md#design-patterns)\n    - [The `Builder` pattern](chapters/ch04.0-logtar-our-logging-library.md#the-builder-pattern)\n  - [Using `builder` pattern with the `LogConfig` class](chapters/ch04.0-logtar-our-logging-library.md#using-builder-pattern-with-the-logconfig-class)\n  - [jsdoc comments](chapters/ch04.0-logtar-our-logging-library.md#jsdoc-comments)\n  - [The `RollingConfig` class](chapters/ch04.0-logtar-our-logging-library.md#the-rollingconfig-class)\n    - [The `RollingSizeOptions` class](chapters/ch04.0-logtar-our-logging-library.md#the-rollingsizeoptions-class)\n    - [The `RollingTimeOptions` class](chapters/ch04.0-logtar-our-logging-library.md#the-rollingtimeoptions-class)\n  - [Finishing up the `RollingConfig` class](chapters/ch04.0-logtar-our-logging-library.md#finishing-up-the-rollingconfig-class)\n    - [Let's recap](chapters/ch04.0-logtar-our-logging-library.md#let-s-recap)\n  - [Adding more useful methods in the `LogConfig` class](chapters/ch04.0-logtar-our-logging-library.md#adding-more-useful-methods-in-the-logconfig-class)\n    - [Why `readFileSync`?](chapters/ch04.0-logtar-our-logging-library.md#why-readfilesync-)\n  - [Refactoring the code](chapters/ch04.1-refactoring-the-code.md#refactoring-the-code)\n    - [**The Need for Refactoring**](chapters/ch04.1-refactoring-the-code.md#-the-need-for-refactoring-)\n    - [**Creating Separate Files**](chapters/ch04.1-refactoring-the-code.md#-creating-separate-files-)\n    - [The `index.js` file](chapters/ch04.1-refactoring-the-code.md#the-index-js-file)\n    - [The `lib/logtar.js` file](chapters/ch04.1-refactoring-the-code.md#the-lib-logtar-js-file)\n    - [The `lib/logger.js` file](chapters/ch04.1-refactoring-the-code.md#the-lib-logger-js-file)\n    - [The `lib/config/log-config.js` file](chapters/ch04.1-refactoring-the-code.md#the-lib-config-log-config-js-file)\n    - [The `lib/config/rolling-config.js` file](chapters/ch04.1-refactoring-the-code.md#the-lib-config-rolling-config-js-file)\n    - [The `lib/utils/log-level.js` file](chapters/ch04.1-refactoring-the-code.md#the-lib-utils-log-level-js-file)\n    - [The `lib/utils/rolling-options.js` class](chapters/ch04.1-refactoring-the-code.md#the-lib-utils-rolling-options-js-class)\n  - [Writing logs](chapters/ch04.2-writing-logs.md#writing-logs)\n    - [1. Re-using the File Handle](chapters/ch04.2-writing-logs.md#1-re-using-the-file-handle)\n    - [2. Log Rotation](chapters/ch04.2-writing-logs.md#2-log-rotation)\n    - [3. Asynchronous Logging](chapters/ch04.2-writing-logs.md#3-asynchronous-logging)\n    - [4. Getting Caller Information (Module and Line Number)](chapters/ch04.2-writing-logs.md#4-getting-caller-information-module-and-line-number-)\n    - [Testing our current API](chapters/ch04.2-writing-logs.md#testing-our-current-api)\n    - [Implementing logging methods](chapters/ch04.2-writing-logs.md#implementing-logging-methods)\n    - [DRY (Don't Repeat Yourself)](chapters/ch04.2-writing-logs.md#dry-don-t-repeat-yourself-)\n    - [The `log` method](chapters/ch04.2-writing-logs.md#the-log-method)\n    - [Considering the `log_level` member variable](chapters/ch04.2-writing-logs.md#considering-the-log_level-member-variable)\n    - [Writing to a file](chapters/ch04.2-writing-logs.md#writing-to-a-file)\n    - [Another gotcha](chapters/ch04.2-writing-logs.md#another-gotcha)\n    - [Logs directory configuration](chapters/ch04.2-writing-logs.md#logs-directory-configuration)\n    - [The `require` object](chapters/ch04.2-writing-logs.md#the-require-object)\n    - [Adding a new helper to create log directory](chapters/ch04.2-writing-logs.md#adding-a-new-helper-to-create-log-directory)\n    - [Updating the `init` method](chapters/ch04.2-writing-logs.md#updating-the-init-method)\n    - [Completing the `log` method](chapters/ch04.2-writing-logs.md#completing-the-log-method)\n  - [Capturing metadata](chapters/ch04.3-capturing-metadata.md#capturing-metadata)\n    - [What is a Stack?](chapters/ch04.3-capturing-metadata.md#what-is-a-stack-)\n    - [Examples of Stacks](chapters/ch04.3-capturing-metadata.md#examples-of-stacks)\n    - [The Call Stack](chapters/ch04.3-capturing-metadata.md#the-call-stack)\n    - [Getting the stack info](chapters/ch04.3-capturing-metadata.md#getting-the-stack-info)\n    - [Getting the `callee` name and the line number](chapters/ch04.3-capturing-metadata.md#getting-the-callee-name-and-the-line-number)\n    - [A more ergonomic way](chapters/ch04.3-capturing-metadata.md#a-more-ergonomic-way)\n    - [Using the `get_caller_info` function](chapters/ch04.3-capturing-metadata.md#using-the-get_caller_info-function)\n  - [A small intro to `async` vs `sync`](chapters/ch04.4-intro-to-async-vs-sync.md#a-small-intro-to-async-vs-sync-)\n    - [The Balance between Opposites](chapters/ch04.4-intro-to-async-vs-sync.md#the-balance-between-opposites)\n    - [Mixing Asynchronous and Synchronous Code](chapters/ch04.4-intro-to-async-vs-sync.md#mixing-asynchronous-and-synchronous-code)\n    - [Faster I/O out of the box](chapters/ch04.4-intro-to-async-vs-sync.md#faster-i-o-out-of-the-box)\n    - [Blocking Code](chapters/ch04.4-intro-to-async-vs-sync.md#blocking-code)\n    - [Concurrency](chapters/ch04.4-intro-to-async-vs-sync.md#concurrency)\n  - [Adding Rolling File Support](chapters/ch04.5-rolling-file-support.md#adding-rolling-file-support)\n    - [Rolling features](chapters/ch04.5-rolling-file-support.md#rolling-features)\n    - [The `rolling_check()` method](chapters/ch04.5-rolling-file-support.md#the-rolling_check-method)\n    - [`file_handle.stat()`](chapters/ch04.5-rolling-file-support.md#-file_handle-stat-)\n    - [Calling the `rolling_check` method](chapters/ch04.5-rolling-file-support.md#calling-the-rolling_check-method)\n    - [A big gotcha!](chapters/ch04.5-rolling-file-support.md#a-big-gotcha-)\n  - [Stack traces across `await` points](chapters/ch04.5-rolling-file-support.md#stack-traces-across-await-points)\n    - [Testing the new Log file creation](chapters/ch04.5-rolling-file-support.md#testing-the-new-log-file-creation)\n- [HTTP Deep dive](chapters/ch05.0-http-deep-dive.md#http-deep-dive)\n  - [A small web server](chapters/ch05.0-http-deep-dive.md#a-small-web-server)\n    - [Starting our web server](chapters/ch05.0-http-deep-dive.md#starting-our-web-server)\n    - [Testing our web server](chapters/ch05.0-http-deep-dive.md#testing-our-web-server)\n    - [Testing with `cURL`](chapters/ch05.0-http-deep-dive.md#testing-with-curl-)\n  - [HTTP Verbs, Versioning and the benefits of `HTTP/1.1`](chapters/ch05.1-http-verbs-versioning-http1_1.md#http-verbs-versioning-and-the-benefits-of-http-1-1-)\n    - [`GET` - Retrieve data](chapters/ch05.1-http-verbs-versioning-http1_1.md#-get-retrieve-data)\n    - [`POST` - Create something](chapters/ch05.1-http-verbs-versioning-http1_1.md#-post-create-something)\n    - [`PUT` - Replace or Create](chapters/ch05.1-http-verbs-versioning-http1_1.md#-put-replace-or-create)\n    - [`HEAD` - Retrieve Metadata](chapters/ch05.1-http-verbs-versioning-http1_1.md#-head-retrieve-metadata)\n    - [`DELETE` - Remove from existence](chapters/ch05.1-http-verbs-versioning-http1_1.md#-delete-remove-from-existence)\n    - [`PATCH` - Partial updates](chapters/ch05.1-http-verbs-versioning-http1_1.md#-patch-partial-updates)\n    - [A small recap](chapters/ch05.1-http-verbs-versioning-http1_1.md#a-small-recap)\n    - [The `/` path](chapters/ch05.1-http-verbs-versioning-http1_1.md#the-path)\n    - [`HTTP/0.9`](chapters/ch05.1-http-verbs-versioning-http1_1.md#-http-0-9-)\n    - [`HTTP/1.0`](chapters/ch05.1-http-verbs-versioning-http1_1.md#-http-1-0-)\n    - [`HTTP/1.1`](chapters/ch05.1-http-verbs-versioning-http1_1.md#-http-1-1-)\n  - [User agents](chapters/ch05.2-user-agents.md#user-agents)\n    - [`User-Agent` can be weird](chapters/ch05.2-user-agents.md#-user-agent-can-be-weird)\n  - [MIME Type and `Content-Type`](chapters/ch05.3-mime-type-and-content-type.md#mime-type-and-content-type-)\n    - [Understanding the `Accept` Header](chapters/ch05.3-mime-type-and-content-type.md#understanding-the-accept-header)\n    - [Mime Type](chapters/ch05.3-mime-type-and-content-type.md#mime-type)\n    - [Anatomy of a MIME type](chapters/ch05.3-mime-type-and-content-type.md#anatomy-of-a-mime-type)\n    - [But why the wildcard `*/*`?](chapters/ch05.3-mime-type-and-content-type.md#but-why-the-wildcard-)\n    - [The `Content-Type` header](chapters/ch05.3-mime-type-and-content-type.md#the-content-type-header)\n    - [The `charset=UTF-8`: character encoding](chapters/ch05.3-mime-type-and-content-type.md#the-charset-utf-8-character-encoding)\n  - [Headers](chapters/ch05.4-headers.md#headers)\n    - [Header Name](chapters/ch05.4-headers.md#header-name)\n    - [Colon (`:`)](chapters/ch05.4-headers.md#colon-)\n    - [Header Value](chapters/ch05.4-headers.md#header-value)\n    - [Whitespace](chapters/ch05.4-headers.md#whitespace)\n    - [Custom `X-` based headers](chapters/ch05.4-headers.md#custom-x-based-headers)\n  - [Request headers](chapters/ch05.4-headers.md#request-headers)\n    - [Accept](chapters/ch05.4-headers.md#accept)\n    - [Referer](chapters/ch05.4-headers.md#referer)\n    - [Authorization](chapters/ch05.4-headers.md#authorization)\n    - [Cookie](chapters/ch05.4-headers.md#cookie)\n    - [Host](chapters/ch05.4-headers.md#host)\n    - [Content-Type (request)](chapters/ch05.4-headers.md#content-type-request-)\n  - [Response Headers](chapters/ch05.4-headers.md#response-headers)\n    - [Content-Type (response)](chapters/ch05.4-headers.md#content-type-response-)\n    - [Cache-Control](chapters/ch05.4-headers.md#cache-control)\n    - [Set-Cookie](chapters/ch05.4-headers.md#set-cookie)\n  - [Response and Status Codes](chapters/ch05.5-response-status-codes.md#response-and-status-codes)\n    - [`Connection: close` in action](chapters/ch05.5-response-status-codes.md#-connection-close-in-action)\n    - [Status Codes](chapters/ch05.5-response-status-codes.md#status-codes)\n- [`Velocy` - Our backend framework](chapters/ch06.00-velocy-our-backend-framework.md#-velocy-our-backend-framework)\n  - [Why Velocy?](chapters/ch06.00-velocy-our-backend-framework.md#why-velocy-)\n  - [What is a backend framework/library anyway?](chapters/ch06.00-velocy-our-backend-framework.md#what-is-a-backend-framework-library-anyway-)\n  - [Core features of our backend framework](chapters/ch06.00-velocy-our-backend-framework.md#core-features-of-our-backend-framework)\n    - [Routing and URL Handling:](chapters/ch06.00-velocy-our-backend-framework.md#routing-and-url-handling-)\n    - [Middlewares](chapters/ch06.00-velocy-our-backend-framework.md#middlewares)\n    - [Building our own database](chapters/ch06.00-velocy-our-backend-framework.md#building-our-own-database)\n    - [Caching](chapters/ch06.00-velocy-our-backend-framework.md#caching)\n    - [Rate limiting](chapters/ch06.00-velocy-our-backend-framework.md#rate-limiting)\n    - [Some other features that we will be implementing](chapters/ch06.00-velocy-our-backend-framework.md#some-other-features-that-we-will-be-implementing)\n  - [A basic `Router` implementation](chapters/ch06.01-basic-router-implementation.md#a-basic-router-implementation)\n    - [A Toy Router](chapters/ch06.01-basic-router-implementation.md#a-toy-router)\n    - [`Transfer-Encoding: chunked`](chapters/ch06.01-basic-router-implementation.md#-transfer-encoding-chunked-)\n    - [Chunks, oh no!](chapters/ch06.01-basic-router-implementation.md#chunks-oh-no-)\n    - [Specifying `Content-Length`](chapters/ch06.01-basic-router-implementation.md#specifying-content-length-)\n    - [Code reusability](chapters/ch06.01-basic-router-implementation.md#code-reusability)\n  - [The `Router` class](chapters/ch06.02-the-router-class.md#the-router-class)\n    - [Using `Router` with an HTTP server](chapters/ch06.02-the-router-class.md#using-router-with-an-http-server)\n  - [`this` is not good](chapters/ch06.02-the-router-class.md#-this-is-not-good)\n    - [Lexical Context](chapters/ch06.02-the-router-class.md#lexical-context)\n    - [Arrow functions are not free](chapters/ch06.02-the-router-class.md#arrow-functions-are-not-free)\n    - [Why should we care about memory?](chapters/ch06.02-the-router-class.md#why-should-we-care-about-memory-)\n    - [Testing the updated code](chapters/ch06.02-the-router-class.md#testing-the-updated-code)\n  - [Improving the `Router` API](chapters/ch06.03-improving-the-router-api.md#improving-the-router-api)\n  - [The Need for a `Trie`](chapters/ch06.04-the-need-for-a-trie.md#the-need-for-a-trie-)\n    - [What is a `Trie` anyway?](chapters/ch06.04-the-need-for-a-trie.md#what-is-a-trie-anyway-)\n  - [Ex. Implementing a `Trie`](chapters/ch06.05-ex-implementing-a-trie.md#ex-implementing-a-trie-)\n    - [Root Node](chapters/ch06.05-ex-implementing-a-trie.md#root-node)\n    - [End of the word](chapters/ch06.05-ex-implementing-a-trie.md#end-of-the-word)\n    - [Challenge 1: Basic Trie with `insert` Method](chapters/ch06.05-ex-implementing-a-trie.md#challenge-1-basic-trie-with-insert-method)\n    - [Challenge 2: Implement `search` method](chapters/ch06.05-ex-implementing-a-trie.md#challenge-2-implement-search-method)\n  - [Ex. Implementing our Trie based `Router`](chapters/ch06.06-ex-implementing-router.md#ex-implementing-our-trie-based-router-)\n    - [Challenge 1: Implementing the `addRoute` method](chapters/ch06.06-ex-implementing-router.md#challenge-1-implementing-the-addroute-method)\n    - [Challenge 2: Implementing the `findRoute` method](chapters/ch06.06-ex-implementing-router.md#challenge-2-implementing-the-findroute-method)\n  - [Ex. Adding `HTTP` method support](chapters/ch06.07-ex-adding-http-methods.md#ex-adding-http-method-support)\n    - [Requirements](chapters/ch06.07-ex-adding-http-methods.md#requirements)\n    - [More details](chapters/ch06.07-ex-adding-http-methods.md#more-details)\n    - [Example](chapters/ch06.07-ex-adding-http-methods.md#example)\n    - [Hints](chapters/ch06.07-ex-adding-http-methods.md#hints)\n    - [Solution](chapters/ch06.07-ex-adding-http-methods.md#solution)\n  - [Adding HTTP methods to the Router](chapters/ch06.08-adding-verbs-api.md#adding-http-methods-to-the-router)\n    - [Update the `TrieRouter` class](chapters/ch06.08-adding-verbs-api.md#update-the-trierouter-class)\n  - [Ex. Implementing Dynamic Routing](chapters/ch06.09-ex-dynamic-routing.md#ex-implementing-dynamic-routing)\n    - [Why Dynamic Routing?](chapters/ch06.09-ex-dynamic-routing.md#why-dynamic-routing-)\n    - [Anatomy of a dynamic route](chapters/ch06.09-ex-dynamic-routing.md#anatomy-of-a-dynamic-route)\n    - [Challenge: Enhance the `TrieRouter` Class to Support Dynamic Routing](chapters/ch06.09-ex-dynamic-routing.md#challenge-enhance-the-trierouter-class-to-support-dynamic-routing)\n    - [Visualisation of our `TrieRouter` structure](chapters/ch06.09-ex-dynamic-routing.md#visualisation-of-our-trierouter-structure)\n    - [Summary](chapters/ch06.09-ex-dynamic-routing.md#summary)\n  - [Running Our Server](chapters/ch06.10-running-our-server.md#running-our-server)\n    - [Refactoring the `TrieRouter` class](chapters/ch06.10-running-our-server.md#refactoring-the-trierouter-class)\n    - [Type Aliases](chapters/ch06.10-running-our-server.md#type-aliases)\n    - [The `run` function](chapters/ch06.10-running-our-server.md#the-run-function)\n  - [Building our first web-server](chapters/ch06.11-building-a-web-server.md#building-our-first-web-server)\n    - [More refactoring](chapters/ch06.11-building-a-web-server.md#more-refactoring)\n    - [Your first web server](chapters/ch06.11-building-a-web-server.md#your-first-web-server)\n  - [Ex. Query Parameters (Advanced)](chapters/ch06.12-query-parameters.md#ex-query-parameters-advanced-)\n    - [Anatomy of a URL with Query Parameters](chapters/ch06.12-query-parameters.md#anatomy-of-a-url-with-query-parameters)\n    - [Challenge 1: Implementing Basic Query Parameter Parsing](chapters/ch06.12-query-parameters.md#challenge-1-implementing-basic-query-parameter-parsing)\n    - [We need to tackle more edge cases](chapters/ch06.12-query-parameters.md#we-need-to-tackle-more-edge-cases)\n    - [Challenge 2: Parsing Query Parameters Manually](chapters/ch06.12-query-parameters.md#challenge-2-parsing-query-parameters-manually)\n\n","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fishtms%2Flearn-nodejs-hard-way","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fishtms%2Flearn-nodejs-hard-way","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fishtms%2Flearn-nodejs-hard-way/lists"}