<?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: Riccardo Tartaglia</title>
    <description>The latest articles on DEV Community by Riccardo Tartaglia (@argonauta).</description>
    <link>https://dev.to/argonauta</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%2F385259%2F7f67e985-a465-4161-9d38-bbeb730aa907.png</url>
      <title>DEV Community: Riccardo Tartaglia</title>
      <link>https://dev.to/argonauta</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/argonauta"/>
    <language>en</language>
    <item>
      <title>Why We Need a Standard Language for Agentic Workflows (And Why I Built One)</title>
      <dc:creator>Riccardo Tartaglia</dc:creator>
      <pubDate>Fri, 13 Mar 2026 16:19:21 +0000</pubDate>
      <link>https://dev.to/argonauta/why-we-need-a-standard-language-for-agentic-workflows-and-why-i-built-one-138</link>
      <guid>https://dev.to/argonauta/why-we-need-a-standard-language-for-agentic-workflows-and-why-i-built-one-138</guid>
      <description>&lt;p&gt;&lt;em&gt;Everyone is building **multi-agent systems&lt;/em&gt;&lt;em&gt;. Nobody agrees on how to describe them.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;I've been building with &lt;strong&gt;LLMs&lt;/strong&gt; for the past two years. I've used LangChain, CrewAI, AutoGen, and a dozen smaller &lt;strong&gt;AI agent frameworks&lt;/strong&gt;. Every single time, the experience follows the same arc: excitement, followed by a slow descent into configuration hell, &lt;strong&gt;vendor lock-in&lt;/strong&gt;, and code that nobody on my team can actually read without opening a Python debugger.&lt;/p&gt;

&lt;p&gt;At some point, I started asking a different question. Not "which &lt;strong&gt;agent framework&lt;/strong&gt; should I use?" but "why do we keep building frameworks at all?"&lt;/p&gt;

&lt;p&gt;Think about it. When you want to query a database, you don't write a Java class that wraps a PostgreSQL driver that wraps a connection pool that wraps a query builder. You write &lt;strong&gt;SQL&lt;/strong&gt;. A few lines, declarative, portable, readable by literally everyone on the team, from the junior dev to the DBA to the PM who just wants to understand what data we're pulling.&lt;/p&gt;

&lt;p&gt;We never got that for &lt;strong&gt;agentic workflows&lt;/strong&gt;. And I think it's the single biggest bottleneck holding &lt;strong&gt;multi-agent AI systems&lt;/strong&gt; back from real adoption.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Reproducibility Crisis in AI Agent Orchestration
&lt;/h2&gt;

&lt;p&gt;There's a dirty secret in the &lt;strong&gt;AI agent&lt;/strong&gt; space: most &lt;strong&gt;multi-agent workflows are not reproducible&lt;/strong&gt;. Not across teams, not across providers, not even across time.&lt;/p&gt;

&lt;p&gt;You build something in CrewAI. Your colleague prefers LangGraph. Your client uses AutoGen. Each framework has its own way of defining agents, its own execution model, its own opinions about how data flows between steps. The workflow itself, the actual logic of &lt;em&gt;"this agent researches, that agent analyzes, a third one reviews,"&lt;/em&gt; gets buried under layers of SDK boilerplate.&lt;/p&gt;

&lt;p&gt;This means three things. First, you can't &lt;strong&gt;share workflows&lt;/strong&gt; without also sharing your entire stack. Second, &lt;strong&gt;switching LLM providers&lt;/strong&gt; (or even models) requires rewriting code, not just changing a config line. Third, &lt;strong&gt;non-developers are completely locked out&lt;/strong&gt;. Your PM can't read a CrewAI pipeline. Your domain expert can't verify that the &lt;strong&gt;agent flow&lt;/strong&gt; matches what they described in the meeting. The workflow becomes a black box owned by whoever wrote it.&lt;/p&gt;

&lt;p&gt;I kept running into this wall. I'd sketch a &lt;strong&gt;multi-agent flow&lt;/strong&gt; on a whiteboard, everyone would nod, and then translating that whiteboard sketch into running code would take days. The sketch was simple. The code was not. Something was fundamentally wrong with the &lt;strong&gt;abstraction layer&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What SQL Taught Us About Declarative Languages (And We Forgot)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;SQL&lt;/strong&gt; was invented in the 1970s. Before SQL, if you wanted to query data, you wrote procedural code. You iterated over records, applied filters manually, joined tables in loops. It worked, but it was slow to write, hard to read, and impossible to port between database systems.&lt;/p&gt;

&lt;p&gt;SQL changed everything not because it was more powerful than procedural code. It was actually &lt;em&gt;less&lt;/em&gt; powerful. You can't write a web server in SQL. That's the point. It was a constrained, &lt;strong&gt;declarative language&lt;/strong&gt; that did one thing well: describe &lt;em&gt;what&lt;/em&gt; data you want, not &lt;em&gt;how&lt;/em&gt; to get it.&lt;/p&gt;

&lt;p&gt;The consequences were enormous. Suddenly anyone could read a query. DBAs, analysts, product managers. Suddenly queries were portable across databases (mostly). Suddenly tools could optimize execution because the language described &lt;strong&gt;intent, not implementation&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I believe &lt;strong&gt;agentic workflows&lt;/strong&gt; are at the exact same inflection point. We're in the "procedural code" era. Everyone is writing imperative, framework-specific &lt;strong&gt;agent code&lt;/strong&gt;. What we need is the &lt;strong&gt;declarative orchestration layer&lt;/strong&gt;. A language that describes what agents should do and how they coordinate, independent of any runtime, any provider, any programming language.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introducing SLANG: A Declarative Language for Multi-Agent Orchestration
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;SLANG&lt;/strong&gt; stands for &lt;em&gt;Super Language for Agent Negotiation &amp;amp; Governance&lt;/em&gt;. It's a minimal, &lt;strong&gt;declarative meta-language&lt;/strong&gt; for &lt;strong&gt;multi-agent workflows&lt;/strong&gt;. And it fits on a napkin.&lt;/p&gt;

&lt;p&gt;The entire language has &lt;strong&gt;three primitives&lt;/strong&gt;. &lt;code&gt;stake&lt;/code&gt; means "produce something and send it somewhere." &lt;code&gt;await&lt;/code&gt; means "wait until someone sends you something." &lt;code&gt;commit&lt;/code&gt; means "I'm done, here's my result." That's it. Everything else, conditionals, loops, variables, &lt;strong&gt;structured output&lt;/strong&gt;, those are built on top of these three operations.&lt;/p&gt;

&lt;p&gt;Here's what a real &lt;strong&gt;agent workflow&lt;/strong&gt; looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;flow "research" {
  agent Researcher {
    tools: [web_search]
    stake gather(topic: "quantum computing") -&amp;gt; @Analyst
  }
  agent Analyst {
    await data &amp;lt;- @Researcher
    stake analyze(data) -&amp;gt; @out
    commit
  }
  converge when: all_committed
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Read it out loud. The Researcher gathers information about quantum computing and sends it to the Analyst. The Analyst waits for that data, analyzes it, outputs the result, and commits. The flow ends when everyone has committed.&lt;/p&gt;

&lt;p&gt;Your PM can read this. Your designer can read this. &lt;strong&gt;An LLM can read this.&lt;/strong&gt; And more importantly, an LLM can &lt;em&gt;execute&lt;/em&gt; this, with zero tooling, zero installation, zero configuration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Zero-Setup Mode: Run Agent Workflows in Any LLM Chat
&lt;/h2&gt;

&lt;p&gt;Here's the thing I'm most excited about, and the part that took the longest to get right.&lt;/p&gt;

&lt;p&gt;The same &lt;code&gt;.slang&lt;/code&gt; file works in &lt;strong&gt;two completely different ways&lt;/strong&gt;. You can paste it into &lt;strong&gt;ChatGPT&lt;/strong&gt;, &lt;strong&gt;Claude&lt;/strong&gt;, or &lt;strong&gt;Gemini&lt;/strong&gt; with a system prompt, and the &lt;strong&gt;LLM becomes your runtime&lt;/strong&gt;. It reads the flow, simulates each agent, passes data between them, and produces real output. No install. No API key. No SDK. I call this &lt;strong&gt;zero-setup mode&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Or you can run it with the &lt;strong&gt;SLANG CLI&lt;/strong&gt; or &lt;strong&gt;API&lt;/strong&gt;, and you get a full &lt;strong&gt;production runtime&lt;/strong&gt;. &lt;strong&gt;Parallel agent execution&lt;/strong&gt;, real tool handlers, checkpoint and resume, &lt;strong&gt;structured output contracts&lt;/strong&gt;, &lt;strong&gt;deadlock detection&lt;/strong&gt;, and support for &lt;strong&gt;300+ models through OpenRouter&lt;/strong&gt;. Different agents in the same flow can even use &lt;strong&gt;different LLM providers&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The same file. Both ways. &lt;em&gt;Start by prototyping in ChatGPT, move to production when you're ready.&lt;/em&gt; This isn't something you can do with a framework, because a framework is, by definition, tied to a specific runtime. A language isn't.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why JSON and YAML Fail as Agent Workflow Standards
&lt;/h2&gt;

&lt;p&gt;I know what some of you are thinking. &lt;em&gt;"Why not just use JSON or YAML to describe workflows?"&lt;/em&gt; I tried that. Everyone tries that. It doesn't work, and the reason is subtle.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;JSON and YAML are data formats, not languages.&lt;/strong&gt; They don't have semantics. When you write &lt;code&gt;{"action": "research", "send_to": "analyst"}&lt;/code&gt;, that blob means nothing without a runtime that interprets it. And every runtime interprets it differently. You haven't created a standard, you've created a configuration file for one specific tool.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;language&lt;/strong&gt; has grammar. It has a parser that validates structure. It has defined execution semantics. It has error codes and &lt;strong&gt;static analysis&lt;/strong&gt;. SLANG has all of these. You can parse a &lt;code&gt;.slang&lt;/code&gt; file, build a &lt;strong&gt;dependency graph&lt;/strong&gt;, &lt;strong&gt;detect deadlocks&lt;/strong&gt; before running anything, and get &lt;strong&gt;real-time diagnostics&lt;/strong&gt; in your editor through &lt;strong&gt;LSP support&lt;/strong&gt;. Try doing that with a JSON config.&lt;/p&gt;

&lt;p&gt;More importantly, a language is something &lt;strong&gt;LLMs can learn, generate, and reason about&lt;/strong&gt;. SLANG's syntax was designed from day one to be &lt;strong&gt;LLM-native&lt;/strong&gt;. Function names are &lt;em&gt;semantic labels&lt;/em&gt;, not code references. &lt;code&gt;stake gather(topic: "AI trends")&lt;/code&gt; tells the LLM what to do in natural language. The structure tells it how to coordinate. This means you can literally ask an LLM to &lt;em&gt;"write me a SLANG flow that does X,"&lt;/em&gt; and it produces working code. &lt;strong&gt;Text-to-SLANG&lt;/strong&gt; works the same way &lt;strong&gt;text-to-SQL&lt;/strong&gt; works.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lessons From Building an Open Source Agent Language
&lt;/h2&gt;

&lt;p&gt;I shipped the first version of SLANG about six months ago. Since then, I've iterated through seven minor releases, adding &lt;strong&gt;variables&lt;/strong&gt;, &lt;strong&gt;loops&lt;/strong&gt;, &lt;strong&gt;conditionals&lt;/strong&gt;, structured output, &lt;strong&gt;retry logic&lt;/strong&gt;, a &lt;strong&gt;web playground&lt;/strong&gt;, &lt;strong&gt;IDE support&lt;/strong&gt; with full &lt;strong&gt;Language Server Protocol&lt;/strong&gt;, and an &lt;strong&gt;MCP server&lt;/strong&gt; that integrates with &lt;strong&gt;Claude Code&lt;/strong&gt; and &lt;strong&gt;Claude Desktop&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A few lessons stood out.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Constraints are features.&lt;/strong&gt; SLANG is deliberately not Turing-complete. You can't write arbitrary logic in it. That's by design. The limited surface area means the language is easy to learn, easy to parse, and easy for LLMs to generate correctly. Every time I was tempted to add a general-purpose feature, I asked myself: "Can this be handled by the LLM inside a &lt;code&gt;stake&lt;/code&gt; call instead?" The answer was almost always yes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The execution model matters more than syntax.&lt;/strong&gt; The hardest part wasn't designing keywords. It was defining what a "round" means, how &lt;strong&gt;parallel execution&lt;/strong&gt; works, when agents block, how data flows through mailboxes. Getting the execution model right meant that advanced patterns like &lt;strong&gt;iterative review loops&lt;/strong&gt;, competitive analysis, and &lt;strong&gt;hierarchical delegation&lt;/strong&gt; fell out naturally from the three primitives.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Zero-setup mode is the killer feature.&lt;/strong&gt; I originally built it as a demo gimmick. But it turned out to be the thing people use most. Being able to paste a workflow into &lt;em&gt;any&lt;/em&gt; LLM chat and have it execute immediately, that removes every single adoption barrier. No install, no signup, no configuration. Just paste and go. When I see someone go from "what is this" to "this is running" in under sixty seconds, I know the abstraction is working.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Future of Declarative Agent Orchestration
&lt;/h2&gt;

&lt;p&gt;I don't think SLANG is the final answer. I think it's the right question, phrased as code. The question is: &lt;strong&gt;can we separate the &lt;em&gt;description&lt;/em&gt; of what agents should do from the &lt;em&gt;mechanics&lt;/em&gt; of how they do it?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If the answer is yes, and I believe it is, then the implications are significant. &lt;strong&gt;Workflows become shareable artifacts&lt;/strong&gt;, like SQL queries or Docker images. Teams can collaborate on &lt;strong&gt;agent logic&lt;/strong&gt; without agreeing on a tech stack. &lt;strong&gt;LLMs can generate, modify, and optimize workflows&lt;/strong&gt; directly. And the entire ecosystem can move faster because the &lt;strong&gt;orchestration layer is standardized&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SLANG is open source&lt;/strong&gt; and available on npm. You can install it with &lt;code&gt;npm install -g @riktar/slang&lt;/code&gt;, open the &lt;strong&gt;playground&lt;/strong&gt; with &lt;code&gt;slang playground&lt;/code&gt;, or just grab the &lt;strong&gt;zero-setup prompt&lt;/strong&gt; and paste it into your favorite LLM right now. The spec, grammar, and full documentation are all on the &lt;strong&gt;GitHub repo&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I built this because I got tired of rewriting the same &lt;strong&gt;agent coordination logic&lt;/strong&gt; in different frameworks. If you've ever felt that frustration, I think you'll find something useful here.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The SQL of AI agents.&lt;/strong&gt; That's the bet. Let's see where it goes.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;SLANG is **open source&lt;/em&gt;* under MIT license. Star the repo, open issues, contribute. The language is young and there's a lot of surface area to cover. If you're building &lt;strong&gt;multi-agent systems&lt;/strong&gt; and want to help shape what this becomes, I'd love to hear from you.*&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Find everything at: &lt;a href="https://github.com/riktar/slang" rel="noopener noreferrer"&gt;github.com/riktar/slang&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>tooling</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Stop Fighting with NestJS Modules: Meet Rikta</title>
      <dc:creator>Riccardo Tartaglia</dc:creator>
      <pubDate>Mon, 19 Jan 2026 16:45:07 +0000</pubDate>
      <link>https://dev.to/argonauta/stop-fighting-with-nestjs-modules-meet-rikta-39k5</link>
      <guid>https://dev.to/argonauta/stop-fighting-with-nestjs-modules-meet-rikta-39k5</guid>
      <description>&lt;p&gt;You love NestJS. The decorators feel elegant. The structure keeps your codebase clean. TypeScript integration works well.&lt;/p&gt;

&lt;p&gt;Then you add a new service.&lt;/p&gt;

&lt;p&gt;You import it in one module. Export it in another. Inject it somewhere else. Suddenly, you get this error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Nest can't resolve dependencies of the UserService (?). 
Please make sure that the argument at index [0] 
is available in the current context.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sound familiar?&lt;/p&gt;

&lt;h2&gt;
  
  
  The Module Problem
&lt;/h2&gt;

&lt;p&gt;NestJS modules solve a real problem: dependency boundaries. They prevent chaos in large codebases.&lt;/p&gt;

&lt;p&gt;But they come at a cost.&lt;/p&gt;

&lt;p&gt;Every new service requires you to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create the service with &lt;code&gt;@Injectable()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Add it to a module's &lt;code&gt;providers&lt;/code&gt; array&lt;/li&gt;
&lt;li&gt;Add it to the &lt;code&gt;exports&lt;/code&gt; array if other modules need it&lt;/li&gt;
&lt;li&gt;Import the module in every place that uses it&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here's what a typical NestJS module 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="c1"&gt;// user.module.ts&lt;/span&gt;
&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Module&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;imports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nx"&gt;DatabaseModule&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;ConfigModule&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;AuthModule&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;LoggingModule&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;controllers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;UserController&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;providers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nx"&gt;UserService&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;UserRepository&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;UserValidator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;UserMapper&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;UserService&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;UserRepository&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserModule&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is boilerplate. Pure configuration overhead.&lt;/p&gt;

&lt;p&gt;And it grows. Fast.&lt;/p&gt;

&lt;p&gt;A medium-sized app has 20+ modules. Each module has 5-10 providers. You spend more time managing arrays than writing business logic.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The worst part?&lt;/strong&gt; A typo in any array breaks your entire dependency graph. Debugging takes hours.&lt;/p&gt;

&lt;h2&gt;
  
  
  What If You Didn't Need Modules?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://rikta.dev" rel="noopener noreferrer"&gt;Rikta&lt;/a&gt; is a new TypeScript framework built on Fastify. It keeps the parts developers love about NestJS (decorators, DI, structure) and removes the module configuration entirely.&lt;/p&gt;

&lt;p&gt;No &lt;code&gt;imports&lt;/code&gt; arrays.&lt;br&gt;
No &lt;code&gt;exports&lt;/code&gt; arrays.&lt;br&gt;
No &lt;code&gt;providers&lt;/code&gt; arrays.&lt;/p&gt;

&lt;p&gt;Decorate your class. Everything works.&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="c1"&gt;// user.service.ts&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;Injectable&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="s1"&gt;@riktajs/core&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="nd"&gt;Injectable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;getUsers&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="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Alice&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="s1"&gt;Bob&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// user.controller.ts&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;Controller&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Autowired&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="s1"&gt;@riktajs/core&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;UserService&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="s1"&gt;./user.service&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="nd"&gt;Controller&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/users&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserController&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Autowired&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;userService&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;UserService&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="nf"&gt;getUsers&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;userService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getUsers&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;p&gt;That's it. No module file. No registration. Rikta scans your code at startup and resolves dependencies automatically.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Zero-Config Autowiring Works
&lt;/h2&gt;

&lt;p&gt;Rikta uses three mechanisms:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Automatic Discovery&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;At startup, Rikta scans your project for classes decorated with &lt;code&gt;@Controller()&lt;/code&gt; or &lt;code&gt;@Injectable()&lt;/code&gt;. It builds a dependency graph from constructor parameters and &lt;code&gt;@Autowired()&lt;/code&gt; decorators.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Global Provider Registry&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;All providers live in a single registry. Any injectable class is available anywhere in your app. No need to export or import.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Dependency Resolution&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Rikta reads TypeScript metadata (via &lt;code&gt;reflect-metadata&lt;/code&gt;) to understand what each class needs. It creates instances in the correct order and injects them automatically.&lt;/p&gt;

&lt;p&gt;The framework detects circular dependencies during initialization and throws a clear error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Error: Circular dependency detected: 
UserService -&amp;gt; AuthService -&amp;gt; UserService
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No cryptic stack traces. No runtime surprises.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Side-by-Side Comparison
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Creating a new feature in NestJS:&lt;/strong&gt;&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="c1"&gt;// 1. Create the service&lt;/span&gt;
&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Injectable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PaymentService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;configService&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ConfigService&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="c1"&gt;// 2. Create the module&lt;/span&gt;
&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Module&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;imports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;ConfigModule&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;providers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;PaymentService&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;PaymentService&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PaymentModule&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

&lt;span class="c1"&gt;// 3. Import in app.module.ts&lt;/span&gt;
&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Module&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;imports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;PaymentModule&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="cm"&gt;/* ... */&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AppModule&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

&lt;span class="c1"&gt;// 4. Import in any module that needs it&lt;/span&gt;
&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Module&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;imports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;PaymentModule&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;providers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;OrderService&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OrderModule&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Creating the same feature in Rikta:&lt;/strong&gt;&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="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Injectable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PaymentService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Autowired&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;configService&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ConfigService&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;p&gt;Done.&lt;/p&gt;

&lt;h2&gt;
  
  
  Performance Benefits
&lt;/h2&gt;

&lt;p&gt;Rikta uses Fastify as its HTTP layer. Fastify handles up to 30,000 requests per second in benchmarks.&lt;/p&gt;

&lt;p&gt;Benchmark results from the official repository:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Rikta vs NestJS&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Startup time&lt;/td&gt;
&lt;td&gt;43% faster&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GET requests&lt;/td&gt;
&lt;td&gt;41% faster&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;POST requests&lt;/td&gt;
&lt;td&gt;25% faster&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Route parameters&lt;/td&gt;
&lt;td&gt;46% faster&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Rikta adds minimal overhead (2-5%) over vanilla Fastify. You get dependency injection and decorators without sacrificing speed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Built-in Zod Validation
&lt;/h2&gt;

&lt;p&gt;NestJS uses class-validator decorators for validation. This works, but you define types twice: once for TypeScript, once for validation.&lt;/p&gt;

&lt;p&gt;Rikta integrates Zod natively. Define a schema once. Get validation and TypeScript types automatically.&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;Controller&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;z&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="s1"&gt;@riktajs/core&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;CreateUserSchema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;email&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;number&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;optional&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="nd"&gt;Controller&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/users&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserController&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(@&lt;/span&gt;&lt;span class="nd"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;CreateUserSchema&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;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;infer&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;CreateUserSchema&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// 'user' is validated AND typed&lt;/span&gt;
    &lt;span class="c1"&gt;// Invalid requests return 400 automatically&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;created&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;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;p&gt;No duplicate type definitions. No manual error handling for validation failures.&lt;/p&gt;

&lt;h2&gt;
  
  
  When To Use Rikta
&lt;/h2&gt;

&lt;p&gt;Rikta works best for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Startups and MVPs&lt;/strong&gt; where development speed matters&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Small to medium teams&lt;/strong&gt; (1-15 developers)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Microservices&lt;/strong&gt; where each service stays focused&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Developers who know NestJS&lt;/strong&gt; and want less boilerplate&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Consider NestJS if:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You have a large team that needs strict module boundaries&lt;/li&gt;
&lt;li&gt;You require the extensive NestJS ecosystem (specific adapters, plugins)&lt;/li&gt;
&lt;li&gt;Your organization mandates explicit dependency documentation&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;Create a new project in seconds:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx @riktajs/cli new my-app
&lt;span class="nb"&gt;cd &lt;/span&gt;my-app
npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your API runs at &lt;code&gt;http://localhost:3000&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The CLI generates a complete project with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;TypeScript configuration optimized for Rikta&lt;/li&gt;
&lt;li&gt;Example controller with REST endpoints&lt;/li&gt;
&lt;li&gt;Example service with dependency injection&lt;/li&gt;
&lt;li&gt;Hot reload development server&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Documentation&lt;/strong&gt;: &lt;a href="https://rikta.dev" rel="noopener noreferrer"&gt;rikta.dev&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/riktaHQ/rikta.js" rel="noopener noreferrer"&gt;github.com/riktaHQ/rikta.js&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;NPM&lt;/strong&gt;: &lt;a href="https://www.npmjs.com/package/@riktajs/core" rel="noopener noreferrer"&gt;@riktajs/core&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Rikta is MIT licensed and open source.&lt;/p&gt;




&lt;p&gt;Have you tried zero-config frameworks? What do you think about the module vs. autowiring tradeoff? Share your experience in the comments.&lt;/p&gt;

</description>
      <category>nestjs</category>
      <category>typescript</category>
      <category>node</category>
      <category>api</category>
    </item>
    <item>
      <title>How I build Rikta: a Zero-Config TypeScript Backend Framework</title>
      <dc:creator>Riccardo Tartaglia</dc:creator>
      <pubDate>Fri, 09 Jan 2026 16:06:23 +0000</pubDate>
      <link>https://dev.to/argonauta/how-i-build-rikta-a-zero-config-typescript-backend-framework-1ek8</link>
      <guid>https://dev.to/argonauta/how-i-build-rikta-a-zero-config-typescript-backend-framework-1ek8</guid>
      <description>&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Rikta is an open source TypeScript framework that eliminates NestJS "module hell" through automatic dependency injection and decorator-based routing. Built on Fastify, it delivers 32% better performance than NestJS while maintaining full type safety.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub Repository&lt;/strong&gt; &lt;a href="https://github.com/riktaHQ/rikta" rel="noopener noreferrer"&gt;https://github.com/riktaHQ/rikta&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Documentation&lt;/strong&gt; &lt;a href="https://rikta.dev" rel="noopener noreferrer"&gt;https://rikta.dev&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  What is Rikta and Why Does It Exist?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Rikta&lt;/strong&gt; is an open source &lt;em&gt;TypeScript backend framework&lt;/em&gt; designed for developers who want structure without complexity.&lt;/p&gt;

&lt;p&gt;The Node.js ecosystem offers two extremes. On one side, you have &lt;strong&gt;Express&lt;/strong&gt;: minimal, flexible, but unstructured. On the other, &lt;strong&gt;NestJS&lt;/strong&gt;: enterprise-ready, but verbose and configuration-heavy.&lt;/p&gt;

&lt;p&gt;Rikta occupies the middle ground. It provides &lt;em&gt;dependency injection&lt;/em&gt;, &lt;em&gt;decorator-based routing&lt;/em&gt;, and &lt;em&gt;automatic validation&lt;/em&gt; without requiring manual module configuration.&lt;/p&gt;


&lt;h2&gt;
  
  
  The Problem: NestJS Module Hell
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;NestJS&lt;/strong&gt; dominates enterprise Node.js development. It brings Angular-style architecture to the backend: modules, providers, dependency injection, and decorators.&lt;/p&gt;

&lt;p&gt;But developers consistently report the same frustration: &lt;strong&gt;module configuration overhead&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Here is a typical NestJS module:&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="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Module&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;imports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;DatabaseModule&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;AuthModule&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;CacheModule&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;controllers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;UserController&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;providers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;UserService&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;UserRepository&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;UserService&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserModule&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Every service&lt;/strong&gt; needs explicit registration in &lt;code&gt;providers&lt;/code&gt;. &lt;strong&gt;Every cross-module dependency&lt;/strong&gt; requires &lt;code&gt;imports&lt;/code&gt; and &lt;code&gt;exports&lt;/code&gt; arrays. &lt;strong&gt;Circular dependencies&lt;/strong&gt; trigger cryptic error messages.&lt;/p&gt;

&lt;p&gt;The community calls this &lt;em&gt;"Module Hell."&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Common NestJS Pain Points
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Verbose boilerplate&lt;/strong&gt;: Creating a simple service requires touching multiple files&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Circular dependency errors&lt;/strong&gt;: The infamous "Nest can't resolve dependencies" message&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Configuration drift&lt;/strong&gt;: Forgetting to export a service breaks consumers silently&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;forwardRef everywhere&lt;/strong&gt;: Workarounds become the norm, not the exception&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Rikta's Solution: Zero-Config Autowiring
&lt;/h2&gt;

&lt;p&gt;Rikta takes a radically different approach. &lt;strong&gt;You decorate a class, and the framework handles everything else.&lt;/strong&gt;&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="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Injectable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;GreetingService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;getGreeting&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Welcome to Rikta!&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="nd"&gt;Controller&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AppController&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Autowired&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;greetingService&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;GreetingService&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nf"&gt;index&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="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;greetingService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getGreeting&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;p&gt;&lt;strong&gt;No module files.&lt;/strong&gt; No imports/exports arrays. No providers configuration.&lt;/p&gt;

&lt;p&gt;The framework &lt;em&gt;automatically discovers&lt;/em&gt; decorated classes, &lt;em&gt;resolves dependencies&lt;/em&gt;, and &lt;em&gt;wires everything together&lt;/em&gt; at startup.&lt;/p&gt;




&lt;h2&gt;
  
  
  Technology Stack and Architecture Decisions
&lt;/h2&gt;

&lt;p&gt;Rikta's stack reflects three core goals: &lt;strong&gt;performance&lt;/strong&gt;, &lt;strong&gt;type safety&lt;/strong&gt;, and &lt;strong&gt;developer experience&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Fastify Instead of Express?
&lt;/h3&gt;

&lt;p&gt;Rikta builds on &lt;strong&gt;Fastify&lt;/strong&gt; rather than Express. This choice stems from three factors.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Raw Performance&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Fastify handles up to &lt;em&gt;30,000 requests per second&lt;/em&gt; in benchmarks. Its schema-based validation compiles JSON schemas into optimized functions at startup. Express runs validation at runtime for every request.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Plugin Architecture&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Fastify encapsulates functionality into isolated plugins with their own dependency injection scope. This maps cleanly to Rikta's service architecture.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Native TypeScript Support&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Fastify ships with &lt;em&gt;complete type definitions&lt;/em&gt;. The type system uses generics for request/response typing, eliminating manual type assertions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why TypeScript is Mandatory
&lt;/h3&gt;

&lt;p&gt;TypeScript is &lt;strong&gt;not optional&lt;/strong&gt; in Rikta. The framework uses &lt;em&gt;experimental decorators&lt;/em&gt; and &lt;em&gt;reflect-metadata&lt;/em&gt; for dependency injection.&lt;/p&gt;

&lt;p&gt;This enables powerful features like automatic type inference from Zod schemas:&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="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(@&lt;/span&gt;&lt;span class="nd"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;UserSchema&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;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;infer&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;UserSchema&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// TypeScript infers the user type from the Zod schema&lt;/span&gt;
  &lt;span class="c1"&gt;// Runtime validation happens automatically&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Why Zod for Validation
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Zod&lt;/strong&gt; schemas define both &lt;em&gt;runtime validation rules&lt;/em&gt; and &lt;em&gt;TypeScript types&lt;/em&gt; in a single source of truth.&lt;/p&gt;

&lt;p&gt;This prevents the common problem of validation logic diverging from type definitions. One schema, two purposes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Monorepo Structure
&lt;/h3&gt;

&lt;p&gt;The project uses &lt;strong&gt;npm workspaces&lt;/strong&gt; to manage multiple packages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;packages/
├── core/       # DI, routing, lifecycle
├── cli/        # Project scaffolding
├── swagger/    # OpenAPI documentation
└── typeorm/    # Database integration
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This structure keeps the &lt;strong&gt;core lightweight&lt;/strong&gt;. Developers install only what they need.&lt;/p&gt;




&lt;h2&gt;
  
  
  Architecture Deep Dive
&lt;/h2&gt;

&lt;p&gt;Rikta's architecture centers on three systems: &lt;em&gt;dependency injection&lt;/em&gt;, &lt;em&gt;routing&lt;/em&gt;, and &lt;em&gt;lifecycle management&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  High-Level Architecture Diagram
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌─────────────────────────────────────────────────────────────────┐
│                     APPLICATION BOOTSTRAP                        │
│                        Rikta.create()                           │
└─────────────────────────────────────────────────────────────────┘
                                │
                                ▼
┌─────────────────────────────────────────────────────────────────┐
│                    AUTO-DISCOVERY ENGINE                         │
│                                                                  │
│   File Scan ──▶ Decorator Detection ──▶ Metadata Extraction     │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘
                                │
                                ▼
┌─────────────────────────────────────────────────────────────────┐
│                 DEPENDENCY INJECTION CONTAINER                   │
│                                                                  │
│   ┌───────────┐ ┌───────────┐ ┌───────────┐ ┌───────────┐      │
│   │ Singleton │ │ Transient │ │  Factory  │ │   Value   │      │
│   │   Scope   │ │   Scope   │ │  Provider │ │   Token   │      │
│   └───────────┘ └───────────┘ └───────────┘ └───────────┘      │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘
                                │
                                ▼
┌─────────────────────────────────────────────────────────────────┐
│                      ROUTE REGISTRATION                          │
│                                                                  │
│   Controller Metadata ──▶ Route Building ──▶ Fastify Handler    │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘
                                │
                                ▼
┌─────────────────────────────────────────────────────────────────┐
│                        FASTIFY SERVER                            │
│                 HTTP Request/Response Handling                   │
└─────────────────────────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  How Dependency Injection Works in Rikta
&lt;/h2&gt;

&lt;p&gt;Rikta's DI system uses &lt;strong&gt;TypeScript decorators&lt;/strong&gt; and the &lt;strong&gt;reflect-metadata&lt;/strong&gt; library. Here is how the pieces connect.&lt;/p&gt;

&lt;h3&gt;
  
  
  The @Injectable Decorator
&lt;/h3&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;reflect-metadata&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;INJECTABLE_KEY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;injectable&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Injectable&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;ClassDecorator&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="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Function&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="nb"&gt;Reflect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;defineMetadata&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;INJECTABLE_KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;target&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;p&gt;This decorator &lt;strong&gt;marks a class as a provider&lt;/strong&gt;. The metadata flag tells the container this class should be managed.&lt;/p&gt;

&lt;h3&gt;
  
  
  The @Autowired Decorator
&lt;/h3&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;AUTOWIRED_KEY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;autowired&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Autowired&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;symbol&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;PropertyDecorator&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="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;propertyKey&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;symbol&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;const&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Reflect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getMetadata&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;design:type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;propertyKey&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;autowiredDeps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Reflect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getMetadata&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;AUTOWIRED_KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;target&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="nx"&gt;autowiredDeps&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;propertyKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="nb"&gt;Reflect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;defineMetadata&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;AUTOWIRED_KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;autowiredDeps&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;target&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;p&gt;This decorator &lt;strong&gt;records which properties need injection&lt;/strong&gt;. It captures the property name, the type (from TypeScript's emitted metadata), and an optional token for custom providers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Container Resolution Logic
&lt;/h3&gt;

&lt;p&gt;The container performs &lt;strong&gt;topological sorting&lt;/strong&gt; to resolve dependencies in the correct order.&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;class&lt;/span&gt; &lt;span class="nc"&gt;Container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;providers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;Function&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;symbol&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kr"&gt;any&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;resolve&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&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;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Function&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;symbol&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Return cached instance if exists (Singleton pattern)&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;providers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;target&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;providers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Get constructor parameter types via reflect-metadata&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;paramTypes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Reflect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getMetadata&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;design:paramtypes&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;target&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="c1"&gt;// Resolve each dependency recursively&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dependencies&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;paramTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Function&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;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

    &lt;span class="c1"&gt;// Instantiate with resolved dependencies&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;instance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)(...&lt;/span&gt;&lt;span class="nx"&gt;dependencies&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Handle @Autowired properties&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;autowired&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Reflect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getMetadata&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;AUTOWIRED_KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&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="k"&gt;for &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;dep&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;autowired&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;dep&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;propertyKey&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dep&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;dep&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Cache and return&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;providers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;instance&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;h3&gt;
  
  
  Understanding Provider Scopes
&lt;/h3&gt;

&lt;p&gt;Rikta supports &lt;strong&gt;two scopes&lt;/strong&gt;: Singleton and Transient.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scope&lt;/th&gt;
&lt;th&gt;Behavior&lt;/th&gt;
&lt;th&gt;Use Case&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Singleton&lt;/strong&gt; (default)&lt;/td&gt;
&lt;td&gt;One instance for entire app&lt;/td&gt;
&lt;td&gt;Services, repositories, configs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Transient&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;New instance on every injection&lt;/td&gt;
&lt;td&gt;Request loggers, unique IDs&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Injectable&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;transient&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;RequestLogger&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;requestId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;randomUUID&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&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="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;requestId&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="nx"&gt;message&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;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Routing System Implementation
&lt;/h2&gt;

&lt;p&gt;Rikta's routing wraps Fastify's router with &lt;strong&gt;decorator-based configuration&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Controller and Route Decorators
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Controller&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;prefix&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="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;ClassDecorator&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="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Function&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="nb"&gt;Reflect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;defineMetadata&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;controller:prefix&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;prefix&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nb"&gt;Reflect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;defineMetadata&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;controller&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;target&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="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;path&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="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;MethodDecorator&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="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;propertyKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;descriptor&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;const&lt;/span&gt; &lt;span class="nx"&gt;routes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Reflect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getMetadata&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;routes&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;constructor&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="nx"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GET&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;propertyKey&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="nb"&gt;Reflect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;defineMetadata&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;routes&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;constructor&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;h3&gt;
  
  
  Parameter Extraction
&lt;/h3&gt;

&lt;p&gt;Rikta provides decorators for &lt;strong&gt;automatic request data extraction&lt;/strong&gt;:&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="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/users&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;createUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CreateUserDto&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;role&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;role&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="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Param&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;id&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="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Headers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;authorization&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;auth&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="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Parameters are automatically extracted and injected&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each decorator stores metadata about which request property to extract. The route handler reads this metadata and builds the argument list &lt;em&gt;before&lt;/em&gt; invoking the controller method.&lt;/p&gt;




&lt;h2&gt;
  
  
  Validation with Zod Integration
&lt;/h2&gt;

&lt;p&gt;Rikta integrates &lt;strong&gt;Zod validation&lt;/strong&gt; directly into the request pipeline.&lt;/p&gt;

&lt;h3&gt;
  
  
  Defining Schemas
&lt;/h3&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;z&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="s1"&gt;zod&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;CreateUserSchema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;email&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;optional&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;CreateUserDto&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;infer&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;CreateUserSchema&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Automatic Request Validation
&lt;/h3&gt;

&lt;p&gt;When you pass a Zod schema to the &lt;code&gt;@Body&lt;/code&gt; decorator, Rikta validates incoming requests &lt;strong&gt;automatically&lt;/strong&gt;:&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="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/users&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;createUser&lt;/span&gt;&lt;span class="p"&gt;(@&lt;/span&gt;&lt;span class="nd"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;CreateUserSchema&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;span class="nx"&gt;CreateUserDto&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// If validation fails: 400 Bad Request with error details&lt;/span&gt;
  &lt;span class="c1"&gt;// If validation passes: user is typed and validated&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The framework compiles Zod schemas into &lt;em&gt;Fastify's JSON schema format&lt;/em&gt; at startup. This enables Fastify's optimized validation path.&lt;/p&gt;




&lt;h2&gt;
  
  
  Lifecycle Hooks and Event Bus
&lt;/h2&gt;

&lt;p&gt;Rikta provides hooks for &lt;strong&gt;application lifecycle events&lt;/strong&gt; and an internal event bus for &lt;strong&gt;cross-service communication&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Available Lifecycle Hooks
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Hook&lt;/th&gt;
&lt;th&gt;When It Fires&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;OnProviderInit&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;After provider instantiation, dependencies injected&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;OnApplicationBootstrap&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;After all providers initialized, before server starts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;OnApplicationShutdown&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;When app receives termination signal&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Injectable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DatabaseService&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;OnProviderInit&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;onProviderInit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Database connected&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Event Bus for Loose Coupling
&lt;/h3&gt;

&lt;p&gt;The event bus enables services to communicate &lt;strong&gt;without direct dependencies&lt;/strong&gt;:&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="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Injectable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Autowired&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;eventBus&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;EventBus&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;createUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CreateUserDto&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;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;repository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;eventBus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;emit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user.created&lt;/span&gt;&lt;span class="dl"&gt;'&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;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;user&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="nd"&gt;Injectable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;NotificationService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;OnEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user.created&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;handleUserCreated&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;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendWelcomeEmail&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;span class="nx"&gt;email&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;h2&gt;
  
  
  Performance: Rikta vs NestJS Benchmarks
&lt;/h2&gt;

&lt;p&gt;Rikta targets &lt;strong&gt;NestJS performance as a baseline&lt;/strong&gt;. Here are the benchmark results from the official repository:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Improvement vs NestJS&lt;/th&gt;
&lt;th&gt;Winner&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Startup Time&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;37.7% faster&lt;/td&gt;
&lt;td&gt;Rikta&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;GET Requests&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;44.3% faster&lt;/td&gt;
&lt;td&gt;Rikta&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;POST Requests&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;14.8% faster&lt;/td&gt;
&lt;td&gt;Rikta&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Param Requests&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;36.7% faster&lt;/td&gt;
&lt;td&gt;Rikta&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Average&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;32.0% faster&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Rikta&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Why Rikta is Faster
&lt;/h3&gt;

&lt;p&gt;The performance gains come from &lt;strong&gt;three sources&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Fastify's optimized HTTP handling&lt;/strong&gt; vs Express (NestJS default)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reduced abstraction layers&lt;/strong&gt; in the DI system&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No module resolution overhead&lt;/strong&gt; at runtime&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Production Optimization Tips
&lt;/h3&gt;

&lt;p&gt;For maximum performance in production:&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;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;Rikta&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;silent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;    &lt;span class="c1"&gt;// Disable console output&lt;/span&gt;
  &lt;span class="na"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;    &lt;span class="c1"&gt;// Disable Fastify logging&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Technical Challenges and Solutions
&lt;/h2&gt;

&lt;p&gt;Building Rikta required solving several &lt;strong&gt;non-trivial technical problems&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Challenge 1: TypeScript Decorator Metadata
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; TypeScript's reflect-metadata requires specific compiler settings. Without &lt;code&gt;emitDecoratorMetadata: true&lt;/code&gt;, the framework cannot read constructor parameter types.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt; The CLI scaffolds projects with the correct tsconfig.json:&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;"compilerOptions"&lt;/span&gt;&lt;span class="p"&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;span class="nl"&gt;"experimentalDecorators"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"emitDecoratorMetadata"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&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;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;h3&gt;
  
  
  Challenge 2: Circular Dependencies
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; Unlike NestJS, Rikta has no module boundaries to catch circular dependencies early. Two services injecting each other creates an infinite resolution loop.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt; Rikta detects cycles during container initialization and throws a &lt;strong&gt;clear error message&lt;/strong&gt; identifying the circular path:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Error: Circular dependency detected:
  UserService -&amp;gt; AuthService -&amp;gt; UserService
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Challenge 3: Property Injection Timing
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; The &lt;code&gt;@Autowired&lt;/code&gt; decorator injects into class properties. But TypeScript initializes properties &lt;em&gt;before&lt;/em&gt; the constructor runs. Default values overwrite injected dependencies.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt; Use the &lt;strong&gt;definite assignment assertion&lt;/strong&gt; pattern:&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="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Autowired&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;greetingService&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;GreetingService&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// Note the !&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;!&lt;/code&gt; tells TypeScript the property will be assigned externally.&lt;/p&gt;

&lt;h3&gt;
  
  
  Challenge 4: Auto-Discovery Performance
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; Scanning the filesystem for decorated classes adds startup time. Large projects with thousands of files see noticeable delays.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt; Rikta scans only specific directories (&lt;code&gt;src/controllers&lt;/code&gt;, &lt;code&gt;src/services&lt;/code&gt; by default). Configuration allows customizing scan paths.&lt;/p&gt;




&lt;h2&gt;
  
  
  Best Practices Applied in Rikta
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Single Responsibility for Decorators
&lt;/h3&gt;

&lt;p&gt;Each decorator does &lt;strong&gt;one thing&lt;/strong&gt;. &lt;code&gt;@Injectable&lt;/code&gt; marks providers. &lt;code&gt;@Controller&lt;/code&gt; marks controllers. &lt;code&gt;@Get&lt;/code&gt; defines routes.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Fail Fast on Configuration Errors
&lt;/h3&gt;

&lt;p&gt;Rikta validates configuration &lt;strong&gt;at startup, not at runtime&lt;/strong&gt;. Missing dependencies, invalid schemas, and circular references throw immediately.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Minimal Core, Optional Packages
&lt;/h3&gt;

&lt;p&gt;The core package includes DI, routing, and lifecycle. Database integration, Swagger documentation, and CLI tooling live in &lt;strong&gt;separate packages&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Convention Over Configuration
&lt;/h3&gt;

&lt;p&gt;Default behaviors match common patterns. Controllers live in &lt;code&gt;src/controllers&lt;/code&gt;. Services live in &lt;code&gt;src/services&lt;/code&gt;. The default scope is Singleton.&lt;/p&gt;




&lt;h2&gt;
  
  
  Lessons Learned
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Lesson 1: Module Systems Have Trade-offs
&lt;/h3&gt;

&lt;p&gt;NestJS modules feel verbose, but they provide &lt;strong&gt;explicit dependency boundaries&lt;/strong&gt;. Rikta's autowiring feels magical, but debugging requires understanding the &lt;em&gt;implicit resolution order&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Neither approach is universally better.&lt;/strong&gt; The choice depends on team size and project complexity.&lt;/p&gt;

&lt;h3&gt;
  
  
  Lesson 2: Decorator Magic Needs Documentation
&lt;/h3&gt;

&lt;p&gt;Decorators hide implementation details. This improves developer experience when everything works. It creates confusion when things break.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rikta invests heavily in error messages&lt;/strong&gt; that explain what the framework expected and what it found.&lt;/p&gt;

&lt;h3&gt;
  
  
  Lesson 3: Fastify Plugin Scoping
&lt;/h3&gt;

&lt;p&gt;Fastify plugins have encapsulation by default. A plugin registered in one scope cannot access decorators from another scope.&lt;/p&gt;

&lt;p&gt;Rikta's &lt;strong&gt;global DI container&lt;/strong&gt; works around this, but integrating with Fastify plugins requires careful scoping.&lt;/p&gt;

&lt;h3&gt;
  
  
  Lesson 4: TypeScript Decorators Are Experimental
&lt;/h3&gt;

&lt;p&gt;The decorator specification has changed multiple times. TypeScript 5 introduced the new standard, but Rikta uses &lt;strong&gt;legacy decorator syntax&lt;/strong&gt; for reflect-metadata compatibility.&lt;/p&gt;

&lt;p&gt;This creates migration risk for future TypeScript versions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Lesson 5: Zero-Config Has Limits
&lt;/h3&gt;

&lt;p&gt;Auto-discovery works for &lt;em&gt;small to medium projects&lt;/em&gt;. Enterprise applications with hundreds of services need explicit control over instantiation order, lazy loading, and module boundaries.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rikta provides escape hatches&lt;/strong&gt;, but the core design assumes simpler use cases.&lt;/p&gt;




&lt;h2&gt;
  
  
  Getting Started with Rikta
&lt;/h2&gt;

&lt;p&gt;Install and scaffold a new project in seconds:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx @riktajs/cli new my-app
&lt;span class="nb"&gt;cd &lt;/span&gt;my-app
npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The CLI generates a complete project structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;my-app/
├── src/
│   ├── controllers/
│   │   └── app.controller.ts
│   ├── services/
│   │   └── greeting.service.ts
│   └── main.ts
├── package.json
└── tsconfig.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your API runs at &lt;strong&gt;&lt;a href="http://localhost:3000" rel="noopener noreferrer"&gt;http://localhost:3000&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Rikta&lt;/strong&gt; offers a compelling alternative for TypeScript backend development. It combines the &lt;em&gt;performance of Fastify&lt;/em&gt;, the &lt;em&gt;structure of decorator-based DI&lt;/em&gt;, and the &lt;em&gt;simplicity of zero-config autowiring&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The framework is &lt;strong&gt;MIT licensed&lt;/strong&gt; and welcomes contributions. If you are tired of NestJS module boilerplate but need more structure than Express provides, Rikta deserves your attention.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Star the repository&lt;/strong&gt; on GitHub and try it in your next project.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub Repository&lt;/strong&gt; &lt;a href="https://github.com/riktaHQ/rikta" rel="noopener noreferrer"&gt;https://github.com/riktaHQ/rikta&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Documentation&lt;/strong&gt; &lt;a href="https://rikta.dev" rel="noopener noreferrer"&gt;https://rikta.dev&lt;/a&gt;&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>showdev</category>
      <category>opensource</category>
      <category>node</category>
    </item>
    <item>
      <title>I Used to Work 12-Hour Days. Then I Let AI Do Half My Job.</title>
      <dc:creator>Riccardo Tartaglia</dc:creator>
      <pubDate>Mon, 27 Oct 2025 15:18:05 +0000</pubDate>
      <link>https://dev.to/argonauta/i-used-to-work-12-hour-days-then-i-let-ai-do-half-my-job-1mig</link>
      <guid>https://dev.to/argonauta/i-used-to-work-12-hour-days-then-i-let-ai-do-half-my-job-1mig</guid>
      <description>&lt;p&gt;Last Tuesday at 3 PM, I caught myself staring at my screen. I had written the same authentication middleware for the &lt;em&gt;fourth time&lt;/em&gt; that month. Different project. Same code. Copy, paste, tweak variable names, ship.&lt;/p&gt;

&lt;p&gt;This is what they don't tell you about software development. &lt;strong&gt;You spend 60% of your time rewriting things you already wrote.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I needed help. Not the "read another productivity blog" kind. &lt;em&gt;Real help.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;So I started experimenting with developer productivity AI tools. Here's what I learned after three months of trial and error.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Autocomplete Trap
&lt;/h2&gt;

&lt;p&gt;GitHub Copilot showed up first. I typed a function name and it autocompleted entire blocks. Impressive for a week. Then I noticed something. It suggested code I wrote last year. Good code. Bad code. &lt;em&gt;All code.&lt;/em&gt; The AI didn't judge. It regurgitated.&lt;/p&gt;

&lt;p&gt;I needed something smarter.&lt;/p&gt;

&lt;p&gt;TabNine came next. Better context awareness. It learned my coding style. But it still felt like autocomplete on steroids. I wanted a tool that understood what I was building, not what I was typing.&lt;/p&gt;

&lt;p&gt;Then I found &lt;strong&gt;&lt;a href="https://artiforge.ai" rel="noopener noreferrer"&gt;artiforge.ai&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It’s not an AI coding agent, it is an AI Enhancer&lt;/p&gt;

&lt;p&gt;It works in every IDE that use an MCP client.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Difference
&lt;/h2&gt;

&lt;p&gt;The difference hit me on day one. With one prompt my LLM can retrieve my project documentation. The entire spec. User stories. API contracts. Database schemas. Everything that had a logic sense in the context of the feature.&lt;/p&gt;

&lt;p&gt;I asked it to generate a complete REST API endpoint with validation, error handling, and tests.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It delivered in 90 seconds.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Production-ready code that followed my project's conventions. The error messages matched my existing patterns. The tests covered edge cases I forgot existed.&lt;/p&gt;

&lt;p&gt;I spent the next hour reviewing instead of writing. Found two logical issues. Fixed them. Shipped the feature before lunch.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Mental Shift
&lt;/h2&gt;

&lt;p&gt;Here's what clicked for me. Most AI coding tools treat you like you're writing a novel. One word at a time. &lt;strong&gt;artiforge.ai treats you like an architect.&lt;/strong&gt; You describe the building. It handles the bricks.&lt;/p&gt;

&lt;p&gt;I still use Copilot for quick completions. I still use ChatGPT to explain complex algorithms. But when I need to build something from scratch, I go to artiforge.ai.&lt;/p&gt;

&lt;h2&gt;
  
  
  My New Workflow
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Morning:&lt;/strong&gt; Review tickets and write specs. Feed them to artiforge.ai. Get initial implementations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Midday:&lt;/strong&gt; Review generated code. Refine. Test. Deploy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Afternoon:&lt;/strong&gt; Focus on architecture decisions. Complex business logic. Things that need human judgment.&lt;/p&gt;

&lt;p&gt;My 12-hour days became 8-hour days. My output &lt;em&gt;doubled.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Irony
&lt;/h2&gt;

&lt;p&gt;The irony? I worried AI would make developers obsolete. Instead, it made me better at being a developer. I stopped being a code monkey. I became a code reviewer. A decision maker. An architect.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Your tools define your workflow.&lt;/strong&gt; Choose tools that multiply your skills instead of replacing them.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Real Productivity Hack
&lt;/h2&gt;

&lt;p&gt;I'm not saying artiforge.ai is perfect. No tool is. But it changed how I think about productivity. Stop optimizing for speed. &lt;strong&gt;Start optimizing for leverage.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The best developers aren't the fastest typers. They're the ones who know &lt;em&gt;when&lt;/em&gt; to write code and &lt;em&gt;when&lt;/em&gt; to generate it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try It Yourself
&lt;/h2&gt;

&lt;p&gt;Try artiforge.ai for your next feature. Upload your specs. See what happens. Worst case, you waste 10 minutes. Best case, you get your afternoon back.&lt;/p&gt;

&lt;p&gt;I got mine back. Now I spend it learning Rust instead of rewriting Express middleware.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Worth it.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>ai</category>
      <category>mcp</category>
      <category>development</category>
    </item>
    <item>
      <title>5 Essential MCP Servers Every Developer Should Know</title>
      <dc:creator>Riccardo Tartaglia</dc:creator>
      <pubDate>Fri, 10 Oct 2025 15:51:41 +0000</pubDate>
      <link>https://dev.to/argonauta/5-essential-mcp-servers-every-developer-should-know-8m5</link>
      <guid>https://dev.to/argonauta/5-essential-mcp-servers-every-developer-should-know-8m5</guid>
      <description>&lt;p&gt;I've been experimenting with &lt;strong&gt;Model Context Protocol&lt;/strong&gt; servers for a few months now, and I have to say, they've changed the way I work. If you're not familiar with MCP, think of it as a universal adapter that lets your AI coding assistant actually do things, access your files, push to GitHub, search the web, whatever you need. It's like giving your AI a set of hands instead of just a voice.&lt;/p&gt;

&lt;p&gt;The thing is, there are hundreds of MCP servers out there now, and it's easy to get lost in the noise. So I wanted to share the five that have actually made a difference in my daily workflow. These aren't just cool demos. They're tools I reach for without thinking about it anymore.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Artiforge.ai
&lt;/h2&gt;

&lt;p&gt;Let me start with the one that surprised me the most. &lt;br&gt;
&lt;strong&gt;&lt;a href="https://artiforge.ai/" rel="noopener noreferrer"&gt;Artiforge&lt;/a&gt;&lt;/strong&gt; isn't just another MCP server—it's more like a complete AI development toolkit that happens to work through MCP. I stumbled across it when I was frustrated with context switching between my IDE and various AI tools, and it ended up solving problems I didn't even know I had.&lt;/p&gt;

&lt;p&gt;What makes Artiforge different is that it brings &lt;strong&gt;orchestration directly into your coding environment&lt;/strong&gt;. Instead of bouncing between terminals, documentation, and chat windows, you can plan complex features, generate documentation, and coordinate multiple AI agents from one place. The setup is surprisingly straightforward too, you generate a personal access token from their dashboard, install the MCP server in Cursor or Windsurf, and you're ready to go.&lt;/p&gt;

&lt;p&gt;The two features that made me a believer:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;First&lt;/strong&gt;, the orchestration tool lets you deploy complex features from simple prompts. It creates plans, workflows, and integrates multiple AI agents without you having to manually wire everything together. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Second&lt;/strong&gt;, the documentation generator is incredible. It automatically creates detailed guides and API references from your codebase, which has saved me countless hours of writing docs that nobody wants to write but everyone needs.&lt;/p&gt;

&lt;p&gt;The free trial gives you 15 days with full access and 80 credits to test everything out. I ended up subscribing because the workflow improvements were too valuable to give up.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Filesystem
&lt;/h2&gt;

&lt;p&gt;This one feels obvious once you have it, but working without it now seems ridiculous. The &lt;strong&gt;&lt;a href="https://github.com/modelcontextprotocol/servers/tree/main/src/filesystem" rel="noopener noreferrer"&gt;Filesystem MCP server&lt;/a&gt;&lt;/strong&gt; gives your AI assistant actual access to your local files. Not just reading them and pasting content into a chat, real file operations.&lt;/p&gt;

&lt;p&gt;I use it constantly for things like "organize all the images on my desktop into a new folder" or "find all the TODO comments across my project files." It handles the tedious file management stuff that interrupts your flow when coding. You can also have your AI write content directly to files, which is perfect for generating boilerplate, updating configs, or creating documentation.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;security model is smart&lt;/strong&gt;. You explicitly define which directories the server can access, so there's no risk of your AI wandering off into sensitive folders. It uses the Model Context Protocol's standard approach, you specify allowed directories when you start the server, and everything is sandboxed within those boundaries.&lt;/p&gt;

&lt;p&gt;What I appreciate most: It removes friction from the development process. Instead of copying file paths, opening multiple windows, or context switching to handle basic file operations, your AI just does it. The mental overhead reduction is real.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. GitHub
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;&lt;a href="https://github.com/github/github-mcp-server" rel="noopener noreferrer"&gt;official GitHub MCP server&lt;/a&gt;&lt;/strong&gt; has become essential for how I interact with repositories. It gives your AI direct access to GitHub's platform, so you can manage issues, review pull requests, and analyze code without leaving your conversation.&lt;/p&gt;

&lt;p&gt;GitHub recently rewrote this server in Go and added a bunch of improvements. The remote version uses &lt;strong&gt;OAuth authentication&lt;/strong&gt;, which means you don't need to manage personal access tokens or worry about Docker containers. It's one-click setup in VS Code, and you're connected.&lt;/p&gt;

&lt;p&gt;Two things that make this indispensable:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;First&lt;/strong&gt;, repository intelligence. You can search code, stream files, and open pull requests without cloning anything locally. When I'm reviewing someone's PR or trying to understand a new codebase, being able to ask "show me where authentication is handled" and getting actual code references is invaluable. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Second&lt;/strong&gt;, the CI/CD visibility. Being able to inspect workflow runs, fetch logs, and re-run failed jobs from a chat interface has eliminated so much tab switching and waiting around.&lt;/p&gt;

&lt;p&gt;The server also surfaces &lt;strong&gt;security insights&lt;/strong&gt;, code scanning alerts and Dependabot warnings so you can address vulnerabilities before they become problems. It's the kind of integration that feels like it should have existed years ago.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Sequential Thinking
&lt;/h2&gt;

&lt;p&gt;This one's less about automation and more about problem-solving. The &lt;strong&gt;&lt;a href="https://github.com/modelcontextprotocol/servers/tree/main/src/sequentialthinking" rel="noopener noreferrer"&gt;Sequential Thinking server&lt;/a&gt;&lt;/strong&gt; helps you work through complex problems by breaking them down into discrete thought sequences. It's particularly useful when you're debugging something gnarly or architecting a new feature.&lt;/p&gt;

&lt;p&gt;I find myself using it when I'm stuck on architectural decisions or trying to reason through edge cases. You describe what you're working on, and it walks through the problem step by step, exposing assumptions and helping you think more clearly. It's like having a really patient rubber duck that actually talks back.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;dynamic reflection aspect&lt;/strong&gt; is what sets it apart. As you work through a problem, it adjusts its approach based on what's working and what isn't. It doesn't just follow a rigid template, it adapts to how you think and the specific problem you're solving.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Fetch
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;&lt;a href="https://github.com/modelcontextprotocol/servers/tree/main/src/fetch" rel="noopener noreferrer"&gt;Fetch server&lt;/a&gt;&lt;/strong&gt; does one thing exceptionally well: it grabs web content and converts it into something your AI can actually use efficiently. When you need to pull documentation, analyze a competitor's site, or incorporate external content into your workflow, this is what you reach for.&lt;/p&gt;

&lt;p&gt;What makes it valuable is the &lt;strong&gt;conversion process&lt;/strong&gt;. It doesn't just dump raw HTML at your AI. It processes web content into a clean, LLM-friendly format that preserves the important structure while stripping out the noise. This means your AI can actually understand and work with web content instead of getting confused by markup and styling.&lt;/p&gt;

&lt;p&gt;I use it most often when researching APIs or checking documentation. Instead of copy-pasting from a dozen browser tabs, I can just point the server at the URLs I need, and it handles the rest. The time savings add up fast, especially when you're comparing approaches across multiple sources.&lt;/p&gt;

&lt;p&gt;The other win: It respects your context window. By intelligently processing content, it ensures you're not wasting tokens on irrelevant markup, which becomes critical when you're working with multiple sources.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Bigger Picture
&lt;/h2&gt;

&lt;p&gt;MCP servers are still relatively new, but they're quickly becoming the standard way to extend AI capabilities. What I've learned from using these five is that the best tools are the ones that disappear, they solve problems so cleanly that you forget they're even there.&lt;/p&gt;

&lt;p&gt;If you're just getting started with MCP, I'd recommend beginning with &lt;strong&gt;Artiforge&lt;/strong&gt; and the &lt;strong&gt;Filesystem server&lt;/strong&gt;. They'll give you immediate productivity gains without a steep learning curve. From there, add GitHub if you're working with repositories regularly, and Sequential Thinking when you're tackling complex problems.&lt;/p&gt;

&lt;p&gt;The ecosystem is growing fast, and new servers are popping up constantly. But these five have proven themselves in daily use. They're not experimental, they're reliable tools that make development work better.&lt;/p&gt;

&lt;p&gt;The future of development is collaborative, with AI as a genuine partner in the process. &lt;strong&gt;MCP servers are what make that partnership actually work.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>ai</category>
      <category>programming</category>
      <category>development</category>
    </item>
    <item>
      <title>JSX Unchained: Make a template engine without React</title>
      <dc:creator>Riccardo Tartaglia</dc:creator>
      <pubDate>Wed, 18 Oct 2023 14:20:36 +0000</pubDate>
      <link>https://dev.to/argonauta/jsx-unchained-make-a-template-engine-4h56</link>
      <guid>https://dev.to/argonauta/jsx-unchained-make-a-template-engine-4h56</guid>
      <description>&lt;p&gt;&lt;strong&gt;Hello, developer.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Today, let's talk about JSX, the love-hate relationship of all React developers. Many hate it, many love it, but have you ever wondered how you could make the most of the power of JSX outside the usual React context?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Well, you're in the right place!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In the vast world of web development, the use of JSX in combination with React has changed how we create dynamic and responsive user interfaces. It must be admitted that the developer experience (DX) offered by React dominates over other frameworks, and JSX is one of the factors that has contributed to the success of this endeavor.&lt;/p&gt;

&lt;p&gt;However, at times, you might feel the need to free JSX from this tight connection with React, thus opening the doors to new creative possibilities.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's peek behind the scenes.
&lt;/h2&gt;

&lt;p&gt;Here's where the questions arise: how can we use JSX independently, without the weight of React? This article is here to guide you through the construction of a template engine that will allow you to do just that.&lt;/p&gt;

&lt;p&gt;Imagine being able to leverage the powerful syntax of JSX in scenarios outside the traditional framework, customizing how JSX elements are evaluated and rendered (pretty cool, huh?).&lt;/p&gt;

&lt;p&gt;Before diving into the creation of our template engine, let's take a quick look at what's behind the scenes between JSX and React:&lt;/p&gt;

&lt;p&gt;JSX, which stands for JavaScript XML, is a kind of markup language that looks very similar to HTML. In reality, behind a JSX tag, there's the React.createElement function that handles the transformation of components. Yes, JSX tags are actually JavaScript functions (when you've recovered from the shock, keep reading).&lt;/p&gt;

&lt;p&gt;Initially, JSX was designed to be used exclusively with React, but over time, it has evolved more and more to be considered a project on its own.&lt;/p&gt;

&lt;p&gt;Our goal is, therefore, to create a template engine that adapts to our needs using JSX. Whether you're building a lightweight and fast app or exploring unusual scenarios, this template engine will be the key to opening new doors to our creativity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Template Engine Design
&lt;/h2&gt;

&lt;p&gt;Let's start with this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I want to maintain the DX of React and write a core capable of translating my JavaScript functions, enriched with JSX, into a representation of pure HTML.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Imagine being able to define your user interface declaratively and then, with a magical touch, make it ready for action.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;But how do we achieve all this?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Simple, we need a bundler! In particular, in this article, I'll use Webpack, but you can reconstruct everything with Vite, EsBuild, etc.&lt;/p&gt;

&lt;p&gt;I'll try to guide you step by step.&lt;/p&gt;

&lt;p&gt;Let's initialize the project.&lt;/p&gt;

&lt;p&gt;Create a new folder and type:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm init -y&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Done? Great.&lt;/p&gt;

&lt;p&gt;Now we need two things in particular:&lt;/p&gt;

&lt;p&gt;The first thing is to install Webpack, and the second is to use a transpiler to "transform" our JSX into JavaScript objects.&lt;/p&gt;

&lt;p&gt;As for the second point, we'll use Babel, but let's focus on Webpack for now.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm i -D webpack webpack-cli webpack-dev-server html-webpack-plugin&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Great! Now let's install Babel.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm i -D @babel/cli @babel/core @babel/preset-env babel-loader&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Last piece: we need a Babel plugin that allows us to transpile JSX. We'll delve into its usage later.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm i -D @babel/plugin-transform-react-jsx&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now that we've installed all the necessary dependencies, let's add the following scripts to our package.json.&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="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&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;span class="nl"&gt;"test"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"echo &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;Error: no test specified&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt; &amp;amp;&amp;amp; exit 1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"webpack"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"webpack serve --open"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"dev"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"webpack-dev-server --open"&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;Plainly put, these scripts are for running our project and building it if we want to. Now, we need to create our "magic." Thanks to the babel/plugin-transform-react-jsx plugin, we can tell Babel to handle a custom runtime for transpiling JSX.&lt;/p&gt;

&lt;p&gt;Essentially, we will now customize how Babel should "evaluate" JSX expressions. So, in the root of our project, let's create the file &lt;em&gt;jsx-runtime.js&lt;/em&gt;.&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;add&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;parent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;child&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;parent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;child&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;nodeType&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;child&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createTextNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;child&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;appendChild&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;parent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;child&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;child&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;child&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;nestedChild&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;parent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;nestedChild&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="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;parent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;child&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="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;jsx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;props&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;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;rest&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;props&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="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;tag&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;function&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="nf"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;children&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;element&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;for &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;p&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;rest&lt;/span&gt;&lt;span class="p"&gt;)&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;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;on&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;substring&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;p&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="nf"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;jsxs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jsx&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This very minimal runtime allows us to transform our "components" with props into pure HTML, bidding farewell to the Virtual DOM. Consider that we could extend the runtime to handle custom components, directives, or anything else that comes to mind. In short, see it as the foundation of our template engine or a future framework.&lt;/p&gt;

&lt;p&gt;Let's add the last piece of the puzzle: the webpack configuration file. Again, in the root of the project, let's create the &lt;em&gt;webpack.config.js&lt;/em&gt; file.&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;HtmlWebpackPlugin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;html-webpack-plugin&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;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;path&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./src/index.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;production&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;path&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="nx"&gt;__dirname&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/dist`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bundle.js&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="na"&gt;module&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;rules&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="na"&gt;test&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\.(?:&lt;/span&gt;&lt;span class="sr"&gt;js|jsx|mjs|cjs&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="sr"&gt;$/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;exclude&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sr"&gt;/node_modules/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;use&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;loader&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;babel-loader&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;presets&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="s1"&gt;@babel/preset-env&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]],&lt;/span&gt;
            &lt;span class="na"&gt;plugins&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@babel/plugin-transform-react-jsx&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="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="s1"&gt;automatic&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                  &lt;span class="na"&gt;importSource&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;__dirname&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/./&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;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="na"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;extensions&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="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.js&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="s1"&gt;.jsx&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="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;HtmlWebpackPlugin&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./public/index.html&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we look at the module attribute, we find the configuration for Babel and the plugin plugin-transform-react-jsx, which refers to the root of the project to find our custom runtime file.&lt;/p&gt;

&lt;p&gt;Aaaaaand that's it, we're done.&lt;/p&gt;

&lt;p&gt;If you want a working example of what I've described so far, I've prepared a functional project for you on &lt;a href="https://stackblitz.com/edit/jsx-as-template-engine?file=src%2Findex.js" rel="noopener noreferrer"&gt;StackBlitz&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;What's missing? A reactivity system. But that's another story...&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;And so, our journey into the discovery of an independent template engine based on JSX comes to an end. We've explored the reasons behind the need to free JSX from React, delved into the architecture of the template engine, and tackled the challenge of implementing a flexible and powerful templating language.&lt;/p&gt;

&lt;p&gt;With this tool at your disposal, you're now armed with a new perspective in web development. Take a look at the benefits that this freedom can bring to your daily workflow.&lt;/p&gt;

&lt;p&gt;Your feedback is valuable. If you've experimented with the proposed template engine, have questions, or suggestions on how to improve it, feel free to share them in the comments. If the article has been helpful, share it with your developer friends!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>frontend</category>
      <category>javascript</category>
      <category>react</category>
    </item>
    <item>
      <title>React Advanced: Manage Server States in the right way</title>
      <dc:creator>Riccardo Tartaglia</dc:creator>
      <pubDate>Fri, 29 Sep 2023 18:54:42 +0000</pubDate>
      <link>https://dev.to/argonauta/react-advanced-manage-server-states-in-the-right-way-2740</link>
      <guid>https://dev.to/argonauta/react-advanced-manage-server-states-in-the-right-way-2740</guid>
      <description>&lt;p&gt;Hello, developer. Today we'll tackle a crucial topic: managing server states in an advanced React app. No frills, just the essential facts on how to make this aspect work efficiently.&lt;/p&gt;

&lt;h3&gt;
  
  
  React and its Dirty Work
&lt;/h3&gt;

&lt;p&gt;You know how powerful React is in handling the frontend. But now, let's talk about something more substantial: how does React manage data exchange with the backend? The answer? Server states.&lt;/p&gt;

&lt;h3&gt;
  
  
  Connecting the Dots
&lt;/h3&gt;

&lt;p&gt;Server states are the glue that holds together the frontend and backend. Nothing magical, just the need to make these two worlds communicate coherently and without frills.&lt;/p&gt;

&lt;h3&gt;
  
  
  Order in Chaos
&lt;/h3&gt;

&lt;p&gt;Centralization is the key. Imagine having a central place where all the data resides. Sounds neat, right? And that's exactly what you want to avoid chaos when things get more complex.&lt;/p&gt;

&lt;h3&gt;
  
  
  A Bit of Realism
&lt;/h3&gt;

&lt;p&gt;We're not here to tell you fairy tales. Managing server states can be complicated. It's the practical and sometimes challenging side of development. But no need to panic; we'll face the challenges together.&lt;/p&gt;

&lt;h3&gt;
  
  
  Beyond the Basic Concept
&lt;/h3&gt;

&lt;p&gt;We won't stop at defining the basic concept. We want to equip you with tools to go beyond, to tackle complex scenarios, and enhance your application.&lt;/p&gt;

&lt;p&gt;So, enough talk. We're here to handle the dirty work and give you the information you need to make server states work smoothly in React. Ready to dive into the details? Let's get to it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Role of Server States in a React Application
&lt;/h2&gt;

&lt;p&gt;The effective management of server states forms the backbone of an advanced React application. In this chapter, we will delve into the crucial role that server states play in the React development ecosystem.&lt;/p&gt;

&lt;h3&gt;
  
  
  Dynamic Communication
&lt;/h3&gt;

&lt;p&gt;Server states act as a vital bridge between the frontend and backend of an application. They enable dynamic communication, allowing the frontend to efficiently receive and send data to the server. This interaction is essential for real-time and dynamic applications, such as those requiring instant or live updates.&lt;/p&gt;

&lt;h3&gt;
  
  
  Centralization of State
&lt;/h3&gt;

&lt;p&gt;A crucial aspect is the centralization of server states. By maintaining a centralized state, the application reduces the chances of inconsistencies and simplifies data management. This approach promotes a clear and organized structure, making code understanding and maintenance more straightforward.&lt;/p&gt;

&lt;h3&gt;
  
  
  Managing Complexity
&lt;/h3&gt;

&lt;p&gt;In complex projects, manually handling server states can become a challenge. Utilizing tools like Redux or React's Context API helps simplify this management. These libraries provide a structured way to organize states, facilitating their management and manipulation.&lt;/p&gt;

&lt;h3&gt;
  
  
  State Preservation
&lt;/h3&gt;

&lt;p&gt;Once received, server states must be efficiently preserved to ensure a consistent user experience. This may involve caching strategies or local state preservation techniques, thereby reducing the continuous dependency on the server for static data.&lt;/p&gt;

&lt;h3&gt;
  
  
  UI Reactivity
&lt;/h3&gt;

&lt;p&gt;Thanks to server states, the user interface can dynamically react to changes in the server-side state. For example, a real-time chat could instantly update messages without requiring a page reload, thereby enhancing the overall user experience.&lt;/p&gt;

&lt;h3&gt;
  
  
  Reducing Network Traffic
&lt;/h3&gt;

&lt;p&gt;By maintaining a centralized server state, network traffic can be reduced. Instead of constantly requesting data from the server, the application can optimize requests, reducing loading times and improving overall performance.&lt;/p&gt;

&lt;p&gt;In summary, fully understanding and leveraging the role of server states in a React app is crucial for the development of modern and high-performance applications. In the upcoming chapters, we will explore in-depth how to recognize, manage, and address issues arising from poorly managed server states.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Recognize a Server State
&lt;/h2&gt;

&lt;p&gt;Alright, now that we have a good overview of what server states are, it's time to learn how to recognize them when you encounter them in the wild world of React. Don't worry, they're not invisible, just a bit elusive.&lt;/p&gt;

&lt;h3&gt;
  
  
  HTTP Request
&lt;/h3&gt;

&lt;p&gt;One of the most obvious ways to understand that you're dealing with a server state is the good old HTTP smoke signal. When you send requests to the server and receive responses, you're looking at server state traffic. It's like the server sending you a message saying, "Hey, I've got something for you!"&lt;/p&gt;

&lt;h3&gt;
  
  
  State Manipulation in Effects
&lt;/h3&gt;

&lt;p&gt;Whenever you see a &lt;code&gt;useEffect&lt;/code&gt; manipulating data reactively, you're probably playing with a server state. It's like React telling you, "Hold on, I need to sync up with the server."&lt;/p&gt;

&lt;h3&gt;
  
  
  Outdated States
&lt;/h3&gt;

&lt;p&gt;If you have to update data because it became outdated after a user's change, well, maybe that data is coming from a server.&lt;/p&gt;

&lt;p&gt;In essence, recognizing a server state is a bit like learning to read tracks in the desert. There are signs everywhere; you just need to know what to look for. Ready to follow the tracks of server states in your code? Let's track them down!&lt;/p&gt;

&lt;h2&gt;
  
  
  Problems Arising from Poor Management
&lt;/h2&gt;

&lt;p&gt;Now that we've learned how to recognize server states, it's time to tackle the less glamorous part of the equation: what happens when things go wrong. Yes, because even server states can cause trouble, especially if they're not handled with the right dose of attention.&lt;/p&gt;

&lt;h3&gt;
  
  
  Data Inconsistency
&lt;/h3&gt;

&lt;p&gt;Imagine your server state as a group of musicians playing together. If they're not synchronized, you'll have sonic chaos. Similarly, poor management of server states can lead to inconsistent data. One component thinks the state is one way, another thinks it's another, and you end up with a dissonant orchestra.&lt;/p&gt;

&lt;h3&gt;
  
  
  Uncontrolled Complexity
&lt;/h3&gt;

&lt;p&gt;Server states can become monstrous if you don't keep an eye on them. Poor management can lead to uncontrollable complexity. Components start fighting against each other, and your application becomes an intricate jungle of logic hard to navigate.&lt;/p&gt;

&lt;h3&gt;
  
  
  Nightmare Debugging
&lt;/h3&gt;

&lt;p&gt;You know those horror movies where the protagonist tries to escape something but can't because there are No escape routes? Well, imagine having to debug poor state management. It's a bit like being in that movie but without a flashlight.&lt;/p&gt;

&lt;h3&gt;
  
  
  Performance Impact
&lt;/h3&gt;

&lt;p&gt;If you let server states get too comfortable, they can impact performance. Unnecessary requests, too frequent updates, and non-optimized data traffic can bog down your application. It's like driving a Ferrari with the brakes on.&lt;/p&gt;

&lt;h3&gt;
  
  
  UI Fragility
&lt;/h3&gt;

&lt;p&gt;Poor management can make your user interface as fragile as glass. One state update, and your UI falls like a house of cards.&lt;/p&gt;

&lt;h3&gt;
  
  
  Resource Waste
&lt;/h3&gt;

&lt;p&gt;If you don't manage server state well, you'll end up sending unnecessary requests, storing superfluous data, and overall wasting resources. It's like throwing money out the window.&lt;/p&gt;

&lt;p&gt;In short, poor management of server states can lead to a series of problems that no developer wants to face. But that's where we come in. In the next sections, we'll see how to avoid these troubles and make server states work in our favor. Ready to fix those glitches? Let's dive in.&lt;/p&gt;

&lt;h2&gt;
  
  
  Management and Updating of Server States
&lt;/h2&gt;

&lt;p&gt;To effectively handle Server State over time, various React libraries have emerged, excelling in fetching, caching, and accessing server-side application state fragments.&lt;/p&gt;

&lt;p&gt;In this article, I'll show you how TanStack Query (formerly React Query) can come to our rescue (logically, you can use any alternatives you prefer).&lt;/p&gt;

&lt;p&gt;Think of TanStack Query as your personal assistant for managing server states. It simplifies fetching data from the server, keeps it in sync with your local state, and frees you from the headaches of typical HTTP requests.&lt;/p&gt;

&lt;p&gt;Let's see how we use it in action, focusing on the use of the useQuery hook and the creation of a custom hook to handle data fetching.&lt;/p&gt;

&lt;h3&gt;
  
  
  Installation of TanStack Query:
&lt;/h3&gt;

&lt;p&gt;First and foremost, make sure you have TanStack Query installed in your project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i @tanstack/react-query
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can use the &lt;code&gt;useQuery&lt;/code&gt; hook&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&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;useQuery&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="s1"&gt;@tanstack/react-query&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;fetchData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &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;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/data&lt;/span&gt;&lt;span class="dl"&gt;'&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="o"&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;ok&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&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;Errore nel recupero dei dati&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="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&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="nf"&gt;App&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;isLoading&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useQuery&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;myData&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fetchData&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;isLoading&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Loading...&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&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;error&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Error: &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// Now 'data' contain server data.&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, &lt;code&gt;useQuery&lt;/code&gt; intelligently handles data fetching from the server. If the data is loading, it will display a loading message. If there are errors, it will show an error message. Otherwise, you'll have access to the updated data.&lt;/p&gt;

&lt;p&gt;Now, let's see how to build a custom hook that allows us to "recycle" our fetching logic in an optimal way.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&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;useQuery&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="s1"&gt;@tanstack/react-query&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;useDataFetching&lt;/span&gt; &lt;span class="o"&gt;=&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;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;isLoading&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useQuery&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;myData&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fetchData&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="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;isLoading&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;isLoading&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useDataFetching&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;isLoading&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Caricamento...&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&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;error&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Errore: &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;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;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;I dati dal server sono: &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With the custom hook &lt;code&gt;useDataFetching&lt;/code&gt;, you have a more modular structure. You can reuse it in different parts of your application to handle fetching.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let'use the Cache
&lt;/h2&gt;

&lt;p&gt;TanStack Query shines when it comes to cache management too. It uses an intelligent caching system that efficiently stores data, reducing the need for repeated server requests. Let's see how this cache magic works.&lt;/p&gt;

&lt;h3&gt;
  
  
  Automatic Cache
&lt;/h3&gt;

&lt;p&gt;By default, TanStack Query automatically saves the results of queries in a local cache. When you request the same data later on, TanStack Query will return the locally stored data instead of making a new request to the server. This not only improves performance but also reduces the load on the server.&lt;/p&gt;

&lt;h3&gt;
  
  
  Configurable Cache Policies
&lt;/h3&gt;

&lt;p&gt;You can configure cache policies based on your specific needs. For example, you can set the cache to automatically invalidate data after a certain period or after a change in server-side data. TanStack Query gives you control to adapt the cache to the dynamics of your application.&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="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;isLoading&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useQuery&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;myData&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fetchData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;cacheTime&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;60000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Invalid after 60 seconds&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Custom Cache Keys
&lt;/h2&gt;

&lt;p&gt;You can also use custom cache keys to store and retrieve specific data. This is useful when you need to manually manipulate the cache or when working with dynamic data.&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="nf"&gt;useQuery&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;myData&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="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;}],&lt;/span&gt; &lt;span class="nx"&gt;fetchData&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, the cache key becomes &lt;code&gt;['myData', { id: 1 }]&lt;/code&gt;, and you can access the data using this custom key.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cache Clearing
&lt;/h2&gt;

&lt;p&gt;TanStack Query also provides methods to manually clear or invalidate the cache. For instance, you can call &lt;code&gt;queryClient.invalidateQueries('myData')&lt;/code&gt; to force a new request when needed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&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;useQueryClient&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="s1"&gt;@tanstack/react-query&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;ClearCacheButton&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;queryClient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useQueryClient&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;handleClick&lt;/span&gt; &lt;span class="o"&gt;=&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;queryClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;invalidateQueries&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;myData&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="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleClick&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Invalidate Cache&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this way, you have total control over the cache and can tailor it to the specific needs of your application. Tanstack Query makes cache management a smooth and customizable experience. Ready to cache in on this knowledge?&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;p&gt;And with that, we conclude our journey through the intriguing world of server states in React. Now you're armed with knowledge to tackle challenges, manage complexities, and build reactive applications.&lt;/p&gt;

&lt;p&gt;You've learned to recognize server states, use Tanstack Query as your trusted ally, and avoid the pitfalls of poor management. Now it's your turn, developer!&lt;/p&gt;

&lt;p&gt;If you have questions, concerns, or stories to share about server state management, leave a comment below. The community is here to help and share experiences.&lt;/p&gt;

&lt;p&gt;If you found this article helpful, share it with your fellow developers or on social media. Sharing is the key to growing our community and spreading knowledge.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>react</category>
      <category>frontend</category>
    </item>
    <item>
      <title>React Advanced: Decoupling your components in the right way</title>
      <dc:creator>Riccardo Tartaglia</dc:creator>
      <pubDate>Sun, 24 Sep 2023 16:44:56 +0000</pubDate>
      <link>https://dev.to/argonauta/react-advance-decoupling-your-components-in-the-right-way-4pkn</link>
      <guid>https://dev.to/argonauta/react-advance-decoupling-your-components-in-the-right-way-4pkn</guid>
      <description>&lt;p&gt;Every developer's dream is to write less code and, if possible, make it all reusable.&lt;/p&gt;

&lt;p&gt;In React, this translates into knowing how to properly decouple the logic of a component from its presentation.&lt;/p&gt;

&lt;p&gt;Easier said than done, right?&lt;/p&gt;

&lt;p&gt;In this article, I'll show you how to effectively decouple your components to make your code extremely reusable.&lt;br&gt;
Before we get started, let's take a look at the fundamental concept of "coupling."&lt;/p&gt;
&lt;h2&gt;
  
  
  Coupling
&lt;/h2&gt;

&lt;p&gt;In computer science, coupling is a concept that denotes the dependence between two or more components. For instance, if a component &lt;code&gt;A&lt;/code&gt; depends on another component &lt;code&gt;B&lt;/code&gt;, then &lt;code&gt;A&lt;/code&gt; is said to be coupled with &lt;code&gt;B&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Coupling is the enemy of change because it ties together things that can change in parallel. &lt;/p&gt;

&lt;p&gt;This makes it extremely challenging to modify a single point in your application. Touching a single component can introduce anomalies in various parts of the application.&lt;/p&gt;

&lt;p&gt;You must spend time tracking down all the parts that need to be modified, or you'll find yourself wondering why everything has gone haywire.&lt;/p&gt;

&lt;p&gt;If we view a React component as a pure presentation element, we can say that it can be coupled with many things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Business logic that determines its behavior (hooks, custom hooks, etc.).&lt;/li&gt;
&lt;li&gt;External services (APIs, databases, etc.).&lt;/li&gt;
&lt;li&gt;Another React component (for example, a component responsible for managing the state of a form).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This tight coupling, when modified, can lead to unpredictable side effects on other parts of the system.&lt;/p&gt;

&lt;p&gt;Let's take a closer look at this component.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&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;useCustomerHook&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="s1"&gt;./hooks&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;Customer&lt;/span&gt; &lt;span class="o"&gt;=&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;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;surname&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useCustomerHook&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;surname&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;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;p&gt;It all seems fine at first glance, but in reality, we have a problem: this component is coupled with the custom hook useCustomerHook, which retrieves customer data from an external service. Therefore, our Customer component is not a "pure" component because it depends on logic that is not solely related to presenting its UI.&lt;/p&gt;

&lt;p&gt;Now, let's consider that the custom hook useCustomerHook is also used in other components. What can we expect if we decide to modify it? Well, we should brace ourselves for quite a bit of work because we'll have to modify all the components that use it and are coupled with it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Decoupling the Logic of a React Component
&lt;/h2&gt;

&lt;p&gt;Let's revisit the previous example. I mentioned that the Customer component is coupled with the custom hook useCustomerHook, which applies fetching logic to retrieve customer data.&lt;/p&gt;

&lt;p&gt;Now, let's explore how to decouple the logic of this component, so that we can transform it into a pure presentation component.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&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;useCustomerHook&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="s1"&gt;./hooks&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;Customer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;surname&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="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;surname&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;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;CustomerWrapper&lt;/span&gt; &lt;span class="o"&gt;=&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;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;surname&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useCustomerHook&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;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Customer&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;surname&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;surname&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;CustomerWrapper&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, the Customer component is indeed a pure presentation component because it no longer uses useCustomerHook and only handles UI logic.&lt;/p&gt;

&lt;p&gt;I've employed a wrapper component to decouple the logic of the Customer component. This technique is known as Container Components and allows us to modify the UI of our component without worrying about "breaking" the underlying logic.&lt;/p&gt;

&lt;p&gt;Customer now only needs to concern itself with displaying presentation information. All the necessary variables are passed as props, making it easy to nest it anywhere in our code without concerns.&lt;br&gt;
However, I'm still not satisfied for two reasons:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The CustomerWrapper component is still coupled with the custom hook. So, if I decide to modify it, I would still need to modify the wrapper component.&lt;/li&gt;
&lt;li&gt;I had to create an extra component, CustomerWrapper, to decouple the logic, which means I've written a bit more code.
We can address these two issues by using composition.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  Composition
&lt;/h2&gt;

&lt;p&gt;In computer science, composition is a concept that refers to combining two or more elements to create a new one. For example, if we have two functions &lt;code&gt;f&lt;/code&gt; and &lt;code&gt;g&lt;/code&gt;, we can compose them to create a new function &lt;code&gt;h&lt;/code&gt;, which is the composition of &lt;code&gt;f&lt;/code&gt; and &lt;code&gt;g&lt;/code&gt;.&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;f&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&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;g&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&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;h&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;f&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;g&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can apply the same concept to custom hooks as well. In fact, we can compose two or more custom hooks to create a new one.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;useCustomerHook&lt;/span&gt; &lt;span class="o"&gt;=&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;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;surname&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useCustomer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;age&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useCustomerAge&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="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;surname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;age&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;p&gt;In this way, the custom hook useCustomerHook is composed of the custom hooks useCustomer and useCustomerAge.&lt;/p&gt;

&lt;p&gt;By using composition, we can decouple the logic of a React component without having to create a wrapper component. To apply composition conveniently, we use the library &lt;a href="https://github.com/helloitsjoe/react-hooks-compose" rel="noopener noreferrer"&gt;react-hooks-compose&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's see how we can apply composition to our example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;composeHooks&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-hooks-compose&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;useCustomerHook&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="s1"&gt;./hooks&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;Customer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;surname&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="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;surname&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;composeHooks&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;useCustomerHook&lt;/span&gt;&lt;span class="p"&gt;})(&lt;/span&gt;&lt;span class="nx"&gt;Customer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, the Customer component is indeed a pure presentation component. It's not coupled with any custom hooks and only handles UI logic. Furthermore, you didn't have to create any additional components to decouple the logic. In fact, composition allows you to create a cleaner and more readable component.&lt;/p&gt;

&lt;p&gt;Another strength of this technique lies in how easy it makes testing the Customer component. You don't need to worry about testing the business logic; you only need to test the UI logic. Additionally, you can test the custom hooks separately.&lt;/p&gt;

&lt;p&gt;As a final highlight, let's see what happens if you decide to add a new custom hook that adds some logic to the Customer component, such as a custom hook that handles logging customer information.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;composeHooks&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-hooks-compose&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;useCustomerHook&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useLoggerHook&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="s1"&gt;./hooks&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;Customer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;surname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;age&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="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;surname&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;composeHooks&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="nx"&gt;useCustomerHook&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;useLoggerHook&lt;/span&gt;
&lt;span class="p"&gt;})(&lt;/span&gt;&lt;span class="nx"&gt;Customer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Perfect, you've added the custom hook useLoggerHook to the Customer component without having to modify the component itself. &lt;/p&gt;

&lt;p&gt;This is because useLoggerHook was composed with the useCustomerHook.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;p&gt;In this article, we've explored how to decouple the logic of a React component through hook composition, turning it into a pure presentation component. The art of hook composition provides us with a powerful tool to enhance the modularity and maintainability of our React components.&lt;/p&gt;

&lt;p&gt;By clearly separating business logic from presentation, we make our components more readable and easier to test. This methodology promotes code reusability and the scalability of React applications, allowing developers to focus on creating cleaner and more performant components.&lt;/p&gt;

&lt;p&gt;If you have any suggestions or questions on this topic, please feel free to share them in the comments below. And if you found this article helpful, don't forget to share it with your fellow developers!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>react</category>
      <category>programming</category>
    </item>
    <item>
      <title>Uncino 🪝 Fast, tiny and solid hooks system for Javascript and NodeJS</title>
      <dc:creator>Riccardo Tartaglia</dc:creator>
      <pubDate>Wed, 31 Aug 2022 10:48:34 +0000</pubDate>
      <link>https://dev.to/argonauta/uncino-fast-tiny-and-solid-hooks-system-for-javascript-and-nodejs-613</link>
      <guid>https://dev.to/argonauta/uncino-fast-tiny-and-solid-hooks-system-for-javascript-and-nodejs-613</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Uncino is italian word for hook&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://github.com/riktar/uncino" rel="noopener noreferrer"&gt;See on Github&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Do you know Wordpress hooks system? Uncino is a hooks system highly inspired to it!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Async / Await support&lt;/li&gt;
&lt;li&gt;Node or Browser support&lt;/li&gt;
&lt;li&gt;Actions / Hooks system&lt;/li&gt;
&lt;li&gt;Easy to use&lt;/li&gt;
&lt;li&gt;No Dependencies&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Philosophy
&lt;/h2&gt;

&lt;p&gt;Uncino permit to your code to interact/modify another piece of code at specific, pre-defined spots.&lt;/p&gt;

&lt;p&gt;Uncino has two types of hooks: Actions and Hooks. To use either, you need to write a custom function, and then register for a specific action or hook.&lt;/p&gt;

&lt;p&gt;Actions allow you to add data or change how your code operates. Actions will run at a specific point in the execution. Callback functions for Actions can perform some kind of a task, like echoing output to the user or inserting something into the database. Callback functions for an Action do not return anything back to the calling Action hook.&lt;/p&gt;

&lt;p&gt;Hooks give you the ability to change data during the execution of your code. Callback functions for Filters will accept a variable, modify it, and return it. They are meant to work in an isolated manner, and should never have side effects such as affecting global variables and output. Filters expect to have something returned back to them.&lt;/p&gt;

&lt;p&gt;With Uncino you can create your own hook spots so that other developers can extend and modify your code or you can create your pluggable core.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pull Requests?
&lt;/h2&gt;

&lt;p&gt;I'd love them!&lt;/p&gt;

&lt;h2&gt;
  
  
  Comments?
&lt;/h2&gt;

&lt;p&gt;Let's hear them! (The nice ones please!)&lt;/p&gt;

&lt;h2&gt;
  
  
  Me?
&lt;/h2&gt;

&lt;p&gt;In case you're interested I'm @riktarweb&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>node</category>
      <category>opensource</category>
      <category>github</category>
    </item>
    <item>
      <title>React Holmes 🔍 - Elementary State Orchestrator for React</title>
      <dc:creator>Riccardo Tartaglia</dc:creator>
      <pubDate>Fri, 27 May 2022 09:26:50 +0000</pubDate>
      <link>https://dev.to/argonauta/react-holmes-elementary-state-orchestrator-for-react-4djd</link>
      <guid>https://dev.to/argonauta/react-holmes-elementary-state-orchestrator-for-react-4djd</guid>
      <description>&lt;p&gt;React Holmes is a 0 config, fast and elementary state orchestrator for React.&lt;/p&gt;

&lt;p&gt;Holmes has a very minimal API. It is as simple to use as React’s integrated hooks, but all state is globally accessible.&lt;/p&gt;

&lt;p&gt;💡 Easy as React state hooks&lt;/p&gt;

&lt;p&gt;🔄 State synchronization between components&lt;/p&gt;

&lt;p&gt;🛰️ Distributed and not centralized state&lt;/p&gt;

&lt;p&gt;🤯 No mutable objects&lt;/p&gt;

&lt;p&gt;🚀 Fast&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/devx-os/react-holmes" rel="noopener noreferrer"&gt;React Holmes on Github&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Motivation
&lt;/h2&gt;

&lt;p&gt;React components has a built-in state object, where you store property values that belongs to the component.&lt;/p&gt;

&lt;p&gt;When the state object changes, the component re-renders.&lt;/p&gt;

&lt;p&gt;This behaviour has certain limitations:&lt;/p&gt;

&lt;p&gt;Component state can only be shared by pushing it up to the common ancestor, but this might include a huge tree that then needs to re-render.&lt;br&gt;
React-Holmes adopts a new vision when talking about state handling.&lt;/p&gt;

&lt;p&gt;As other state managers use an external single source of truth to hydrate app client on state change, React-Holmes does not create an external store and does not need to wrap your app in a context.&lt;/p&gt;

&lt;p&gt;So, where is the global state?&lt;br&gt;
There is no global state, actually.&lt;br&gt;
The state is decentralized into components themselves.&lt;/p&gt;

&lt;p&gt;The ONLY differences are the hook declared for state management and a key to identify state chunk.&lt;/p&gt;

&lt;p&gt;While to declare a React state we need to declare it as:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const [state, setState] = React.useState('test');
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;with React-Holmes we need to declare it as:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const [state, setState] = useHolmesState('key', 'test');
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;What does useHolmesState do?&lt;br&gt;
When a state is set with useHolmesState, the hook is responsible to set state with React and add some power ups to it.&lt;/p&gt;

&lt;p&gt;In fact, when a component using useHolmesState is mounted, it will create (if not exists) a new RxJs Observable identified by specified key.&lt;/p&gt;

&lt;p&gt;If we register another component with the same key, it will not create another Observable, instead it will subscribe to existing one, allowing access to its value and its callback to mutate the state.&lt;/p&gt;

&lt;p&gt;This allows state handling to be delegated to React itself, guaranteeing reactish updates and shared state too.&lt;/p&gt;

&lt;p&gt;So React-Holmes can be considered a React state orchestrator because its hooks can be used into very small and deeply nested components without performance impacts generated by multiple re-renders.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/devx-os/react-holmes" rel="noopener noreferrer"&gt;React Holmes on Github&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>opensource</category>
      <category>showdev</category>
    </item>
    <item>
      <title>Blur Animation: CSS Transition</title>
      <dc:creator>Riccardo Tartaglia</dc:creator>
      <pubDate>Wed, 29 Dec 2021 11:42:23 +0000</pubDate>
      <link>https://dev.to/argonauta/blur-animation-css-transition-2ndc</link>
      <guid>https://dev.to/argonauta/blur-animation-css-transition-2ndc</guid>
      <description>&lt;p&gt;Little experiment for create a blur movement effect using CSS animation.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/riktar/embed/bdEVPP?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>codepen</category>
      <category>javascript</category>
      <category>css</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>New Skeleton component in windy - React UI Kit based on Tailwind</title>
      <dc:creator>Riccardo Tartaglia</dc:creator>
      <pubDate>Wed, 14 Jul 2021 15:18:03 +0000</pubDate>
      <link>https://dev.to/argonauta/new-skeleton-component-in-windy-react-ui-kit-based-on-tailwind-4741</link>
      <guid>https://dev.to/argonauta/new-skeleton-component-in-windy-react-ui-kit-based-on-tailwind-4741</guid>
      <description>&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%2Fi5eksjubclyqbmyfd166.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%2Fi5eksjubclyqbmyfd166.png" alt="image" width="489" height="102"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hi there, new update from &lt;strong&gt;windy&lt;/strong&gt; - React UI Kit based on Tailwind!&lt;/p&gt;

&lt;p&gt;We have added a new Skeleton component in Windy (&lt;a href="https://windy-docs.vercel.app" rel="noopener noreferrer"&gt;https://windy-docs.vercel.app&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;Let's use it in 5 lines of code!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"w-full"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Skeleton&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"w-3/4 mb-3"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Skeleton&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"mb-3"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Skeleton&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"w-1/2"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you can see other example in &lt;a href="https://windy-docs.vercel.app/docs/components/skeleton" rel="noopener noreferrer"&gt;https://windy-docs.vercel.app/docs/components/skeleton&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I'm working hard to improve windy so every feedback is important. 👨‍💻 Let's try it and let me know 🔥🙏&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>tailwindcss</category>
      <category>react</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
