<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Manon</title>
    <description>The latest articles on Forem by Manon (@manonja).</description>
    <link>https://forem.com/manonja</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F40895%2Ff5f9bdec-6a43-45fe-aa4e-2e385900a03d.jpeg</url>
      <title>Forem: Manon</title>
      <link>https://forem.com/manonja</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/manonja"/>
    <language>en</language>
    <item>
      <title>From TypeScript to Rust: Navigating Memory Safety Challenges</title>
      <dc:creator>Manon</dc:creator>
      <pubDate>Tue, 21 Jan 2025 04:34:08 +0000</pubDate>
      <link>https://forem.com/manonja/from-typescript-to-rust-navigating-memory-safety-challenges-3ia2</link>
      <guid>https://forem.com/manonja/from-typescript-to-rust-navigating-memory-safety-challenges-3ia2</guid>
      <description>&lt;p&gt;I’m setting out on an exciting new challenge: learning Rust. Why? It’s the  &lt;a href="https://github.blog/developer-skills/programming-languages-and-frameworks/why-rust-is-the-most-admired-language-among-developers/" rel="noopener noreferrer"&gt;most loved programming language&lt;/a&gt;, there’s got to be a reason! Plus, I’ve designed a curriculum to help  people level up their backend skills to land and work on more meaningful, impactful projects. I’m the first test subject. You can have a look and level up &lt;a href="https://github.com/manonja/top-backend-DISSS" rel="noopener noreferrer"&gt;here&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Learning a new programming language isn’t magic.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It’s all about practice and tackling plenty of programming challenges 😊&lt;/p&gt;

&lt;p&gt;For example, Leetcode is a solid place to start. Exercise two: &lt;strong&gt;Linked List&lt;/strong&gt;. Even with five years as a developer, I had to refresh my memory. Working as a TypeScript/React/Node.js full-stack developer at startups, you don’t often encounter structures like linked lists. &lt;/p&gt;

&lt;p&gt;Simply said, &lt;strong&gt;a linked list is a group of nodes where one node points to the next.&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;I often find it easier to think in analogy. So here's one: a linked list is like a hiking trail with markers in the mountains. Each trail marker (node) points to the next one. You can only move forward step by step, and can't take shortcuts! If you want to reach a specific marker, you have to follow the trail from the start. This makes it simple to add or remove markers (nodes) without messing up the entire trail.&lt;/p&gt;

&lt;p&gt;Sometimes you need a &lt;strong&gt;structure that’s adaptable&lt;/strong&gt;, like a trail that can grow or shrink without a complete redesign. Linked lists, for example, are great for apps that manage dynamic tasks, like your daily to-dos. When you add or complete a task, the list adjusts seamlessly, just like updating a trail (if this is a thing at all).&lt;/p&gt;

&lt;h3&gt;
  
  
  Implementing a Linked List in Rust, it turns out, is a tough one.
&lt;/h3&gt;

&lt;p&gt;I found it harder in Rust compared to, let's say, Typescript, because of its strict &lt;strong&gt;ownership and borrowing rules&lt;/strong&gt;, which are there to ensure &lt;strong&gt;memory safety&lt;/strong&gt;. Each node needs to point to the next, and Rust's borrow checker ensures no mutable reference is active while others exist. In simpler terms, Rust needs to know exactly how much memory to allocate, and where. As a beginner with Rust, wrapping my head around these concepts has been fun. &lt;/p&gt;

&lt;p&gt;TypeScript, on the other hand, makes this easier. It’s garbage-collected, so memory management is automatic. You can create nodes as objects and connect them without worrying about ownership, borrowing, or memory allocation. But that simplicity comes with trade-offs (of course): Rust’s strictness leads to better performance and safer code, even if it makes something as "basic" as a linked list harder. &lt;/p&gt;

&lt;h3&gt;
  
  
  How do we implement a linked list in Rust?
&lt;/h3&gt;

&lt;p&gt;My understanding is that it has to be with &lt;strong&gt;dynamic memory allocation&lt;/strong&gt;. Rust can do this with the &lt;code&gt;&amp;lt;Box&amp;gt;&lt;/code&gt; smart pointer, which allocates memory to the heap at runtime instead of the stack. However, this approach introduces challenges, because heap memory isn’t automatically freed, which makes it less safe and contradicts Rust’s core principles. &lt;/p&gt;

&lt;p&gt;I’m excited to dig deeper into these safeties issues, if the &lt;code&gt;&amp;lt;Box&amp;gt;&lt;/code&gt; container is really the answer, and make a Linked List in Rust!&lt;/p&gt;

&lt;p&gt;What about you? How would you approach building a linked list in Rust?&lt;/p&gt;

</description>
      <category>rust</category>
      <category>programming</category>
    </item>
    <item>
      <title>Want to be a better full-stack developer? Know the web and HTTP principles</title>
      <dc:creator>Manon</dc:creator>
      <pubDate>Thu, 09 Jan 2025 21:03:07 +0000</pubDate>
      <link>https://forem.com/manonja/want-to-be-a-better-full-stack-developer-know-the-web-and-http-principles-o7n</link>
      <guid>https://forem.com/manonja/want-to-be-a-better-full-stack-developer-know-the-web-and-http-principles-o7n</guid>
      <description>&lt;h2&gt;
  
  
  Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Why Build a HTTP server from Scratch?&lt;/li&gt;
&lt;li&gt;
First, the basics. What Is an HTTP Server?

&lt;ul&gt;
&lt;li&gt;TCP vs. UDP&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Key features of my HTTP Server (Typescript + Nodejs)&lt;/li&gt;

&lt;li&gt;

What I Learned

&lt;ul&gt;
&lt;li&gt;Learning 1: Sockets!&lt;/li&gt;
&lt;li&gt;Learning 2: Routing Isn’t That Simple&lt;/li&gt;
&lt;li&gt;Learning 3: Always Try to Break Your Software&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;What’s Next?&lt;/li&gt;

&lt;li&gt;Why It Matters - Meta Learnings&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why Build a HTTP server from Scratch?
&lt;/h2&gt;

&lt;p&gt;These days, you can spin up a fully functional server in minutes with the help of modern tools.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;So why would anyone bother building an HTTP server from scratch using Nodejs and Typescript?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For me, it's an experiment I am running for the next three months: mastering building blocks fundamentals and re training myself on doing deep work.&lt;/p&gt;

&lt;p&gt;There is also a simple truth about working in tech: if I am serious about thriving as a full-stack engineer, I surely need to own the basics, and not just know how to work with abstractions and frameworks that do pretty much everything for you.&lt;/p&gt;

&lt;p&gt;Beyond the technical challenge, there’s the simple satisfaction of building something fun and tangible. There’s unparalleled satisfaction in crafting a tool that serves a real purpose, like delivering a web page that serves an HTML page with images and text, using only the basics.&lt;/p&gt;

&lt;p&gt;It’s a powerful way to deepen your technical skills in a meaningful way while working on something enjoyable.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;First, the basics. What Is an HTTP Server?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;At its core, an HTTP server is a program that listens for incoming HTTP requests from clients (like a browser or API consumer), processes those requests, and sends back responses. It uses the &lt;strong&gt;TCP (Transmission Control Protocol)&lt;/strong&gt; to establish a reliable connection, ensuring that data packets arrive in order and intact.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;TCP vs. UDP&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;I do mountaineering and one analogy came to me to differentiate TCP and UDP protocols.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;TCP:&lt;/strong&gt; Think of climbers on a glacier roped together. Everyone reaches the summit securely and in order. That’s TCP: ensuring that data (climbers) arrive in order and intact.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;UDP:&lt;/strong&gt; UDP are like alpinists climbing individually without ropes. It’s usually faster, but there’s no guarantee everyone gets there. Fast, but less reliable.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Key features of my HTTP Server (Typescript + Nodejs)&lt;/strong&gt;
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Handles GET and POST Requests:&lt;/strong&gt; Responds with a simple “Hello, World!” for basic requests.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Supports for HTTP/1.1 Protocol:&lt;/strong&gt; Implements the essentials of this widely-used protocol.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Serves Static Files:&lt;/strong&gt; Fetches and delivers image files stored in the server’s &lt;code&gt;public/images/&lt;/code&gt; directory.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Routing:&lt;/strong&gt; Implements basic routing using &lt;code&gt;if-else&lt;/code&gt; statements to handle different endpoints like &lt;code&gt;/api&lt;/code&gt; or &lt;code&gt;/&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Error Handling:&lt;/strong&gt; Ensures proper responses for malformed requests, like returning &lt;code&gt;400 Bad Request&lt;/code&gt; for parsing errors.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  What I Learned
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Learning 1: Sockets!
&lt;/h3&gt;

&lt;p&gt;Sockets are how servers and clients talk to each other. Before this project, I knew about sockets the way most of us know about cars: we press the gas pedal, and the car moves. Magic! Now, I’ve seen how there is nothing magical about it, especially when I wrote the &lt;code&gt;createDataHandler&lt;/code&gt; function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;createDataHandler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;net&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Socket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;handleRequest&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rawRequest&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;statusCode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;statusMessage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Record&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;Buffer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;chunk&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Buffer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;buffer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;chunk&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Buffer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;buffer&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;chunk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\r\n\r\n&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;handleRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;writable&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;formatHttpResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;end&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Socket is not writable, skipping response&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Explanation of &lt;code&gt;createDataHandler&lt;/code&gt; Function
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;createDataHandler&lt;/code&gt; is a function that handles incoming TCP data chunks for HTTP requests. It maintains a &lt;strong&gt;buffer&lt;/strong&gt;—a string that accumulates data from incoming chunks.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Chunk Conversion:&lt;/strong&gt; For each chunk, it converts the binary data into a string and appends it to the buffer.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Header Detection:&lt;/strong&gt; It then checks if the buffer contains &lt;code&gt;\r\n\r\n&lt;/code&gt;, which marks the end of the HTTP headers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Processing &amp;amp; Response:&lt;/strong&gt; If it finds the marker, it processes the request and sends a response.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This gave me a clearer view of how HTTP works at the lowest level: every incoming request starts as raw data, and the server has to parse it into something usable. Sockets are the invisible ropes that pull these chunks back and forth, and the &lt;code&gt;createDataHandler&lt;/code&gt; function is the intermediary which makes something sensible of the data.&lt;/p&gt;

&lt;p&gt;We can also appreciate how fragile things are: if the buffer isn’t handled properly—by failing to detect the end of the headers, for example—the server breaks. These are things I've never appreciated when using frameworks.&lt;/p&gt;

&lt;h3&gt;
  
  
  Learning 2: Routing Isn’t That Simple
&lt;/h3&gt;

&lt;p&gt;Manual routing turned out to be more challenging than I expected, especially when it came to handling content types. Frameworks like Express.js make this super easy, but behind the scenes, there’s a lot happening:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Content-Type Handling:&lt;/strong&gt; My server only supported JSON for request bodies, and I had to set the correct MIME type manually for responses. Adding support for more content types, like &lt;code&gt;multipart/form-data&lt;/code&gt; for file uploads or &lt;code&gt;application/x-www-form-urlencoded&lt;/code&gt; for form submissions, would require additional parsing logic.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Headers Management:&lt;/strong&gt; In a basic setup, you’re responsible for setting essential headers like &lt;code&gt;Content-Type&lt;/code&gt; and &lt;code&gt;Content-Length&lt;/code&gt;. Get these values wrong, and the client either won’t understand the response or will hang waiting for more data. This is what happened when my server was not picking up the &lt;code&gt;images/jpeg&lt;/code&gt; datatype.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parsing Body Formats:&lt;/strong&gt; Each content type requires its own logic. For example, JSON bodies need to be parsed into JavaScript objects, while &lt;code&gt;multipart/form-data&lt;/code&gt; requires handling file streams. This complexity grows quickly as you add support for more formats.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Express.js automates most of this. It detects the &lt;code&gt;Content-Type&lt;/code&gt; header, parses the body accordingly, and sets the right MIME type for responses. Doing this manually gave me a deep appreciation for how much work frameworks save.&lt;/p&gt;

&lt;p&gt;While my manual routing works for basic cases, it’s clear that scaling it to handle more complex scenarios would require more effort.&lt;/p&gt;

&lt;h3&gt;
  
  
  Learning 3: Always Try to Break Your Software
&lt;/h3&gt;

&lt;p&gt;Software is rarely perfect the first time around. A great way to test my server was to run:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;hey -n 1000 -m GET http://localhost:8080/&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Stress Test Outcome
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;BOOM.&lt;/strong&gt; The server crashed after 800 requests.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why?&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
This command sends 1,000 simultaneous GET requests, simulating real-world stress. It exposed a critical issue: I wasn’t handling socket timeouts properly. My server would hang because it didn’t close idle sockets.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Fix:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
To fix this, I chose to close the socket after each request, which works great for the scope of this project. But if I wanted to support persistent connections, I’d need to avoid calling &lt;code&gt;socket.end()&lt;/code&gt; and implement additional logic. For now, closing the connection after each request is the simplest and safest approach. It’s clean, predictable, and prevents resource leaks.&lt;/p&gt;




&lt;h2&gt;
  
  
  What’s Next?
&lt;/h2&gt;

&lt;p&gt;There’s a lot more I can add to this server, which is also the reason why I love to start a project from &lt;strong&gt;ZERO&lt;/strong&gt;. I get to own every bite of it and can add on to it as learning-needs/curiosity fit.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;HTTPS:&lt;/strong&gt; Right now, it’s plain HTTP. Adding SSL/TLS would make it secure.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;WebSockets:&lt;/strong&gt; For real-time communication, like chat apps.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Authentication:&lt;/strong&gt; Handle user logins and sessions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Better Routing:&lt;/strong&gt; Add support for more content types and dynamically set MIME types based on file extensions or request content.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Caching:&lt;/strong&gt; Improve performance by storing frequently requested data.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Why It Matters - Meta Learnings
&lt;/h2&gt;

&lt;p&gt;I am a huge fan of Tim Ferriss, especially when it comes to his lessons on &lt;strong&gt;meta learning&lt;/strong&gt;, or the ability to learn pretty much everything and become a top performer in any field in a short period of time.&lt;/p&gt;

&lt;p&gt;Writing an HTTP server from scratch was a way to dig deeper into one of the fundamental building blocks of full-stack engineering—to deeply understand the web and servers. It was also interesting to see how constraints (not using a framework like Express) force you to think critically and solve problems creatively, which of course deepens my understanding. Last but not least, there’s simply a unique joy in building something functional from scratch! 😃&lt;/p&gt;

&lt;p&gt;You can check the project on &lt;a href="https://github.com/manonja/node-http-server-from-scratch" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;Happy building!&lt;/p&gt;

</description>
      <category>fullstack</category>
      <category>httpserver</category>
      <category>node</category>
      <category>typescript</category>
    </item>
    <item>
      <title>How do you know you have enough data?</title>
      <dc:creator>Manon</dc:creator>
      <pubDate>Sat, 14 Dec 2024 15:47:06 +0000</pubDate>
      <link>https://forem.com/manonja/how-do-you-know-you-have-enough-data-138b</link>
      <guid>https://forem.com/manonja/how-do-you-know-you-have-enough-data-138b</guid>
      <description>&lt;p&gt;In the world of deep learning, a common question that arises is, “How do I know if I have enough data?” This is a &lt;strong&gt;crucial consideration because the quantity and quality of your data can significantly impact the performance of your model&lt;/strong&gt;. However, knowing whether your dataset is sufficient isn’t always straightforward and requires a combination of practice and experimentation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Check the model and ask yourself: is it good enough?
&lt;/h2&gt;

&lt;p&gt;Before diving into data collection or augmentation efforts, it’s important to assess whether your current model is performing well enough. This involves evaluating its accuracy, loss, and generalization ability. If the model is not performing satisfactorily, it’s crucial to investigate whether the issue lies in the dataset size, diversity, or other factors like model complexity.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Questions to Ask:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Is the model overfitting or underfitting? Overfitting might indicate that the model is too complex for the available data. Underfitting suggests the model may be too simple or not trained enough.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How does the model perform on validation or test data? Consistent performance across training and validation sets can indicate sufficient data.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  You Can’t Know If You Have Enough Until You Train the Model
&lt;/h2&gt;

&lt;p&gt;The truth is, you can’t really know if you have enough data until you actually train the model. The process of training helps reveal whether your dataset is capturing the necessary features and patterns to achieve your desired level of performance. You may find that even a small dataset works well with certain problems, especially with the right techniques, like transfer learning or data augmentation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Training Early is Key:
&lt;/h2&gt;

&lt;p&gt;According to Jeremy Howard from Fastai, training early is the recommended approach when it comes to learning fast how your model is doing, and so if you have enough data:&lt;/p&gt;

&lt;p&gt;Training early will give us immediate feedback on how well the model is learning, allowing for quick adjustments to data collection or model parameters, and it will allow us to iterate on our model design and data preprocessing steps, refining them based on initial results.&lt;/p&gt;

&lt;p&gt;As new practitioner, we might spend excessive time gathering or preprocessing data without knowing if it’s even necessary. A better approach seems therefore to train on day 1 to see what kind of accuracy we can achieve with the existing data, and iterate from there. Key Takeaway: Avoid Waiting Too Long Before Training the Model!&lt;/p&gt;

&lt;h2&gt;
  
  
  Advantages of Training Early:
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Experimentation&lt;/strong&gt;: Training early enables experimentation with different models and hyperparameters, helping us to learn what works best for our specific problem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Understanding data needs&lt;/strong&gt;: Initial training results can inform whether more data is required or if our efforts should focus on optimizing other aspects of the model.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Avoiding wasted effort&lt;/strong&gt;: We might find that a simple model trained on limited data achieves acceptable results, saving time and resources!&lt;/p&gt;

&lt;p&gt;That being said, the great thing is that there are techniques available to maximise our data, ensuring we can build effective models even with limited datasets (yay!) - Techniques such as data augmentation, transfer learning, and regularization can significantly enhance model performance.&lt;/p&gt;

&lt;h3&gt;
  
  
  Techniques to maximise our data under constraint (without enough data for instance):
&lt;/h3&gt;

&lt;p&gt;The great thing about deep learning is that there are numerous techniques to maximise our data, ensuring we can build effective models even with limited datasets (yay!) - Techniques such as data augmentation, transfer learning, and regularization can significantly enhance model performance.&lt;/p&gt;

&lt;p&gt;Stay tuned for a separate article that will delve into these techniques, providing strategies and tips on how to make the most of our available data and improve model performance even with constraints.&lt;/p&gt;

&lt;h4&gt;
  
  
  Key takeaway: By training our model early and often, we can gain valuable insights into our data’s sufficiency and learn how to make informed decisions about data collection and preprocessing. This approach not only helps build better models but also makes our development process more agile and responsive.
&lt;/h4&gt;

&lt;p&gt;Any tips on identifying if you have enough data?&lt;/p&gt;

&lt;p&gt;Stay curious, &lt;br&gt;
Manon &lt;/p&gt;

</description>
      <category>deeplearning</category>
      <category>data</category>
      <category>dataset</category>
    </item>
    <item>
      <title>What Usain Bolt, Leibniz and Newton Have in Common?</title>
      <dc:creator>Manon</dc:creator>
      <pubDate>Sat, 14 Dec 2024 15:32:26 +0000</pubDate>
      <link>https://forem.com/manonja/what-usain-bolt-leibniz-and-newton-have-in-common-44c3</link>
      <guid>https://forem.com/manonja/what-usain-bolt-leibniz-and-newton-have-in-common-44c3</guid>
      <description>&lt;p&gt;When I first came across a mention of Usain Bolt, Leibniz, and Newton together on Khan Academy, it instantly sparked my attention, which makes me want to share it in return. &lt;/p&gt;

&lt;p&gt;What could a legendary sprinter and two famous mathematicians have in common? It turns out the answer lies in the basics of calculus, which I realise is more relevant than I initially thought when learning deep learning and artificial intelligence mathematical concepts.&lt;/p&gt;

&lt;p&gt;In the context of understanding how neural networks (really work), I logically found myself revisiting the basics of calculus. Oh joy! In this article, I'll share how these three seemingly disparate figures are linked through one obsession that is not only crucial in sports and physics but also, it turns out, in the rapidly evolving field of AI (I know, unbearable suspense!)&lt;/p&gt;

&lt;h2&gt;
  
  
  Asking a Fundamental Question
&lt;/h2&gt;

&lt;p&gt;Bolt, Leibniz, and Newton were all obsessed with the same fundamental question, one that drives much of differential calculus: &lt;strong&gt;What is the instantaneous rate of change of something?&lt;/strong&gt; This might sound abstract, but it's actually a question that pops up in many real-world situations.&lt;/p&gt;

&lt;p&gt;Take Bolt, for example. We might be curious about how fast he’s running at any given moment during a race. Not just his average speed over a second or the next ten seconds, but his exact speed right now. This is precisely what differential calculus helps us figure out—it's all about understanding instantaneous rates of change, the speed of something at a specific moment in time.&lt;/p&gt;

&lt;p&gt;At its core, the instantaneous rate of change is all about pinpointing how quickly something is happening at a specific moment. In simpler terms, it’s the speed of a process at one exact point in time. Imagine you're driving a car. While you might be interested in your average speed during a trip, you might also want to know how fast you’re going right now, as you glance at the speedometer. That’s an instantaneous rate of change—the speed of the car at that precise moment.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is an Instantaneous Rate of Change?
&lt;/h2&gt;

&lt;p&gt;In mathematics, this concept is crucial because it allows us to move beyond averages and see what's happening in the moment. For athletes like Usain Bolt, it’s the difference between knowing his average speed over a race and understanding his top speed at any given instant. This idea isn't just limited to speed; it applies to any situation where change occurs—whether it’s the temperature outside, the stock market's rise and fall, or even how fast a neural network is learning during training.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why is this concept so crucial in deep learning?
&lt;/h2&gt;

&lt;p&gt;In mathematics, this concept allows us to move beyond averages and see what's happening in the moment. For athletes like Usain Bolt, it’s the difference between knowing his average speed over a race and understanding his top speed at any given instant. This idea isn't just limited to speed; it applies to any situation where change occurs—whether it’s the temperature outside, the stock market's rise and fall, or, and this is where my interests lie today: how fast a neural network is learning during training.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fllrlpfi1yjen7xzoiohz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fllrlpfi1yjen7xzoiohz.png" alt="Image description" width="800" height="382"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Calculate the average rate of change over [1, 3] - Khan Academy&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What about Derivatives?
&lt;/h2&gt;

&lt;p&gt;You might remember derivatives from your college classes. Personally, I definitely needed a refresher on that fundamental mathematical concept. Instantaneous rates of change and derivatives are deeply connected in calculus. A derivative, in simple terms, measures how a function changes as its input changes. It gives us the rate at which something is happening at any precise moment. So, if we were to graph Usain Bolt's speed over time during a race, the derivative of that graph at any given point would tell us his exact speed at that moment.&lt;/p&gt;

&lt;h3&gt;
  
  
  Derivatives are powerful because they allow us to move from knowing general trends to understanding specific details in real time.
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Read that again.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Derivatives give us the insight needed to see how things are changing right now, not just on average, whether we are calculating Usain Bolt’s speed or fine-tuning the learning speed of a neural network.&lt;/p&gt;

&lt;h2&gt;
  
  
  Applied derivative example and why it matters in the context of deep learning
&lt;/h2&gt;

&lt;p&gt;Let’s come back to why we arrived here in the first place: understand how neural net really work.&lt;/p&gt;

&lt;p&gt;When we dive into the world of deep learning, derivatives become more than just abstract mathematical tools—they are in fact essential for training neural networks. In this context, derivatives are used to optimise the network by adjusting the weights of connections between neurons to minimise errors and improve performance.&lt;/p&gt;

&lt;p&gt;Let’s consider how a neural network learns to recognise images.&lt;/p&gt;

&lt;p&gt;During training, the network makes predictions and compares them to the actual outcomes. The difference between the prediction and the reality is calculated as an error. To reduce this error, the network uses a process called backpropagation, which relies on derivatives. By calculating the derivative of the error with respect to each weight in the network, we can determine how much each weight should be adjusted to improve the model's accuracy. This adjustment process is repeated many times, gradually tuning the network until it performs well.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In essence, and based on what I learned so far through the Fastai course and Andrej Karpathy’s youtube series, derivatives help guide the network’s learning process, making them indispensable in the development of AI systems. Without understanding and applying these instantaneous rates of change, the sophisticated models that drive advancements in machine learning and artificial intelligence would simply not be possible.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What we learned today:
&lt;/h2&gt;

&lt;p&gt;Instantaneous rates of change and derivatives are crucial concepts that connect theoretical mathematics with real-world applications.&lt;/p&gt;

&lt;p&gt;Derivatives allow us to move from understanding general trends to capturing specific, real-time details.&lt;/p&gt;

&lt;p&gt;In deep learning, derivatives are essential for optimising and improving neural network performance.&lt;/p&gt;

&lt;p&gt;The best takeaway for me is: ##We don’t need super advanced mathematical concepts to learn deep learning!## And that's a really good news.&lt;/p&gt;

&lt;p&gt;Keep moving,&lt;br&gt;
Manon 🦉 &lt;/p&gt;

</description>
      <category>deeplearning</category>
      <category>calculus</category>
      <category>learning</category>
    </item>
    <item>
      <title>Fitting a function to data</title>
      <dc:creator>Manon</dc:creator>
      <pubDate>Sat, 14 Dec 2024 15:16:26 +0000</pubDate>
      <link>https://forem.com/manonja/fitting-a-function-to-data-ie0</link>
      <guid>https://forem.com/manonja/fitting-a-function-to-data-ie0</guid>
      <description>&lt;p&gt;The first time I heard about “Fitting a function to data“ in the &lt;a href="https://course.fast.ai/" rel="noopener noreferrer"&gt;fastai&lt;/a&gt; course, my brain went 🤯 - it turns out, fitting a function to data is a &lt;strong&gt;fundamental aspect in training models&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In the context of neural networks, “fitting a function to data” refers to the process of training a model to learn the underlying patterns, relationships, or mappings between input data and the desired output.&lt;/p&gt;

&lt;p&gt;Let’s delve into this fundamental aspect of neural nets, why it’s essential, and how it is achieved in practice.&lt;/p&gt;

&lt;h3&gt;
  
  
  Understanding the Concept:
&lt;/h3&gt;

&lt;p&gt;At its core, a neural network is a complex mathematical function designed to &lt;strong&gt;transform input data into output predictions&lt;/strong&gt;. The objective of training, or fitting, is to adjust the function's parameters—namely, weights and biases—so that the network’s predictions closely align with the actual target values. This process of fine-tuning is crucial for the model to accurately reflect the relationships within the data.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a Function?
&lt;/h2&gt;

&lt;p&gt;First things first. What is a function?&lt;/p&gt;

&lt;p&gt;A function defines a relationship between a set of inputs and a set of possible outputs. When we talk about functions in machine learning, we're referring to this relationship in a specific context:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Input (X): The data we provide to the model (e.g., images, text, numerical features).

Output (Y): The prediction or classification that the model generates (e.g., labels, regression values).

In a neural network, the function is represented as f(X,θ)f(X, \theta)f(X,θ), where:

XXX is the input data.

θ\thetaθ represents the parameters (weights and biases).

fff is the model that maps inputs to outputs.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The goal of fitting the function is to &lt;strong&gt;adjust θ\thetaθ so that the function fff accurately captures the relationship between XXX and YYY&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Do We Fit a Function to Data?
&lt;/h2&gt;

&lt;p&gt;Fitting a function to data is essential in neural networks for several reasons:&lt;/p&gt;

&lt;h3&gt;
  
  
  To Learn Patterns and Relationships
&lt;/h3&gt;

&lt;p&gt;Discovering Hidden Structures: Data often contains complex patterns or relationships that aren’t immediately obvious. By fitting a function, a neural network can learn these structures and make sense of the data.&lt;/p&gt;

&lt;p&gt;Feature Extraction: Neural networks have the ability to automatically learn and extract relevant features from raw data, reducing the need for extensive manual feature engineering.&lt;/p&gt;

&lt;h3&gt;
  
  
  To Make Predictions
&lt;/h3&gt;

&lt;p&gt;Generalization: Once a neural network is trained, it should generalize well to unseen data, making accurate predictions based on the patterns it has learned.&lt;/p&gt;

&lt;p&gt;Decision Making: The predictions made by a neural network can drive decision-making processes in various applications, such as self-driving cars, medical diagnosis, and financial forecasting.&lt;/p&gt;

&lt;h3&gt;
  
  
  To Better Optimization and Efficiency
&lt;/h3&gt;

&lt;p&gt;Loss Minimization: The process of fitting involves minimizing a loss function, which quantifies the difference between predicted and actual values. The goal is to find parameter values that yield the lowest possible loss.&lt;/p&gt;

&lt;p&gt;Efficient Representation: Neural networks can efficiently represent complex functions with relatively few parameters, making them well-suited for high-dimensional data.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Does Fitting Work?
&lt;/h2&gt;

&lt;p&gt;The process of fitting a function to data in a neural network involves several key steps that I tried to summarise below:&lt;/p&gt;

&lt;p&gt;Step 1: &lt;strong&gt;Initialisation&lt;/strong&gt;: The weights and biases of the network are initialised, often with small random values.&lt;/p&gt;

&lt;p&gt;Step 2: &lt;strong&gt;Passing the data and first prediction&lt;/strong&gt;: the Input data is passed through the network layers, with transformations applied based on the current parameter values to produce an output. The network then generates predictions for the given input data.&lt;/p&gt;

&lt;p&gt;Step 3: &lt;strong&gt;Loss Calculation&lt;/strong&gt;: We then apply a loss function (e.g., mean squared error, cross-entropy) to measure the difference between predicted and actual target values. This is a key step in fitting data into functions. We then can calculate Loss: the loss is computed for the given predictions, providing a metric for how well the network is performing.&lt;/p&gt;

&lt;p&gt;Step 4: &lt;strong&gt;Back-propagation&lt;/strong&gt;: Using backpropagation, the gradients of the loss with respect to each parameter are computed. This involves applying the chain rule to propagate errors backward through the network. This is called gradient calculation (best video on it I found here).&lt;/p&gt;

&lt;p&gt;Step 5: &lt;strong&gt;Parameter Update&lt;/strong&gt;: Parameters are updated using optimisation algorithms like stochastic gradient descent (SGD).&lt;/p&gt;

&lt;p&gt;Step 6: &lt;strong&gt;Iteration&lt;/strong&gt;, of course! The training process is repeated over multiple iterations (epochs) and different subsets of data (batches) to continuously refine the parameter values. The ultimate goal in the iterative process is to reach a convergence to a set of parameters that minimize the loss function, achieving a good fit to the training data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Not Use Traditional Models like Linear Regression?
&lt;/h2&gt;

&lt;p&gt;In the Fastai course, we use a simpler Linear Regression to fit a quadratic. This model fits simple functions to data, which prove to be insufficient for more complex tasks where:&lt;/p&gt;

&lt;p&gt;Non-linearity: Data relationships are non-linear and require sophisticated functions to capture.&lt;/p&gt;

&lt;p&gt;High Dimensionality: Inputs are high-dimensional (e.g., images, audio) and need complex architectures.&lt;/p&gt;

&lt;p&gt;Complex Patterns: Patterns involve intricate interactions that simple models cannot capture effectively. Neural networks excel in these scenarios due to their ability to approximate complex functions.&lt;/p&gt;

&lt;h2&gt;
  
  
  What We Learned Today
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Fitting a function to data is the &lt;strong&gt;process of training a neural network to learn the relationships between input data and the desired output&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A neural network functions is a complex mathematical model that adjusts its parameters (weights and biases) &lt;strong&gt;to minimise the difference between predictions and actual target values&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Fitting a function is essential for discovering hidden structures in data and making accurate predictions&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The process of fitting involves &lt;strong&gt;key steps&lt;/strong&gt;: initialisation, forward pass, loss calculation, backpropagation, and iterative optimisation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Traditional models like linear regression may not be sufficient for complex, non-linear, and high-dimensional data, where &lt;strong&gt;neural networks excel&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Stay curious!&lt;/p&gt;

&lt;p&gt;Manon 🦉&lt;/p&gt;

</description>
      <category>neuralnetwork</category>
      <category>deeplearning</category>
      <category>data</category>
    </item>
    <item>
      <title>A Quick and Comprehensive Guide On Which Database to Use in your next Fullstack Application</title>
      <dc:creator>Manon</dc:creator>
      <pubDate>Mon, 26 Feb 2024 17:49:07 +0000</pubDate>
      <link>https://forem.com/manonja/a-quick-and-comprehensive-guide-on-which-database-to-use-in-your-next-fullstack-application-7po</link>
      <guid>https://forem.com/manonja/a-quick-and-comprehensive-guide-on-which-database-to-use-in-your-next-fullstack-application-7po</guid>
      <description>&lt;p&gt;In the ever-evolving world of technology, we can safely say that there is this one constant (🥳), the backbone of most applications — whether they're your go-to weather app or the &lt;strong&gt;database managing global transactions&lt;/strong&gt; — is the &lt;strong&gt;database management system (DBMS)&lt;/strong&gt; they rely on. Building fullstack applications made me want to gather in one place my notes and takeaways from different databases, which hopefully will also help you see clearer, and make an informed decision on which database to use, and why. &lt;/p&gt;

&lt;p&gt;So this is a short and sweet guide on the main three databases most used today: SQLite, PostgreSQL, and MongoDB. Each of these powerhouses offers unique features, advantages, and typical use cases. Let's dive in! &lt;/p&gt;

&lt;h3&gt;
  
  
  SQLite - The Lightweight Champion 🕊️
&lt;/h3&gt;

&lt;p&gt;Imagine a tiny, yet mighty warrior—that's SQLite! It's the database equivalent of having a Swiss Army knife in your pocket. It is designed to be embedded within the application it powers: SQLite is a self-contained, disk-based database that doesn't fuss over needing a separate server process. &lt;/p&gt;

&lt;h4&gt;
  
  
  Pros:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Lightweight and Portable: Effortless setup, ideal for constrained environments.&lt;/li&gt;
&lt;li&gt;No Installation Needed: Seamless integration with applications, simplifying deployment.&lt;/li&gt;
&lt;li&gt;Reliable and Accessible: A robust storage solution that's straightforward to manage.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Cons:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Limited Scalability: Not the best fit for high-traffic scenarios or concurrent writes.&lt;/li&gt;
&lt;li&gt;Fewer Features: Misses out on some advanced functionalities of more complex systems.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Famous Use Case:
&lt;/h4&gt;

&lt;p&gt;Apple makes extensive use of SQLite across macOS and iOS, embedding it within various system functions and applications, showcasing its reliability and efficiency.&lt;/p&gt;

&lt;h3&gt;
  
  
  PostgreSQL: The Robust Workhorse 🏋️‍♂️
&lt;/h3&gt;

&lt;p&gt;Here we are dealing with object-relational database system that's all about reliability, robust features, and performance. It's like having a reliable workhorse that can carry heavy loads without breaking a sweat. PostgreSQL shines then in enterprise applications, web services, data warehousing, or geospatial databases thanks to its scalability and advanced features.&lt;br&gt;
A big plus for PostgreSQL is that it's open-source 😎&lt;/p&gt;

&lt;h4&gt;
  
  
  Pros:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Highly Scalable: made to handle large datasets and numerous concurrent users.&lt;/li&gt;
&lt;li&gt;Advanced Features: Rich in functionalities like complex queries and transactions.&lt;/li&gt;
&lt;li&gt;Extensibility: Custom data types and functions for tailored solutions.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Cons:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Complexity: Its sophistication can be a hurdle for smaller teams or projects.&lt;/li&gt;
&lt;li&gt;Resource Intensive: Requires a significant investment in hardware and upkeep.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Famous Use Case:
&lt;/h4&gt;

&lt;p&gt;:drum-roll: Instagram!&lt;/p&gt;

&lt;h3&gt;
  
  
  MongoDB: The Agile NoSQL 🐐
&lt;/h3&gt;

&lt;p&gt;Finally, let's talk about MongoDB, the NoSQL database that's all about flexibility and speed. Picture a gymnast performing a flawless routine—graceful, flexible, and powerful. That's MongoDB, storing data in flexible, JSON-like documents which allows fields to vary and data structure to change over time. It's perfect for big data applications, content management systems, and mobile apps requiring real-time data. &lt;/p&gt;

&lt;h4&gt;
  
  
  Pros:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;High Performance: Designed for rapid data retrieval and large data volumes.&lt;/li&gt;
&lt;li&gt;Scalability: Sharding capability for distributing data across servers.&lt;/li&gt;
&lt;li&gt;Flexible Schema: Adapts to polymorphic data, perfect for changing data models.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Cons:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Awkward Joins: Performing joins is less straightforward than in relational databases.&lt;/li&gt;
&lt;li&gt;Memory Usage: Potentially high, which could be restrictive in certain environments.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Famous Use Case:
&lt;/h4&gt;

&lt;p&gt;Meta  utilizes MongoDB for its diverse set of applications.&lt;/p&gt;

&lt;h3&gt;
  
  
  Making the Choice
&lt;/h3&gt;

&lt;p&gt;Choosing between SQLite, PostgreSQL, and MongoDB isn't about picking the best database overall — it's about finding the best fit for your project's needs. If simplicity and ease of use are paramount, SQLite might be your best choice. For projects requiring data integrity, complex queries, and scalability, PostgreSQL stands ready to support you in that. And for scenarios demanding flexibility, scalability, and high performance, especially with large volumes of unstructured data, MongoDB might be the way to go.&lt;/p&gt;

&lt;p&gt;Thanks for reading, and happy coding 👋&lt;/p&gt;

</description>
      <category>database</category>
      <category>fullstack</category>
      <category>guide</category>
    </item>
    <item>
      <title>8 Plugins You Should Add To Your IDE And Why</title>
      <dc:creator>Manon</dc:creator>
      <pubDate>Fri, 16 Feb 2024 12:49:34 +0000</pubDate>
      <link>https://forem.com/manonja/8-plugins-you-should-add-to-your-ide-and-why-468</link>
      <guid>https://forem.com/manonja/8-plugins-you-should-add-to-your-ide-and-why-468</guid>
      <description>&lt;p&gt;First and foremost, I am using WebStorm. I know. I am paying for my licence. Why? Because I find it extremely powerful in terms of performance, typing, and debugging capabilities. I am also used to its shortcuts now, which makes it hard for me to switch to VSC (and believe me, I’ve tried many times!)&lt;/p&gt;

&lt;p&gt;The nice thing about WebStorm is also that it has all the plugins you need coming out of the box. You then end up adding very specific plugins you need, and that’s it.&lt;/p&gt;

&lt;p&gt;Note: I recommend to disable the plugins you won’t need for your projects though. For example, if you are a React developer, it’s pretty safe to say that you won’t need the Angular plugin. Just go to Settings -&amp;gt; Plugins -&amp;gt; Installed, and disable it. A clean working environment is a powerful environment ;)&lt;/p&gt;

&lt;p&gt;So, what are the plugins that I am using?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;a href="https://plugins.jetbrains.com/plugin/7495--ignore" rel="noopener noreferrer"&gt;.ignore&lt;/a&gt;&lt;/strong&gt;: is a plugin for all .[something]ignore you can think of: .eslintignore, .dockerignore , .vercelignore , .gitignore …it will help with syntax highlighting, suggesting new .gitignore files on a project, support comments and brackets, or entries inspections with quick-fix proposals. You can see the full list of feature &lt;a href="https://plugins.jetbrains.com/plugin/7495--ignore" rel="noopener noreferrer"&gt;here&lt;/a&gt;!&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;a href="https://plugins.jetbrains.com/plugin/9525--env-files-support" rel="noopener noreferrer"&gt;.env files support&lt;/a&gt;&lt;/strong&gt;: isn’t annoying that you cannot just go to declaration (in .env file) and usages (in code) just by hitting a shortcut command? With this plugin, you can 🙏 — This plugin also helps with autocompletion on environment variables, which is pretty convenient.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;a href="https://plugins.jetbrains.com/plugin/7425-wakatime" rel="noopener noreferrer"&gt;Wakatime&lt;/a&gt;&lt;/strong&gt;: this one is not for everyone. Only for the metrics lovers 🙈 As it turns out, there are a lot of metrics lovers among us, developers (shocker): in 2023, more than 500k developers spent a combined 51 million hours programming, all tracked with WakaTime plugins 🤯 — so, if you don’t use it already, give it a try!&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;a href="https://plugins.jetbrains.com/plugin/10080-rainbow-brackets" rel="noopener noreferrer"&gt;Rainbow Bracket&lt;/a&gt;&lt;/strong&gt;: because honestly, who never got crazy trying to find the start and the end of endless divs???&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;a href="https://plugins.jetbrains.com/plugin/20686-prisma-orm" rel="noopener noreferrer"&gt;Prisma ORM&lt;/a&gt;&lt;/strong&gt;: this is obviously if you are using Prisma in your project. I started to experiment with it recently as my data models and data queries to Mongo, it works great. This plugin will make your experience even better as you won’t have to go to your terminal or to the Prisma interface in your browser, no, you’ll be able to interact with Prisma and your backend directly from WebStorm 😎&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/features/copilot" rel="noopener noreferrer"&gt;Github copilot&lt;/a&gt;&lt;/strong&gt;. You can check the github page if you want to know more about its powerful capabilities. Some developers — IMO the hard core developers — will tell you copilot is a bad thing to use, but honestly, it allows me to be much faster and to spend time on the trickier part of the code, not the trivial ones AI can help me with. So, just give it a try and take it with a pinch of salt. You will still be a good developer even if you are using the help of AI ;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;a href="https://plugins.jetbrains.com/plugin/14944-mdx" rel="noopener noreferrer"&gt;MDX&lt;/a&gt;&lt;/strong&gt;: not a must, but very convenient if you are using this format that combines Markdown and Javascript. It is especially useful if you want to write markdown inside React components since it allows to write JSX in markdown content. This plugin therefore helps me save time thanks to its code completion and syntax highlighting.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And that’s it! I’d love to hear in the comments what plugins do you find the most useful in your projects?&lt;/p&gt;

&lt;p&gt;Happy coding! 🌞&lt;/p&gt;

</description>
      <category>ide</category>
      <category>webstorm</category>
      <category>plugins</category>
      <category>devtips</category>
    </item>
    <item>
      <title>Add storybook to your SvelteKit app</title>
      <dc:creator>Manon</dc:creator>
      <pubDate>Mon, 27 Jun 2022 18:02:52 +0000</pubDate>
      <link>https://forem.com/manonja/add-storybook-to-your-sveltekit-app-49fb</link>
      <guid>https://forem.com/manonja/add-storybook-to-your-sveltekit-app-49fb</guid>
      <description>&lt;p&gt;Pre-requisites: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;have a SvelteKit project. You cannot install Storybook on an empty project. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Step 1: at your root project, run &lt;code&gt;npx storybook init&lt;/code&gt;. During the installation, you will be asked if you want to run the 'eslintPlugin' migration on your project? Say yes. This is needed for the best Storybook experience. &lt;/p&gt;

&lt;p&gt;Step 2: &lt;code&gt;npm run storybook&lt;/code&gt; &lt;br&gt;
You will probably get an &lt;code&gt;[ERR_REQUIRE_ESM]&lt;/code&gt; error, something like this: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4lbt0394a8z5kt1bd05q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4lbt0394a8z5kt1bd05q.png" alt="Image description" width="800" height="33"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Fix: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;in .storybook, rename your main.js file to main.cjs &lt;/li&gt;
&lt;li&gt;in main.cjs file, replace this line &lt;code&gt;"preprocess": require("../svelte.config.js").preprocess&lt;/code&gt; with &lt;code&gt;preprocess: import('../svelte.config.js').preprocess&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Et voila! Enjoy 🙌&lt;/p&gt;

</description>
      <category>svelte</category>
      <category>storybook</category>
      <category>frontend</category>
      <category>tips</category>
    </item>
    <item>
      <title>4 simple steps you can take now to improve your TypeScript codebase</title>
      <dc:creator>Manon</dc:creator>
      <pubDate>Wed, 17 Feb 2021 19:46:39 +0000</pubDate>
      <link>https://forem.com/secfi/4-simple-steps-you-can-take-now-to-improve-your-typescript-codebase-58ca</link>
      <guid>https://forem.com/secfi/4-simple-steps-you-can-take-now-to-improve-your-typescript-codebase-58ca</guid>
      <description>&lt;p&gt;&lt;em&gt;Because in an ideal world, readability and maintainability would be the north star of every programmer.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;TL;DR&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Make your TS Config as strict as possible so you can agree on naming conventions, avoid typing errors, etc&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use a linter and formatter tool so your team can focus on the real deal&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Agree on a project architecture&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Leverage the power of pair programming to solve complex issues&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Don't try to abstract so much that your teammate (and, most likely, your future self) cannot understand your code later. When working within a team, often the most critical issue is to read and understand other people's code. Focusing on readability and maintainability will not only help you read and refactor your code in two months from now, but it will also help the whole team to be more productive, efficient, and, overall, happy!&lt;/p&gt;

&lt;p&gt;Readable and maintainable codebases are also key when it comes to scaling your application. When starting a new project, it is better to start simple and small with strong and clear foundations rather than over-engineering your application without even knowing where your project will be in a few months from now.&lt;/p&gt;

&lt;p&gt;But what can you do to make readability and maintainability your north star?&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Make your TS Config as strict as possible
&lt;/h2&gt;

&lt;p&gt;If you can, make your TS Config strict. You might have tons of errors, to begin with, but this is worth it as you will enjoy all the benefits of better type safety.&lt;br&gt;
Here are some of the most useful rules you can enable in your TSconfig file:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;"strict":&lt;/code&gt; the strict flag will enable a wide range of type checking, therefore, resulting in stronger guarantees of program correctness. If you turn this on, you will enable all of the strict mode family options. If you want to enable only some of the strict family (see below), it is not necessary to enable strict.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;"strictNullChecks":&lt;/code&gt; set this rule to truewill save you a considerable amount of Javascript errors; especially the much-loved runtime error 'undefined' is not a function , frequently caused by bugs in JavaScript code. With strictNullChecksenabled, TypeScript won't allow you to use a variable that is not known to the compiler (an exception is to be made with the use of any typed variables, more on this later).&lt;/p&gt;

&lt;p&gt;&lt;code&gt;"strictBindCallApply"&lt;/code&gt;: this rule is also super useful as it will check that the built-in methods of functions call, bindand apply are correctly invoked.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;"strictFunctionTypes":&lt;/code&gt; if enabled, function parameters are checked more correctly. However, this rule doesn't apply to functions written in the method syntax, only for function syntax.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;"forceConsistentCasingInFilesNames":&lt;/code&gt; enabling this rule will be useful if you are working on a project where developers use different OS because it will prevent issues related to the file casing and how the files are referenced in the code. TypeScript will thus issue an error if a program tries to include a file with a casing different from the casing on disk.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;"noImplicitAny":&lt;/code&gt; TypeScript will issue an error whenever it would have found a type any. This rule is really strict and probably hard to implement in large codebases or codebases transitioning to TypeScript.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;"noImplicitThis":&lt;/code&gt; TypeScript will raise an error if your code has implied any type of "this" expression.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;"noImplicitReturns":&lt;/code&gt; if you enable this rule, TypeScript will check all code paths in a function to ensure they actually return a value.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;"noUnusedParameters":&lt;/code&gt; enabling this will raise errors on unused parameters in functions.&lt;br&gt;
For full reference, you can check the official documentation here.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Use a linter and formatter tool
&lt;/h2&gt;

&lt;p&gt;Why is it so critical to have a TypeScript code that is readable, well-formatted, and clean? Because it will allow programmers to focus on what they do best and enjoy the most: implement business logic, improve performance, enhance the architecture of a codebase, build a UI library… you name it!&lt;br&gt;
Using a linter and formatter tool (ESlint, Prettier…) will provide consistency to your codebase and make your team happier. And, we all know that a happy team is an efficient one! By keeping your TypeScript clean with linters and formatters, you are avoiding long debates among programmers regarding missing semi-colons or indentation (oh, joy!)&lt;/p&gt;

&lt;p&gt;Your codebase will become:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;easier to read and start with for new joiners&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;easier to review&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;easier to refactor&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;a happier place where programmers have fewer frictions&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3. Agree on a project architecture
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;As Daniel Irvine pointed out in &lt;a href="https://dev.to/d_ir/clean-code-dirty-code-human-code-6nm?signin=true"&gt;this article&lt;/a&gt;, 'almost always the biggest problem I see is interpersonal issues that stem from disagreements about project direction and structure.'&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you are working on a solo project or within a team, you will always be rewarded if you agree and follow a clear project structure. This will allow you to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;onboard&lt;/strong&gt; new joiners more easily&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;navigate your project in a &lt;strong&gt;structured and clear way&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;find relevant files faster&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;better refactor&lt;/strong&gt; your code as it will be easier to see the bigger picture within your project&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;overall, &lt;strong&gt;enhance your productivity and happiness&lt;/strong&gt; with working on your project&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  4. Use the power of pair programming to solve complex issues
&lt;/h2&gt;

&lt;p&gt;Why should you consider pairing with a teammate more often? For many good reasons!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;It's &lt;strong&gt;fun and creates bonding&lt;/strong&gt; within a team, which is not to be neglected as it will most likely improve the overall codebase in the long run.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It allows a &lt;strong&gt;faster and better spread of knowledge&lt;/strong&gt; among teams, especially if the programmer leading the session is familiar with a part of the codebase the other teammate is not.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Along with the same idea, pair programming will allow a &lt;strong&gt;better transfer of skills&lt;/strong&gt; towards junior developers as they can pick-up tips and tricks from more experienced developers, leading to faster growth.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Usually, when pair programming, you and your teammate are &lt;strong&gt;programming 'out loud'&lt;/strong&gt;, which ultimately leads to discover hidden items in the code and to a clearer understanding of the complexities.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Thanks for reading, and happy coding! 😀&lt;/p&gt;

</description>
      <category>programming</category>
      <category>typescript</category>
      <category>webdev</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
