<?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>DEV Community: kai belmo</title>
    <description>The latest articles on DEV Community by kai belmo (@b1m0110).</description>
    <link>https://dev.to/b1m0110</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F470222%2F2331d2f0-5904-4aaa-ae78-6362b478047f.jpg</url>
      <title>DEV Community: kai belmo</title>
      <link>https://dev.to/b1m0110</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/b1m0110"/>
    <language>en</language>
    <item>
      <title>AI Can Generate a SaaS Prototype. Building the Product Still Takes Months.</title>
      <dc:creator>kai belmo</dc:creator>
      <pubDate>Tue, 21 Jul 2026 22:38:25 +0000</pubDate>
      <link>https://dev.to/b1m0110/ai-can-generate-a-saas-prototype-building-the-product-still-takes-months-2kpf</link>
      <guid>https://dev.to/b1m0110/ai-can-generate-a-saas-prototype-building-the-product-still-takes-months-2kpf</guid>
      <description>&lt;p&gt;You’ve probably seen posts that make building a SaaS with AI sound almost effortless:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Give Claude one prompt, wait a few hours, and launch.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That wasn’t my experience.&lt;/p&gt;

&lt;p&gt;I used Claude and other AI coding tools while building &lt;a href="https://useinfill.com" rel="noopener noreferrer"&gt;Infill&lt;/a&gt;, and they absolutely helped. I wrote code faster, found bugs sooner, and avoided a lot of repetitive work.&lt;/p&gt;

&lt;p&gt;But the product still took me more than three months to build.&lt;/p&gt;

&lt;p&gt;The reason is simple: generating code was never the hardest part.&lt;/p&gt;

&lt;h2&gt;
  
  
  The First Version Was Easy
&lt;/h2&gt;

&lt;p&gt;Getting an early demo working did not take long.&lt;/p&gt;

&lt;p&gt;Infill is a browser extension that helps users fill repetitive forms. The basic idea sounds straightforward:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Read the fields on the page.&lt;/li&gt;
&lt;li&gt;Match them with information from the user’s profile.&lt;/li&gt;
&lt;li&gt;Fill the form.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;An AI model can help build that prototype quickly.&lt;/p&gt;

&lt;p&gt;The problems start when you ask what happens outside the happy path.&lt;/p&gt;

&lt;p&gt;Websites use strange labels. Some forms are split across multiple pages. Some fields already contain data. Others are hidden, disabled, sensitive, or designed to catch bots.&lt;/p&gt;

&lt;p&gt;Then there are the questions that have nothing to do with generating another component:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What information should be filled automatically?&lt;/li&gt;
&lt;li&gt;What should always require user approval?&lt;/li&gt;
&lt;li&gt;Where should profile data be stored?&lt;/li&gt;
&lt;li&gt;What happens when the AI makes the wrong match?&lt;/li&gt;
&lt;li&gt;How much will every form submission cost?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those decisions became most of the work.&lt;/p&gt;

&lt;h2&gt;
  
  
  Calling an AI Model for Everything Was a Bad Idea
&lt;/h2&gt;

&lt;p&gt;My first instinct was to let an LLM handle all the field matching.&lt;/p&gt;

&lt;p&gt;It looked good in a demo: send the form fields to the model, receive the mappings, and fill the page.&lt;/p&gt;

&lt;p&gt;But that approach would become expensive very quickly.&lt;/p&gt;

&lt;p&gt;Every form would create another API request. Larger forms would use more tokens. More users would mean higher bills and more latency.&lt;/p&gt;

&lt;p&gt;There was also a bigger privacy problem.&lt;/p&gt;

&lt;p&gt;To let the model handle everything, I would need to send form fields and parts of the user’s profile to an external AI provider. Depending on the form, that data could include names, addresses, phone numbers, employment history, financial details, or other sensitive information.&lt;/p&gt;

&lt;p&gt;In other words, I would be exposing far more user data than necessary just to fill a form.&lt;/p&gt;

&lt;p&gt;The product might work, but the economics and privacy model would not.&lt;/p&gt;

&lt;p&gt;So I changed the architecture.&lt;/p&gt;

&lt;p&gt;Infill now tries deterministic matching first. Common fields can be matched locally without an AI call. AI is only an optional fallback for cases where the normal rules are not enough.&lt;/p&gt;

&lt;p&gt;This is less exciting than saying the whole product is powered by an autonomous agent.&lt;/p&gt;

&lt;p&gt;It is also faster, cheaper, more private, and easier to reason about.&lt;/p&gt;

&lt;h2&gt;
  
  
  I Still Write the Important Code Myself
&lt;/h2&gt;

&lt;p&gt;I do not hand the entire codebase to an AI agent and accept whatever it generates.&lt;/p&gt;

&lt;p&gt;For the important parts, I still write the code myself.&lt;/p&gt;

&lt;p&gt;That includes architectural boundaries, design patterns, data flow, privacy rules, sensitive-field handling, and the parts that could become expensive or dangerous if they are implemented badly.&lt;/p&gt;

&lt;p&gt;AI can suggest five different abstractions in a few seconds. It cannot know which one will still make sense six months later.&lt;/p&gt;

&lt;p&gt;It can generate a service, a hook, or a repository pattern. It does not understand the trade-offs of adding another layer to the system unless I give it that context.&lt;/p&gt;

&lt;p&gt;For routine work, AI is great. I use it for scaffolding, repetitive code, tests, refactoring suggestions, and exploring alternatives.&lt;/p&gt;

&lt;p&gt;But for decisions that shape the product, I slow down.&lt;/p&gt;

&lt;p&gt;I draw the boundaries. I choose the patterns. I review how data moves through the system. I decide what must stay local, what can be optional, and what should never be automated.&lt;/p&gt;

&lt;p&gt;The more sensitive the code is, the less comfortable I am treating AI output as a finished answer.&lt;/p&gt;

&lt;p&gt;A generated function can look clean and still leak data, create an expensive API path, hide a race condition, or introduce a pattern that makes the codebase harder to maintain.&lt;/p&gt;

&lt;p&gt;AI can write code quickly.&lt;/p&gt;

&lt;p&gt;I still have to decide whether that code deserves to exist.&lt;/p&gt;

&lt;h2&gt;
  
  
  AI Made Me Faster, Not Finished
&lt;/h2&gt;

&lt;p&gt;AI coding agents were useful throughout the project.&lt;/p&gt;

&lt;p&gt;They helped me explore approaches, generate tests, refactor code, and understand browser-extension issues faster than I could have on my own.&lt;/p&gt;

&lt;p&gt;But they didn’t decide the product architecture for me.&lt;/p&gt;

&lt;p&gt;They didn’t know which trade-offs mattered most. They didn’t know how much risk I was comfortable with, what users would trust, or what my API budget could support.&lt;/p&gt;

&lt;p&gt;And when the generated code was technically correct but wrong for the product, I still had to notice.&lt;/p&gt;

&lt;p&gt;That is the part I think gets lost in the “one-prompt SaaS” conversation.&lt;/p&gt;

&lt;p&gt;AI can help you reach a prototype surprisingly quickly.&lt;/p&gt;

&lt;p&gt;Turning that prototype into something reliable, private, maintainable, and affordable still takes real engineering.&lt;/p&gt;

&lt;p&gt;I’m not saying AI coding agents are overhyped. I use them every day.&lt;/p&gt;

&lt;p&gt;I just don’t think “AI built my SaaS” is the full story.&lt;/p&gt;

&lt;p&gt;A more honest version is:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AI helped me build faster, but I still had to build the product.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can check out Infill here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Website: &lt;a href="https://useinfill.com" rel="noopener noreferrer"&gt;https://useinfill.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Source code: &lt;a href="https://github.com/KaiBelmo/infill" rel="noopener noreferrer"&gt;https://github.com/KaiBelmo/infill&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>saas</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>Debugging with AI: Stop Feeding It Files, Start Feeding It Snapshots</title>
      <dc:creator>kai belmo</dc:creator>
      <pubDate>Mon, 08 Jun 2026 20:17:10 +0000</pubDate>
      <link>https://dev.to/b1m0110/debugging-with-ai-stop-feeding-it-files-start-feeding-it-snapshots-c75</link>
      <guid>https://dev.to/b1m0110/debugging-with-ai-stop-feeding-it-files-start-feeding-it-snapshots-c75</guid>
      <description>&lt;p&gt;AI coding agents are great at reading and understanding code. But debugging? That’s rarely just a code reading problem.&lt;/p&gt;

&lt;p&gt;Most bugs surface because something at &lt;strong&gt;runtime&lt;/strong&gt; didn’t behave: a request payload arrived in an unexpected shape, a condition took the wrong branch, a store dropped a field, or a queue handler mangled the data.&lt;/p&gt;

&lt;p&gt;When that happens, the AI defaults to what it knows best (scanning files, Handlers, services, types, tests, helpers) It builds a theory from static text. Sometimes that works, but it’s slow, token-heavy, and noisy. The model is forced to &lt;em&gt;infer&lt;/em&gt; runtime truth from source code alone, and it often gets it wrong.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What if you could give the AI a clean, structured snapshot of the exact values that mattered?&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The AI agent skill that makes debugging less guessy
&lt;/h2&gt;

&lt;p&gt;That’s exactly why I built the &lt;a href="https://github.com/KaiBelmo/snaplog" rel="noopener noreferrer"&gt;snaplog skill&lt;/a&gt;.&lt;br&gt;
Instead of asking your assistant to guess where the bug lives, the skill teaches it a tiny, repeatable workflow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Describe the bug:
“Actor, trigger, expected state, observed state.”&lt;/li&gt;
&lt;li&gt;The AI identifies the likely boundary:
For example, request input, branch decision, state transition, persistence write, or error path.&lt;/li&gt;
&lt;li&gt;The AI adds one or two temporary &lt;code&gt;snaplog.injectLog()&lt;/code&gt; calls:
Only the variables that matter.&lt;/li&gt;
&lt;li&gt;You reproduce the bug.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;snaplog&lt;/code&gt; writes local structured logs:
Usually under &lt;code&gt;.debug/debug.log&lt;/code&gt; for Node.&lt;/li&gt;
&lt;li&gt;The AI reads the snapshots and reasons from runtime facts:
It no longer has to infer everything from static source code.&lt;/li&gt;
&lt;li&gt;The temporary instrumentation gets removed.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This saves tokens because the AI gets a compact runtime artifact instead of repeatedly searching broad code paths.&lt;/p&gt;
&lt;h2&gt;
  
  
  Under the hood: the library that makes it work
&lt;/h2&gt;

&lt;p&gt;The skill itself is small on purpose. It works through a focused npm package: &lt;a href="https://www.npmjs.com/package/@kaibelmo/snaplog" rel="noopener noreferrer"&gt;&lt;code&gt;@kaibelmo/snaplog&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It’s a local-first TypeScript runtime snapshot debugger that runs in Node.js, browsers, and browser extensions. Think of it as the sweet spot between messy &lt;code&gt;console.log&lt;/code&gt; spam and a full-blown observability platform.&lt;/p&gt;

&lt;p&gt;Here’s what using it looks like:&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createSnaplogClient&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@kaibelmo/snaplog&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createNodeSnaplogTransport&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@kaibelmo/snaplog/node&lt;/span&gt;&lt;span class="dl"&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;snaplog&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createSnaplogClient&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;runtime&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;node&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;checkout/applyDiscount&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;transport&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;createNodeSnaplogTransport&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="na"&gt;serialize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;redactKeys&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;token&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;password&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="nx"&gt;snaplog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;injectLog&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="nx"&gt;cart&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;discount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;finalTotal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;user&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run your reproduction steps, and you get clean, structured logs (default path &lt;code&gt;.debug/debug.log&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"event"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"snapshot"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"variable"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"finalTotal"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;89.99&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"checkout/applyDiscount"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"timestamp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"..."&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The library handles safe serialization, automatic redaction of sensitive keys, simple flow tracking, and multiple storage backends (file logs for Node, extension storage for browsers). It’s deliberately minimal, zero-dependency where possible, and gets out of your way once the bug is fixed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the skill and library work better together
&lt;/h2&gt;

&lt;p&gt;With the &lt;code&gt;snaplog&lt;/code&gt; skill, the AI isn’t adding random logs. It’s placing temporary snapshots at the exact points that matter, then reading the captured values directly.&lt;/p&gt;

&lt;p&gt;Less code scanning. Fewer guesses. Faster debugging.&lt;/p&gt;

&lt;p&gt;Instead of making the model imagine runtime state, you give it the facts.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx skills add KaiBelmo/snaplog
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Github repo: &lt;a href="https://github.com/KaiBelmo/snaplog" rel="noopener noreferrer"&gt;github.com/KaiBelmo/snaplog&lt;/a&gt;  &lt;/p&gt;

</description>
      <category>typescript</category>
      <category>ai</category>
      <category>programming</category>
      <category>agentskills</category>
    </item>
    <item>
      <title>TypeScript: Not Always the Answer</title>
      <dc:creator>kai belmo</dc:creator>
      <pubDate>Thu, 27 Jul 2023 21:03:28 +0000</pubDate>
      <link>https://dev.to/b1m0110/typescript-not-always-the-answer-2e98</link>
      <guid>https://dev.to/b1m0110/typescript-not-always-the-answer-2e98</guid>
      <description>&lt;p&gt;JavaScript is a versatile and dynamic programming language that allows developers to build a wide range of applications. However, its dynamic nature can sometimes lead to errors and bugs that are challenging to detect during development. To address this, developers often turn to type annotations to provide clarity and ensure code correctness. Two popular approaches for adding type annotations to JavaScript code are JSDoc and TypeScript.&lt;/p&gt;

&lt;h3&gt;
  
  
  Understanding JSDoc
&lt;/h3&gt;

&lt;p&gt;JSDoc is a comment syntax that can be used to annotate JavaScript code with type information. JSDoc annotations are not enforced by the JavaScript compiler, but they can be used by linters and IDEs to provide static type checking. &lt;br&gt;
JSDoc annotations are written in the form of @tag, where the tag specifies the type or purpose of the annotated element. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="cm"&gt;/**
 * @type {string}
 */&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;randomestring&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;42&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;JSDoc also supports more complex type annotations, such as custom objects, arrays, and function signatures.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="cm"&gt;/**
 * @typedef {Object} Foo
 * @property {string} bar
 * @property {number} nda
 */&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * @type {Foo[]}
 */&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;randomObj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;bar&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;the answer to life, universe and everything&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;nda&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;bar&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;random string&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;nda&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * @param {Foo} obj
 * @returns {string}
 */&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;randomFunction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;bar&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; is &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;nda&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&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;h3&gt;
  
  
  Understanding TypeScript
&lt;/h3&gt;

&lt;p&gt;TypeScript is JavaScript on steroids, adding optional static typing and other powerful features to the language. It allows developers to write a more strict form of JavaScript that helps write less error-prone code. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;TypeScript needs to be compiled before it can be executed.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Foo&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;bar&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;nda&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="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;randomObj&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Foo&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;bar&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;the answer to life, universe and everything&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;nda&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;bar&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;random string&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;nda&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;randomFunction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Foo&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="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;bar&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; is &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;nda&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&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;h3&gt;
  
  
  JSDoc vs. TypeScript: Choosing the Right Approach
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Scenario #1 If you are using a framework like Next.js or Vue, there is always a build step. Therefore, you can ignore JSDoc and use TypeScript.&lt;/li&gt;
&lt;li&gt;JSDoc is a favorable option over TypeScript in scenarios where faster shipping is crucial due to the absence of compilation steps. Additionally, it proves beneficial when working with third-party JavaScript libraries without TypeScript support, handling small projects or scripts, and when incrementally adding type annotations to existing JavaScript codebases instead of rewriting them in TypeScript.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  useful links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=MJHO6FSioPI"&gt;Rich Harris (creator of Svelte) talks about Typescript and JSdoc.&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>typescript</category>
      <category>jsdoc</category>
      <category>javascript</category>
    </item>
    <item>
      <title>learn recursion: the hard way</title>
      <dc:creator>kai belmo</dc:creator>
      <pubDate>Wed, 10 Nov 2021 18:50:24 +0000</pubDate>
      <link>https://dev.to/b1m0110/learn-recursion-the-hard-way-43d</link>
      <guid>https://dev.to/b1m0110/learn-recursion-the-hard-way-43d</guid>
      <description>&lt;p&gt;"To understand recursion, you must first understand recursion."&lt;br&gt;
this joke is completely wrong because if you want to understand recursion you need to check this &lt;a href="https://dev.to/b1m0110/learn-recursion-the-hard-way-43d"&gt;blog post&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>algorithms</category>
    </item>
  </channel>
</rss>
