<?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: Víctor García</title>
    <description>The latest articles on DEV Community by Víctor García (@gc-victor).</description>
    <link>https://dev.to/gc-victor</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%2F1212759%2Ff09fc8ee-fa27-48ab-9b2c-d1b4d102f844.jpg</url>
      <title>DEV Community: Víctor García</title>
      <link>https://dev.to/gc-victor</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/gc-victor"/>
    <language>en</language>
    <item>
      <title>Agent Orchestration in OpenCode</title>
      <dc:creator>Víctor García</dc:creator>
      <pubDate>Wed, 08 Apr 2026 09:06:59 +0000</pubDate>
      <link>https://dev.to/gc-victor/agent-orchestration-in-opencode-3n4k</link>
      <guid>https://dev.to/gc-victor/agent-orchestration-in-opencode-3n4k</guid>
      <description>&lt;p&gt;Most AI tooling talks about "agents" as if they are magic. In practice, the interesting part is not the agent. It is the orchestration layer: who gets to do what, when work is delegated, how permissions are enforced, and how results come back.&lt;/p&gt;

&lt;p&gt;That is where OpenCode gets interesting.&lt;/p&gt;

&lt;p&gt;OpenCode does not treat agents as loose prompts glued onto a model. It treats them as a runtime system. Native agents are defined in code. File-based agents are loaded from Markdown. Both are merged into the same registry, then executed through the same prompt, permission, and session pipeline.&lt;/p&gt;

&lt;p&gt;At the center of that system is the &lt;code&gt;task&lt;/code&gt; tool.&lt;/p&gt;

&lt;p&gt;When one agent delegates work, it does not simply "call another prompt." It creates or resumes a child session, selects a subagent, passes a scoped instruction, and receives a result back in a structured form. That makes delegation session-based, resumable, and inspectable.&lt;/p&gt;

&lt;p&gt;That matters because orchestration is more than routing. It is control.&lt;/p&gt;

&lt;p&gt;Here is the OpenCode model: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Agents live in a shared runtime registry.&lt;/li&gt;
&lt;li&gt;Permissions decide which tools and delegation targets are actually available.&lt;/li&gt;
&lt;li&gt;Prompts shape behavior, but permissions enforce capability.&lt;/li&gt;
&lt;li&gt;Delegation happens through child sessions, not inline prompt chaining.&lt;/li&gt;
&lt;li&gt;The parent agent stays in control while subagents do isolated work.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One of the clearest examples is our &lt;code&gt;Agent Orchestrator&lt;/code&gt;, which is intentionally restricted: it is a primary agent denied direct execution tools like edit, bash, read, glob, and grep. It is allowed to use &lt;code&gt;task&lt;/code&gt;, skills, and todo management—in other words, it is designed to think in terms of routing and coordination, not direct execution.&lt;/p&gt;

&lt;p&gt;That design forces the right behavior.&lt;/p&gt;

&lt;p&gt;The orchestrator does not research on its own. It does not implement on its own. It does not document on its own. It classifies the request, decides whether work should be split, chooses the right specialist, and delegates.&lt;/p&gt;

&lt;p&gt;So who are "we" when we use it?&lt;/p&gt;

&lt;p&gt;We are not a single monolithic agent. We are a coordinated system of specialists.&lt;/p&gt;

&lt;p&gt;The orchestrator hands work to the right subagent for the job:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;exploration agents for codebase discovery and tracing&lt;/li&gt;
&lt;li&gt;librarian agents for reference gathering and documentation lookup&lt;/li&gt;
&lt;li&gt;oracle-style agents for higher-order reasoning and tradeoff analysis&lt;/li&gt;
&lt;li&gt;writer agents for final drafting, rewriting, and polish&lt;/li&gt;
&lt;li&gt;general agents for broader multi-step execution&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is the real value of orchestration. It turns "an AI assistant" into an operating model.&lt;/p&gt;

&lt;p&gt;OpenCode also gets an important architectural detail right: permissions are the control plane. The runtime filters tools before the model even sees them, then checks permissions again at execution time. That means orchestration is not based on trust alone. It is bounded by policy.&lt;/p&gt;

&lt;p&gt;The result is a cleaner division of labor:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;orchestrator&lt;/code&gt; routes&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;explore&lt;/code&gt; and &lt;code&gt;librarian&lt;/code&gt; research&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;build&lt;/code&gt;, &lt;code&gt;general&lt;/code&gt;, &lt;code&gt;dev&lt;/code&gt;, and &lt;code&gt;fixer&lt;/code&gt; implement&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;writer&lt;/code&gt; writes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And because delegated work runs in child sessions, context does not sprawl uncontrollably across every step. The parent can coordinate the workflow without inheriting all the noise of every subtask.&lt;/p&gt;

&lt;p&gt;That is why agent orchestration in OpenCode feels less like prompt engineering and more like systems design.&lt;/p&gt;

&lt;p&gt;It is not about creating one super-agent. It is about building a disciplined network of agents with clear roles, bounded permissions, and explicit delegation paths.&lt;/p&gt;

&lt;p&gt;That is how we use the Agent Orchestrator: as the control layer that decides which specialist should do the work, how tasks should be split, when subtasks should run in parallel, and how results should be recombined into something useful for the user.&lt;/p&gt;

&lt;p&gt;That model is more durable than the "one agent does everything" pattern. It is easier to reason about, easier to extend, and safer to operate.&lt;/p&gt;

&lt;p&gt;And as agentic systems mature, I think that distinction will matter more and more.&lt;/p&gt;

&lt;p&gt;If the first wave of AI products was about generating outputs, the next wave will be about coordinating capabilities.&lt;/p&gt;

&lt;p&gt;OpenCode shows what that can look like in practice.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;References&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://opencode.ai" rel="noopener noreferrer"&gt;OpenCode Site&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/anomalyco/opencode" rel="noopener noreferrer"&gt;OpenCode GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://gist.github.com/gc-victor/873c908e01038d27e4285b45dc1fdda3" rel="noopener noreferrer"&gt;Orchestrator.md&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>opencode</category>
      <category>ai</category>
      <category>programming</category>
    </item>
    <item>
      <title>Server-First Web Component Architecture: SXO + Reactive Component</title>
      <dc:creator>Víctor García</dc:creator>
      <pubDate>Tue, 13 Jan 2026 18:21:25 +0000</pubDate>
      <link>https://dev.to/gc-victor/the-server-first-web-component-architecture-sxo-reactive-components-n4p</link>
      <guid>https://dev.to/gc-victor/the-server-first-web-component-architecture-sxo-reactive-components-n4p</guid>
      <description>&lt;p&gt;Web components offer native UI primitives. However, they often introduce complex lifecycles, Shadow DOM issues, and verbose code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SXO + Reactive Component&lt;/strong&gt; solves this. It combines server-side rendering with vanilla JSX and a signal-based reactive system. You get declarative authoring, instant page loads, and progressive enhancement without hydration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Server-First, Reactivity-Second
&lt;/h2&gt;

&lt;p&gt;SXO inverts the traditional model:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Server&lt;/strong&gt;: Renders semantic HTML wrapped in custom elements (e.g., &lt;code&gt;&amp;lt;product-card&amp;gt;&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Client&lt;/strong&gt;: A lightweight reactive runtime (~4.8KB) binds state and behavior to the existing DOM.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;There is no hydration pass. The HTML is the source of truth.&lt;/p&gt;

&lt;h2&gt;
  
  
  Core Concepts
&lt;/h2&gt;

&lt;p&gt;Reactive Components use &lt;code&gt;$&lt;/code&gt;-prefixed attributes to link HTML to behavior.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;&lt;code&gt;$state="key"&lt;/code&gt;&lt;/strong&gt;: Initializes state from text content. Updates reflect automatically.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;&lt;code&gt;$bind-*="key"&lt;/code&gt;&lt;/strong&gt;: Two-way binds attributes (like &lt;code&gt;value&lt;/code&gt; or &lt;code&gt;checked&lt;/code&gt;) to state.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;&lt;code&gt;$on*="method"&lt;/code&gt;&lt;/strong&gt;: Binds events to client-side handlers.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;&lt;code&gt;define(tag, setup)&lt;/code&gt;&lt;/strong&gt;: Defines client logic, state, effects (&lt;code&gt;$effect&lt;/code&gt;), and events (&lt;code&gt;$on&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Product Card
&lt;/h2&gt;

&lt;p&gt;Lets create a product card with a quantity selector and a "Favorite" toggle.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Server Component (JSX)
&lt;/h3&gt;

&lt;p&gt;Renders accessible HTML on the server. No client-side logic is included here.&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="c1"&gt;// src/components/product-card.jsx&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;ProductCard&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;price&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;image&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;product&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="na"&gt;card&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"card"&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;img&lt;/span&gt; &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;image&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;title&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;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h3&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;title&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;h3&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;price&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="na"&gt;class&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"controls"&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;button&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="na"&gt;onclick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"decrement"&lt;/span&gt; &lt;span class="na"&gt;aria-label&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Decrease"&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;button&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;input&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"number"&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="na"&gt;bind-value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"qty"&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"1"&lt;/span&gt; &lt;span class="na"&gt;min&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"1"&lt;/span&gt; &lt;span class="na"&gt;aria-label&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Qty"&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;button&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="na"&gt;onclick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"increment"&lt;/span&gt; &lt;span class="na"&gt;aria-label&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Increase"&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;button&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;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt;
        &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="na"&gt;onclick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"toggleFavorite"&lt;/span&gt;
        &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="na"&gt;bind-attr&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"favoriteAttrs"&lt;/span&gt;
        &lt;span class="na"&gt;aria-pressed&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"false"&lt;/span&gt;
        &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"btn-icon"&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;button&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;product&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="na"&gt;card&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;h3&gt;
  
  
  2. Client Enhancer
&lt;/h3&gt;

&lt;p&gt;Attaches behavior to the server-rendered markup.&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="c1"&gt;// src/components/product-card.client.js&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;define&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@qery/reactive-component&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nf"&gt;define&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;product-card&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="nx"&gt;$state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;$on&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;$compute&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="c1"&gt;// 1. Initialize State&lt;/span&gt;
  &lt;span class="nx"&gt;$state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;qty&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="nx"&gt;$state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isFavorite&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// 2. Compute aria-pressed attribute declaratively&lt;/span&gt;
  &lt;span class="c1"&gt;//    and falsy values remove them&lt;/span&gt;
  &lt;span class="nf"&gt;$compute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;favoriteAttrs&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;isFavorite&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="nx"&gt;isFavorite&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;aria-pressed&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;isFavorite&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;true&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;false&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="c1"&gt;// 3. Define Actions&lt;/span&gt;
  &lt;span class="nx"&gt;$on&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;increment&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="nx"&gt;$state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;qty&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;$on&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;decrement&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;$state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;qty&lt;/span&gt; &lt;span class="o"&gt;&amp;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;$state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;qty&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="nx"&gt;$on&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toggleFavorite&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;$state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isFavorite&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;$state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isFavorite&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;
  
  
  3. Page Composition
&lt;/h3&gt;

&lt;p&gt;Compose the component in a server route.&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="c1"&gt;// src/pages/products/index.jsx&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;ProductCard&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../../components/product-card.jsx&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="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;ShopPage&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;products&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`
    &amp;lt;!DOCTYPE html&amp;gt;
    &amp;lt;html lang="en"&amp;gt;
      &amp;lt;head&amp;gt;
        &amp;lt;title&amp;gt;Shop&amp;lt;/title&amp;gt;
        &amp;lt;link rel="stylesheet" href="/styles.css"&amp;gt;
      &amp;lt;/head&amp;gt;
      &amp;lt;body&amp;gt;
        &amp;lt;main&amp;gt;
          &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;products&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="nx"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;ProductCard&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;join&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="s2"&gt;
        &amp;lt;/main&amp;gt;
      &amp;lt;/body&amp;gt;
    &amp;lt;/html&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;h2&gt;
  
  
  Key Advantages
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Instant Interaction&lt;/strong&gt;: The UI is visible immediately. No loading spinners or layout shifts.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Simple State&lt;/strong&gt;: Signal-based state management without complex providers.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Zero-Config&lt;/strong&gt;: Automatic bundling of per-route client entries.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://github.com/gc-victor/sxo" rel="noopener noreferrer"&gt;SXO&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://github.com/gc-victor/reactive-component" rel="noopener noreferrer"&gt;Reactive Component&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>architecture</category>
      <category>frontend</category>
      <category>javascript</category>
      <category>performance</category>
    </item>
    <item>
      <title>SXO: Optimized Server-Side JSX. Build Simple. Build Fast</title>
      <dc:creator>Víctor García</dc:creator>
      <pubDate>Sat, 23 Aug 2025 17:09:27 +0000</pubDate>
      <link>https://dev.to/gc-victor/sxo-optimized-server-side-jsx-build-simple-build-fast-p51</link>
      <guid>https://dev.to/gc-victor/sxo-optimized-server-side-jsx-build-simple-build-fast-p51</guid>
      <description>&lt;p&gt;If you're looking to build high-performance websites without the complexity of client-side frameworks, &lt;strong&gt;SXO&lt;/strong&gt; is a server-side JSX framework designed for speed and simplicity. It skips React's overhead, offering a lean alternative for server-rendered content.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SXO delivers:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Composable JSX&lt;/strong&gt; optimized for server rendering.&lt;/li&gt;
&lt;li&gt;  Intuitive, explicit &lt;strong&gt;directory-based routing&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Blazing-fast builds&lt;/strong&gt; powered by &lt;strong&gt;esbuild&lt;/strong&gt; and a &lt;strong&gt;Rust/WASM JSX precompiler&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;  A &lt;strong&gt;unified CLI&lt;/strong&gt; for development, building, and serving.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Predictable output&lt;/strong&gt; with separate client/server bundles and a route manifest.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://github.com/gc-victor/sxo" rel="noopener noreferrer"&gt;GitHub: gc-victor/sxo&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Features &amp;amp; Architecture
&lt;/h2&gt;

&lt;p&gt;SXO combines a powerful toolchain with a simple structure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Routing:&lt;/strong&gt; Define routes with folders. Each &lt;code&gt;index.(jsx|tsx)&lt;/code&gt; file in &lt;code&gt;src/pages&lt;/code&gt; becomes a route, supporting dynamic segments like &lt;code&gt;[slug]&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Pages:&lt;/strong&gt; Each page exports a JSX render function and optional &lt;code&gt;head&lt;/code&gt; metadata for titles, scripts, and styles.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Performance:&lt;/strong&gt; A Rust-powered JSX precompiler and esbuild ensure top-tier build speed.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Reactivity:&lt;/strong&gt; Add partial interactivity with reactive islands (&lt;code&gt;[reactive-component]&lt;/code&gt;) without a full client framework.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;DX:&lt;/strong&gt; The dev server uses SSE for precise hot-replacement, updating only changed fragments without a full refresh.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Project Structure:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;your-app/
├── src/
│   ├── components/     # Optional - @components alias
│   ├── utils/          # Optional - @utils alias
│   ├── middleware.js   # For custom request handling
│   └── pages/
│       ├── index.html  # HTML shell
│       ├── global.css  # Global styles
│       ├── index.jsx   # Route: /
│       └── about/
│           └── index.jsx # Route: /about
└── package.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Build Output:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;dist/client/&lt;/code&gt;: Hashed static assets (CSS, JS).&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;dist/server/&lt;/code&gt;: Server bundles and a &lt;code&gt;routes.json&lt;/code&gt; manifest.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Get Started in Seconds
&lt;/h2&gt;

&lt;p&gt;Begin without installation using &lt;code&gt;npx&lt;/code&gt; or &lt;code&gt;pnpm dlx&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx sxo dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Example Page (&lt;code&gt;src/pages/index.jsx&lt;/code&gt;):&lt;/strong&gt;&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;Page&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@components/Page&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;head&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Home&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt; &lt;span class="c1"&gt;// Injected metadata&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default &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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Page&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;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Welcome to SXO&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&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;Page&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;&lt;strong&gt;Core Commands:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;sxo dev&lt;/code&gt; – Start dev server with hot-reload.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;sxo build&lt;/code&gt; – Create production builds.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;sxo start&lt;/code&gt; – Serve the production build.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;sxo clean&lt;/code&gt; – Remove build artifacts.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Advanced Configuration
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Middleware:&lt;/strong&gt; Add &lt;code&gt;src/middleware.js&lt;/code&gt; to handle logic like authentication, logging, or headers. Export a single function or an array. Changes are reloaded in development.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Custom Paths/Ports:&lt;/strong&gt; Override defaults via CLI flags:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sxo start &lt;span class="nt"&gt;--pages-dir&lt;/span&gt; ./src/pages &lt;span class="nt"&gt;--port&lt;/span&gt; 4011
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why Choose SXO?
&lt;/h2&gt;

&lt;p&gt;SXO is a powerful, minimal foundation for server-rendered sites like blogs, documentation, or landing pages. It offers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Unmatched Build Speed&lt;/strong&gt; from esbuild and Rust.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;A Clean Developer Experience&lt;/strong&gt; with simple conventions and APIs.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Granular Updates&lt;/strong&gt; for rapid iteration in development.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Zero Framework Lock-in&lt;/strong&gt;, allowing you to add reactivity only where needed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s the ideal tool for developers who want the familiar component model of JSX without the overhead and complexity of a full client-side framework.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>rust</category>
      <category>jsx</category>
    </item>
    <item>
      <title>Documentation That Developers Actually Want to Write</title>
      <dc:creator>Víctor García</dc:creator>
      <pubDate>Sun, 09 Mar 2025 14:45:40 +0000</pubDate>
      <link>https://dev.to/gc-victor/documentation-that-developers-actually-want-to-write-33io</link>
      <guid>https://dev.to/gc-victor/documentation-that-developers-actually-want-to-write-33io</guid>
      <description>&lt;p&gt;Documentation is an essential part of software development in the open-source world. We all know it's crucial, yet somehow, it always ends up as a collection of outdated markdown files and half-finished README.md lurking in our repositories. That's exactly why Query Docs exists—not to reinvent documentation but to make it actually work for both contributors and developers.&lt;/p&gt;

&lt;p&gt;I created Query Docs because I was drowning in half-baked documentation solutions that felt like trying to solve a Rubik's Cube blindfolded. The frustration was real: great software deserves great documentation, but the tools to create it often felt like they were working against us.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What do Query Docs do?&lt;/strong&gt; It takes your existing markdown files—the ones you're already writing—and transforms them into a complete documentation site. The kind that doesn't make your users want to file a bug report just to navigate it.&lt;/p&gt;

&lt;p&gt;And no, this isn't another "60-second setup" tool that secretly requires a PhD in configuration files to use properly.&lt;/p&gt;

&lt;p&gt;Here's what you get:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Navigation that doesn't hate your users&lt;/strong&gt;: A clear page hierarchy with intuitive structure (yes, even for complex products)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Search that works&lt;/strong&gt;: Type a term and find relevant results—seems basic, but it's surprisingly rare&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Workflows that don't fight you&lt;/strong&gt;: Your content stays in simple markdown—easy to update, version, and collaborate on&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Full syntax highlighting&lt;/strong&gt;: Code blocks that are readable, with proper language detection&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ready to transform your documentation experience? It takes seconds to get started without the usual headaches:&lt;/p&gt;

&lt;p&gt;1​. Create a new project using the &lt;a href="https://qery.io/docs/cli/create.html" rel="noopener noreferrer"&gt;Query CLI&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;Use either of these commands—whatever works for you:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# With pnpm&lt;/span&gt;
pnpm dlx @qery/query create

&lt;span class="c"&gt;# With npm&lt;/span&gt;
npx @qery/query create
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When prompted, select the &lt;code&gt;docs&lt;/code&gt; project type. This sets up everything with sensible defaults.&lt;/p&gt;

&lt;p&gt;2​. Launch your development server:&lt;/p&gt;

&lt;p&gt;Navigate to your new project directory and run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3​. View your site:&lt;/p&gt;

&lt;p&gt;Open your browser and go to &lt;a href="http://localhost:3000" rel="noopener noreferrer"&gt;http://localhost:3000&lt;/a&gt;. Your starter documentation site is ready for your content.&lt;/p&gt;

&lt;p&gt;Tada!&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/sKHanqScGkk"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Here's where the frustration-free experience really begins. Create a &lt;a href="https://qery.io/docs/modules/documentation.html#summarymd-format" rel="noopener noreferrer"&gt;SUMMARY.md&lt;/a&gt; file—it's like a table of contents that makes sense to humans:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Summary&lt;/span&gt;

&lt;span class="gu"&gt;## Intro Stuff  &lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;What Even Is This?&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;index.md&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; Your elevator pitch  
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;Quick Start&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;getting-started.md&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; The "shut up and let me code" section  

&lt;span class="gu"&gt;## Features  &lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;Feature X&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;features/x.md&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; The thing your VP overpromised to clients  
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;Feature Y&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;features/y.md&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; The thing that actually works  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each link points to a markdown file. Your index.md could be as simple as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Welcome to Our App&lt;/span&gt;

We made a thing! It (probably) won't crash.

&lt;span class="gu"&gt;## What's This For?&lt;/span&gt;

Imagine [insert competitor] but with fewer existential crises during setup.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Query Docs is designed with a simple, logical structure that stays out of your way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src/  
└── docs/   # Your markdown lives here  
└── api/    # Search endpoints  
└── pages/  # Where the server turns MD into HTML  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you organize your content, it creates a file-based routing system that mirrors your documentation's logical structure. The &lt;a href="https://qery.io/docs/modules/documentation.html#generate-documentation" rel="noopener noreferrer"&gt;docs generator&lt;/a&gt; produces JSON files containing all the necessary information—content, navigation links, table of contents—ready for your server to render.&lt;/p&gt;

&lt;p&gt;Query's &lt;a href="https://qery.io/docs/modules/function.html#jsx-serverside" rel="noopener noreferrer"&gt;JSX Server-Side Rendering&lt;/a&gt; lets you build dynamic documentation pages with a component-based architecture—without loading your users' browsers with unnecessary JavaScript. The result? Fast-loading docs that work everywhere, even on that ancient laptop your QA person refuses to upgrade.&lt;/p&gt;

&lt;p&gt;Documentation shouldn't look like it was styled by someone who thinks "UX" is a myth. Query Docs uses Tailwind to make your docs match your brand without requiring design expertise.&lt;/p&gt;

&lt;p&gt;Let's talk about search—what's the point of documentation if no one can find anything? Query Docs pre-builds a search index, so when users type a keyword from your content, they get relevant results. There's no spinning up Elasticsearch, no extra configuration, or third parties—just functional search that understands your content.&lt;/p&gt;

&lt;p&gt;Beyond the basics, Query Docs includes features that solve real documentation problems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Smart navigation&lt;/strong&gt;: Automatically generates previous/following links between pages&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hierarchical TOC&lt;/strong&gt;: Creates structured navigation from your content organization&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Customizable templates&lt;/strong&gt;: Use your own JSX templates for complete control&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Metadata support&lt;/strong&gt;: Add YAML frontmatter for additional page information&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Is It Perfect? Of course not—no documentation system is. However, Query Docs focuses on solving the problems that matter to open-source creators and their users. The goal isn't perfection; it's making documentation less painful and more useful.&lt;/p&gt;

&lt;p&gt;So, should you give Query Docs a try? If you're tired of documentation being the worst part of your development process, absolutely. At worst, you'll save a few hours of frustration. At best, you might—and I say this with cautious optimism—not hate writing docs anymore.&lt;/p&gt;

&lt;p&gt;And that might be the most revolutionary feature of all.&lt;/p&gt;

&lt;h2&gt;
  
  
  Learn More About Query Docs
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://qery.io/docs/" rel="noopener noreferrer"&gt;See it in action&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://qery.io/docs/modules/documentation.html" rel="noopener noreferrer"&gt;Query Docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://qery.io/docs/server/server-docs.html" rel="noopener noreferrer"&gt;Query Docs Server&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Disclaimer&lt;/strong&gt;: As a dyslexic, &lt;a href="https://dev.to/gc-victor/ai-a-game-changing-tool-for-people-with-dyslexia-1mfo"&gt;I rely on AI tools&lt;/a&gt; to help write and organize blog articles. While I review the content, AI helps me articulate my thoughts more clearly.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Reactive Component Hot Reloading with State Preservation</title>
      <dc:creator>Víctor García</dc:creator>
      <pubDate>Tue, 11 Feb 2025 14:30:39 +0000</pubDate>
      <link>https://dev.to/gc-victor/reactive-component-hot-reloading-with-state-preservation-4of1</link>
      <guid>https://dev.to/gc-victor/reactive-component-hot-reloading-with-state-preservation-4of1</guid>
      <description>&lt;p&gt;Modern web development demands creating responsive and fluid user experiences. However, traditional approaches often require a full page refresh to apply code changes, which clears user inputs, authentication data, and navigation history—forcing developers to recreate testing conditions after every update. To overcome these challenges, developers have embraced hot reloading, a technique that updates code in real-time while preserving the application's state, resulting in a more efficient development process.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9bbtbtuhetbwtg5r5jqw.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%2F9bbtbtuhetbwtg5r5jqw.png" alt=" " width="800" height="393"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hot reloading enables developers to see immediate changes in the UI and continue testing without resetting the application. Among the various tools that utilize this capability, Reactive Component is designed to manage its own state and data flow, which makes it well-suited for hot reloading. This component maintains an accurate record of its current state and updates the user interface automatically when changes occur. This built-in capability simplifies tracking and preserving state during code updates. The clear separation of state management within the reactive component ensures that any updates can be applied without disrupting the overall application behavior.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo76romchbstfji4bha0l.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%2Fo76romchbstfji4bha0l.png" alt=" " width="800" height="301"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Building on the robust state management of Reactive Components, the hot reload mechanism continuously monitors source files using Server-Sent Events (SSE). When a modification is detected, the current application state is captured and stored. The updated code is then applied by creating new component instances without interrupting user interactions. Finally, the preserved state is reattached to these new components, ensuring that all user inputs and data persist accurately. This method streamlines updates and enables real-time adjustments without the overhead of rebuilding the entire application state.&lt;/p&gt;

&lt;p&gt;Despite the hot reload mechanism's efficiency, ensuring optimal performance requires further attention to code efficiency. Developers should optimize code to minimize computational overhead during updates. This includes streamlining DOM operations, applying debouncing techniques, and ensuring efficient serialization and deserialization of state data. If issues occur, reviewing state preservation logs and verifying event handler reattachment and property recalculation can help identify and resolve problems.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmrct6p8mh75o5o9780ej.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%2Fmrct6p8mh75o5o9780ej.png" alt=" " width="800" height="287"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With these optimizations in place, hot reloading becomes an indispensable tool for developing complex applications. It allows developers to update styles, animations, or functionality while keeping the current state intact, ensuring that the application displays real-time data and maintains uninterrupted user interactions.&lt;/p&gt;

&lt;p&gt;In summary, Reactive Component hot reloading represents an important advancement in the web development process. Developers can test and iterate quickly on new features and design modifications by enabling updates without losing the application state. This method saves time and supports a more reliable and consistent development experience. As development practices evolve, ensuring effective state preservation will remain fundamental to creating robust web applications.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Explore the &lt;a href="https://github.com/gc-victor/reactive-component" rel="noopener noreferrer"&gt;Reactive Component repository&lt;/a&gt; on GitHub.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;a href="https://www.npmjs.com/package/@qery/reactive-component" rel="noopener noreferrer"&gt;Reactive Component package&lt;/a&gt; on NPM.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Dive directly into the code of the &lt;a href="https://github.com/gc-victor/reactive-component/tree/main/src/pages/hot-reload" rel="noopener noreferrer"&gt;Hot Reload system&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Disclaimer
&lt;/h2&gt;

&lt;p&gt;As a dyslexic, I rely heavily on AI to help write and organize my blog articles. While I review and shape the content, AI helps me write down my thoughts.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/gc-victor/ai-a-game-changing-tool-for-people-with-dyslexia-1mfo"&gt;https://dev.to/gc-victor/ai-a-game-changing-tool-for-people-with-dyslexia-1mfo&lt;/a&gt;&lt;/p&gt;

</description>
      <category>reactive</category>
      <category>reactivecomponent</category>
      <category>webcomponents</category>
      <category>javascript</category>
    </item>
    <item>
      <title>AI: A Game-Changing Tool for People with Dyslexia</title>
      <dc:creator>Víctor García</dc:creator>
      <pubDate>Wed, 15 Jan 2025 10:37:35 +0000</pubDate>
      <link>https://dev.to/gc-victor/ai-a-game-changing-tool-for-people-with-dyslexia-1mfo</link>
      <guid>https://dev.to/gc-victor/ai-a-game-changing-tool-for-people-with-dyslexia-1mfo</guid>
      <description>&lt;p&gt;As someone living with dyslexia, I've always had a complex relationship with writing. While my mind is full of ideas and insights I want to share, transforming those thoughts into coherent written content has been a constant challenge. That's why I want to share how artificial intelligence has become an invaluable tool in my writing process and why it represents a breakthrough for many people with dyslexia who want to express themselves through writing.&lt;/p&gt;

&lt;p&gt;I have always hidden my dyslexia, but I have come to realize that it is a part of who I am. This realization became even more profound when I discovered that my daughter has it, too. I now understand that keeping it hidden isn't helping either of us, and I need to be open to supporting her journey. It has shaped my perspective on the world and how I interact with it. I have learned to embrace my dyslexia as a unique lens through which I view the world, and I am grateful for the insights and creativity it has brought into my life.&lt;/p&gt;

&lt;h2&gt;
  
  
  Living with Dyslexia: More Than Just Spelling Challenges
&lt;/h2&gt;

&lt;p&gt;Before diving into how AI helps, it's important to understand that dyslexia affects more than just spelling. While most people are aware that dyslexia can cause spelling difficulties, fewer understand that it can also affect other critical skills, such as reading comprehension, writing fluency, express themselves clearly, and the ability to organize thoughts on paper. Some of the common challenges we face include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Word Recall&lt;/strong&gt;: Often, we know what we want to say, but finding the right word feels like trying to catch smoke with our hands. The word is floating in our minds but just out of reach.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Spelling Inconsistency&lt;/strong&gt;: The same word might be spelled correctly one minute and incorrectly the next. It's not about memorization but how our brains process and recall spelling patterns.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Organizational Challenges&lt;/strong&gt;: Our thoughts often come in bursts of creativity, but organizing them into a logical flow can feel overwhelming. It's like having all the puzzle pieces but struggling to see how they fit together.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Working Memory Limitations&lt;/strong&gt;: While writing, we might forget the beginning of our sentence by the time we reach the end, making it difficult to maintain coherent thoughts throughout longer pieces.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Time Management&lt;/strong&gt;: Tasks that might take others an hour can take us significantly longer, leading to frustration and sometimes even abandoning writing projects altogether.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Traditional Writing Process: A Mountain to Climb
&lt;/h2&gt;

&lt;p&gt;For years, my writing process involved multiple steps that were both time-consuming and mentally exhausting:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Writing everything down as quickly as possible before the thoughts escaped&lt;/li&gt;
&lt;li&gt;Reviewing and reorganizing the jumbled mess of ideas&lt;/li&gt;
&lt;li&gt;Checking and rechecking spelling&lt;/li&gt;
&lt;li&gt;Having others proofread my work&lt;/li&gt;
&lt;li&gt;Making corrections and starting the process again&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This approach wasn't just inefficient – it was demoralizing. Despite having valuable insights to share, the mechanical aspects of writing often overshadowed the actual content I wanted to convey.&lt;/p&gt;

&lt;h2&gt;
  
  
  Enter AI: A Bridge Between Thoughts and Written Expression
&lt;/h2&gt;

&lt;p&gt;When I started using AI as a writing tool, it felt like finally finding the missing piece of the puzzle. AI doesn't just correct spelling or grammar – it serves as an intelligent partner in the writing process. Here's how it transforms the writing experience for people with dyslexia:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Immediate Feedback and Correction
&lt;/h3&gt;

&lt;p&gt;Instead of writing an entire piece and then facing the daunting task of editing, AI provides real-time suggestions. This immediate feedback helps build confidence and maintains the flow of thoughts without getting caught up in mechanical details.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Organization and Structure
&lt;/h3&gt;

&lt;p&gt;When I share my ideas with AI, even in their raw, unstructured form, it helps organize them into a coherent narrative. It's like having a writing partner who can help arrange my thoughts while preserving my unique voice and perspective.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Word Finding Support
&lt;/h3&gt;

&lt;p&gt;When I struggle to find the right word, I can describe what I'm trying to say, and AI suggests appropriate terms. This feature has saved countless hours of frustrating searching through my mental dictionary.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Consistency in Expression
&lt;/h3&gt;

&lt;p&gt;AI helps maintain consistency throughout longer pieces, which can be particularly challenging for people with dyslexia. It remembers the context and can suggest ways to keep ideas connected and flowing naturally.&lt;/p&gt;

&lt;h2&gt;
  
  
  Breaking Down the Stigma
&lt;/h2&gt;

&lt;p&gt;One of the most critical aspects of using AI for writing is addressing the stigma that sometimes comes with it. Let me be clear: using AI as a writing tool is not cheating or taking shortcuts. It's about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Creating equal opportunities for everyone&lt;/li&gt;
&lt;li&gt;Focusing on the content rather than the mechanics&lt;/li&gt;
&lt;li&gt;Using available tools to express ourselves more effectively&lt;/li&gt;
&lt;li&gt;Maintaining our authentic voice while overcoming technical challenges&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Just as someone who wears glasses isn't "cheating" at seeing, using AI tools isn't cheating at writing. It's about accessing the support we need to express ourselves clearly and effectively.&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Use AI in My Writing Process
&lt;/h2&gt;

&lt;p&gt;My current writing process with AI looks something like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Using System Prompt&lt;/strong&gt;: I provide the AI with a system prompt for writing and let it generate a draft based on the information provided.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Brain Dump&lt;/strong&gt;: I share my initial thoughts with the AI without worrying about spelling, organization, or grammar.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Provide References&lt;/strong&gt;: I share any relevant research or resources with the AI to help it understand the context of my writing.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Review and Refinement&lt;/strong&gt;: I review the AI's suggestions, accepting what feels right and adjusting what doesn't.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Final Polish&lt;/strong&gt;: A final review ensures everything flows naturally and accurately represents my thoughts.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The Future of Writing with Dyslexia
&lt;/h2&gt;

&lt;p&gt;Integrating AI into the writing process represents more than just a technological advancement – it's a democratization of written expression. For those of us with dyslexia, it means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;More confidence in professional communication&lt;/li&gt;
&lt;li&gt;Increased willingness to share our ideas and perspectives&lt;/li&gt;
&lt;li&gt;Reduced anxiety about written expression&lt;/li&gt;
&lt;li&gt;More time focusing on content rather than mechanics&lt;/li&gt;
&lt;li&gt;Enhanced autonomy when writing and creating content&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Maintaining Authenticity
&lt;/h2&gt;

&lt;p&gt;One common concern about using AI for writing is maintaining an authentic voice and original thoughts. As someone who uses AI regularly, I can confidently say that AI is a tool for expression, not a replacement for personal voice. The ideas, perspectives, and insights are still entirely our own – AI helps us present them more effectively.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion: Embracing the Future of Writing
&lt;/h2&gt;

&lt;p&gt;As we continue to advance technologically, it's crucial to recognize and embrace tools that make life more accessible for everyone. AI-assisted writing isn't about replacing human creativity or thought — it's about breaking down barriers that have historically prevented some of us from effectively sharing our voices with the world.&lt;/p&gt;

&lt;p&gt;For those with dyslexia who might be hesitant about using AI tools for writing, I encourage you to try them. They offer the support needed to share your valuable perspectives with the world more confidently and effectively.&lt;/p&gt;

&lt;p&gt;Remember: your thoughts and ideas matter, and using AI to help express them more clearly doesn't make them less valuable or authentic. It is just the tool that allows your voice to reach the audience it deserves.&lt;/p&gt;

&lt;h2&gt;
  
  
  Disclaimer
&lt;/h2&gt;

&lt;p&gt;As someone with dyslexia, I utilize AI tools extensively to assist in writing and structuring my blog posts. Although the ideas and direction are my own, AI technology helps me translate my thoughts into written form.&lt;/p&gt;

</description>
      <category>dyslexia</category>
      <category>webdev</category>
      <category>programming</category>
      <category>ai</category>
    </item>
    <item>
      <title>Building Static HTML Pages with JSX Server-Side Rendering</title>
      <dc:creator>Víctor García</dc:creator>
      <pubDate>Mon, 13 Jan 2025 15:56:44 +0000</pubDate>
      <link>https://dev.to/gc-victor/building-static-html-pages-with-jsx-server-side-rendering-5cbi</link>
      <guid>https://dev.to/gc-victor/building-static-html-pages-with-jsx-server-side-rendering-5cbi</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Have you ever visited a website that took forever to load? Frustrating, isn't it? Fast loading times and smooth user experiences aren't just nice-to-haves—they're essential for keeping visitors around and ranking high on search engines. Server-Side Rendering (SSR) with &lt;a href="https://facebook.github.io/jsx/" rel="noopener noreferrer"&gt;JSX&lt;/a&gt; presents an effective solution to these challenges. Unlike client-side rendering, where JavaScript constructs the page within the user's browser, SSR generates the complete HTML on the server before sending it to the client. This approach offers significant benefits for performance, &lt;a href="https://developers.google.com/search/docs/fundamentals/seo-starter-guide" rel="noopener noreferrer"&gt;Search Engine Optimization (SEO)&lt;/a&gt;, and overall simplicity.&lt;/p&gt;

&lt;p&gt;In this article, we'll explore developing static sites with JSX, focusing on the rationale, benefits, and best practices for this development strategy. Whether you're a developer looking to improve website performance, enhance SEO, simplify deployment, or explore new approaches to web development, this guide will provide valuable insights.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Choose SSR with JSX for Your Static Sites?
&lt;/h2&gt;

&lt;p&gt;Several key advantages make JSX-based SSR an attractive choice for building static websites.&lt;/p&gt;

&lt;p&gt;If you've worked with React before, you'll feel right at home with JSX. It uses a component-based architecture that makes it intuitive to adopt, promoting code reusability and maintainability. The result? Cleaner, more organized projects with quicker development cycles.&lt;/p&gt;

&lt;p&gt;Imagine visiting a website and seeing the content instantly—no waiting for JavaScript to piece everything together. That's the power of SSR. By sending fully formed HTML to the browser, users experience faster initial page loads, especially those on slower networks or devices. Faster loading means happier users and lower bounce rates.&lt;/p&gt;

&lt;p&gt;Search engines love fully rendered HTML. SSR ensures crawlers receive complete page content upfront, making indexing and ranking your site easier. This translates to better search visibility and a competitive edge.&lt;/p&gt;

&lt;p&gt;With SSR, there's less reliance on client-side JavaScript for rendering. This results in smaller payloads and better security since there's less code running in the browser.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnjg3p8qdn8kk9e91gggw.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%2Fnjg3p8qdn8kk9e91gggw.png" alt="Building Static HTML Pages with JSX Server-Side Rendering" width="800" height="374"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Choosing the Right Tool
&lt;/h2&gt;

&lt;p&gt;With so many tools claiming to make web development easier, how do you pick the right one? Join &lt;a href="https://qery.io" rel="noopener noreferrer"&gt;Query&lt;/a&gt;, a lightweight framework that simplifies JSX-based SSR without adding unnecessary complexity. Query offers an unusual approach by implementing an optimized JSX transform similar to &lt;a href="https://docs.deno.com/runtime/reference/jsx/#jsx-precompile-transform" rel="noopener noreferrer"&gt;Deno's JSX precompile transform&lt;/a&gt;. This transform prioritizes generating static HTML strings whenever possible, minimizing object creation and garbage collection overhead, resulting in significantly faster rendering times.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Choose Query?
&lt;/h3&gt;

&lt;p&gt;Forget the headaches of managing separate backend servers and databases. Query combines both into a single, streamlined system. This means you can write efficient SQL queries directly within your server-side functions, avoiding the complexity of ORMs and database clients. It's all about keeping things simple and efficient.&lt;/p&gt;

&lt;p&gt;Built on a highly optimized JavaScript runtime powered by &lt;a href="https://bellard.org/quickjs/" rel="noopener noreferrer"&gt;QuickJS&lt;/a&gt;, Query offers fast startup times and efficient execution. Its built-in caching mechanism further enhances performance by storing function responses, reducing database load and latency. This focus on speed makes Query a standout choice for server-side rendering, especially in applications with many components.&lt;/p&gt;

&lt;p&gt;Query's file-based routing, JSX support, and direct database access reduce boilerplate and configuration. This allows you to focus on what really matters—building your application logic. Its intuitive API ensures that developers of all levels can quickly get up to speed.&lt;/p&gt;

&lt;p&gt;Testing your code shouldn't be a chore. Inspired by &lt;a href="https://jestjs.io/" rel="noopener noreferrer"&gt;Jest&lt;/a&gt; and &lt;a href="https://bun.sh/docs/cli/test" rel="noopener noreferrer"&gt;Bun's test runner&lt;/a&gt;, Query's built-in test suite makes testing seamless. With familiar functions like &lt;code&gt;test&lt;/code&gt;, &lt;code&gt;describe&lt;/code&gt;, and &lt;code&gt;expect&lt;/code&gt;, writing and managing tests without extra tools is easy.&lt;/p&gt;

&lt;p&gt;Deploying your app globally is so simple with Query's integration with &lt;a href="http://fly.io/" rel="noopener noreferrer"&gt;Fly.io&lt;/a&gt;. Using &lt;a href="https://fly.io/docs/litefs/" rel="noopener noreferrer"&gt;LiteFS&lt;/a&gt; for distributed SQLite database replication, you can ensure low-latency access for users across different regions. Say goodbye to complex deployment pipelines.&lt;/p&gt;

&lt;p&gt;Query handles asset storage and serving, so you don't need external services like Amazon S3. This keeps your workflow simple and your assets closely tied to your application.&lt;/p&gt;

&lt;p&gt;Choosing the right tool for your project involves understanding your specific needs. If you're focused on content-heavy projects like blogs, documentation sites, or landing pages, consider your project's complexity, scalability, and the level of control you want over the development process when evaluating options.&lt;/p&gt;

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

&lt;p&gt;Server-side rendering with JSX offers a compelling approach to building high-performance static HTML websites. By leveraging the component model and optimizing for performance and SEO, you can create fast, scalable, and maintainable sites that provide an excellent user experience. This method is particularly well-suited for projects with predominantly static content, such as blogs, documentation sites, and landing pages.&lt;/p&gt;

&lt;p&gt;Whether you're building a blog or a documentation site or just curious about new approaches to web development, SSR with JSX offers plenty of benefits. Why not give Query a try and see how it changes your workflow?&lt;/p&gt;

&lt;p&gt;For projects seeking a simple, performant, and readily deployable solution that combines server-side rendering with JSX and direct database access, Query emerges as a strong contender. Its optimized JSX transform contributes to enhanced performance, making it an attractive option for those prioritizing speed and efficiency. While other frameworks might boast larger ecosystems and more mature communities, Query's unique approach streamlines development and deployment, presenting a viable alternative for a wide range of projects.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Disclaimer&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;As a dyslexic, I rely heavily on AI to help write and organize my blog articles. While I review and shape the content, AI helps me write down my thoughts.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.bdadyslexia.org.uk/dyslexia/about-dyslexia/what-is-dyslexia" rel="noopener noreferrer"&gt;What is dyslexia?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://facebook.github.io/jsx/" rel="noopener noreferrer"&gt;JSX&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://qery.io/docs/modules/function.html" rel="noopener noreferrer"&gt;Query Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://qery.io/docs/modules/database.html" rel="noopener noreferrer"&gt;Query Database Module&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bellard.org/quickjs/" rel="noopener noreferrer"&gt;QuickJS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/DelSkayn/rquickjs" rel="noopener noreferrer"&gt;rquickjs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/awslabs/llrt/tree/main/llrt_modules" rel="noopener noreferrer"&gt;AWS LLRT Modules&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.deno.com/runtime/reference/jsx/" rel="noopener noreferrer"&gt;Deno JSX Precompile Transform&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://marvinh.dev/blog/speeding-up-javascript-ecosystem-part-9/" rel="noopener noreferrer"&gt;Speeding Up the JavaScript Ecosystem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://fly.io/docs/" rel="noopener noreferrer"&gt;Fly.io Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://fly.io/docs/litefs/" rel="noopener noreferrer"&gt;LiteFS Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.sqlite.org/" rel="noopener noreferrer"&gt;SQLite Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://jestjs.io/" rel="noopener noreferrer"&gt;Jest Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bun.sh/docs/cli/test" rel="noopener noreferrer"&gt;Bun Test Runner Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>jsx</category>
      <category>javascript</category>
      <category>rust</category>
      <category>html</category>
    </item>
    <item>
      <title>Building a Minimal Blog with Query</title>
      <dc:creator>Víctor García</dc:creator>
      <pubDate>Fri, 11 Oct 2024 16:22:33 +0000</pubDate>
      <link>https://dev.to/gc-victor/building-a-minimal-blog-with-query-2hj9</link>
      <guid>https://dev.to/gc-victor/building-a-minimal-blog-with-query-2hj9</guid>
      <description>&lt;p&gt;This tutorial will guide you through creating a basic blog application using &lt;a href="https://qery.io" rel="noopener noreferrer"&gt;Query&lt;/a&gt;. You'll see how Query simplifies the development process by handling the database, backend, and frontend in one cohesive system.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Set up a new Query project
&lt;/h2&gt;

&lt;p&gt;First, create a new Query project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm dlx @qery/query create
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Select the &lt;code&gt;minimal&lt;/code&gt; project template and follow the prompts to create a new project. The &lt;code&gt;minimal&lt;/code&gt; template provides a simple starting point for building simple web applications with Query.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Define the database schema
&lt;/h2&gt;

&lt;p&gt;Query uses SQLite databases for data storage. SQLite is a lightweight, file-based database well-suited for small—to medium-sized applications. It provides a simple and efficient way to store and retrieve data without the need for a separate database server.&lt;/p&gt;

&lt;p&gt;In this example, we'll define the schema for our blog application using SQLite. Create a file &lt;code&gt;migrations/blog.sql&lt;/code&gt; with the following contents:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;IF&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;EXISTS&lt;/span&gt; &lt;span class="n"&gt;post&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="nb"&gt;INTEGER&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt; &lt;span class="n"&gt;AUTOINCREMENT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;created_at&lt;/span&gt; &lt;span class="nb"&gt;INTEGER&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;strftime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'%s'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'now'&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 SQLite statement creates a table named &lt;code&gt;post&lt;/code&gt; with the following columns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;id&lt;/code&gt;: An auto-incrementing integer that serves as the primary key for each post.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;title&lt;/code&gt;: A text column to store the post's title.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;content&lt;/code&gt;: A text column to store the content of the post.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;created_at&lt;/code&gt;: An integer column to store the creation timestamp of the post, defaulting to the current Unix timestamp.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can define your database schema using SQL files and manage its evolution over time by creating additional migration files.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Create the views
&lt;/h2&gt;

&lt;p&gt;In this project, we are using a combination of HTML and TypeScript files for server-side rendering. HTML files define the static structure of the page, while TypeScript files handle dynamic content and data fetching.&lt;/p&gt;

&lt;p&gt;Create a file &lt;code&gt;src/pages/index.html&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;My Blog&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/new"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Create New Post&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;main&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;&amp;lt;!-- POSTS --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/main&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a file &lt;code&gt;src/pages/get.index.ts&lt;/code&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Database&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;query:database&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="nx"&gt;html&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./index.html&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Post&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;created_at&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handleRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Request&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;db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Database&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;blog.sql&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;posts&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="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;SELECT * FROM post ORDER BY created_at DESC&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;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;html&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;!-- POSTS --&amp;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;generatePostsHTML&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;posts&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;new&lt;/span&gt; &lt;span class="nc"&gt;Response&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="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text/html; charset=utf-8&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;generatePostsHTML&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;posts&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="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;posts&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="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;`
            &amp;lt;article&amp;gt;
                &amp;lt;h2&amp;gt;&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;title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/h2&amp;gt;
                &amp;lt;p&amp;gt;&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;content&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/p&amp;gt;
                &amp;lt;p&amp;gt;Posted on &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;Date&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;created_at&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toLocaleString&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/p&amp;gt;
            &amp;lt;/article&amp;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;join&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the &lt;code&gt;get.index.ts&lt;/code&gt; file, we import the &lt;code&gt;Database&lt;/code&gt; class from &lt;code&gt;query:database&lt;/code&gt; to interact with the SQLite database. Inside the &lt;code&gt;handleRequest&lt;/code&gt; function, we create a new instance of the &lt;code&gt;Database&lt;/code&gt; class and use the &lt;code&gt;query&lt;/code&gt; method to fetch all posts from the &lt;code&gt;post&lt;/code&gt; table, ordering them by the &lt;code&gt;created_at&lt;/code&gt; column in descending order.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;generatePostsHTML&lt;/code&gt; function takes the fetched posts and generates the corresponding HTML markup for each post. The generated HTML is then used to replace the &lt;code&gt;&amp;lt;!-- POSTS --&amp;gt;&lt;/code&gt; placeholder in the HTML template.&lt;/p&gt;

&lt;p&gt;Finally, the &lt;code&gt;handleRequest&lt;/code&gt; function returns a &lt;code&gt;Response&lt;/code&gt; object with the generated HTML as the body and the appropriate headers.&lt;/p&gt;

&lt;p&gt;Create files &lt;code&gt;src/pages/new/index.html&lt;/code&gt; and &lt;code&gt;src/pages/new/get.index.ts&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Create New Post&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;form&lt;/span&gt; &lt;span class="na"&gt;action=&lt;/span&gt;&lt;span class="s"&gt;"/api/post"&lt;/span&gt; &lt;span class="na"&gt;method=&lt;/span&gt;&lt;span class="s"&gt;"POST"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"title"&lt;/span&gt; &lt;span class="na"&gt;placeholder=&lt;/span&gt;&lt;span class="s"&gt;"Title"&lt;/span&gt; &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;textarea&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"content"&lt;/span&gt; &lt;span class="na"&gt;placeholder=&lt;/span&gt;&lt;span class="s"&gt;"Content"&lt;/span&gt; &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/textarea&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Create Post&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/form&amp;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="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;html&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./index.html&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="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handleRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Request&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;new&lt;/span&gt; &lt;span class="nc"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;html&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text/html; charset=utf-8&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;The &lt;code&gt;src/pages/new/get.index.ts&lt;/code&gt; file is another TypeScript file that handles the rendering of the "Create New Post" page. It simply returns the HTML content imported from &lt;code&gt;index.html&lt;/code&gt; as the response.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Create API endpoints
&lt;/h2&gt;

&lt;p&gt;In Query, API endpoints are defined using JavaScript or TypeScript files with a specific naming convention. The file name prefix determines the HTTP method (&lt;code&gt;delete,&lt;/code&gt; &lt;code&gt;get,&lt;/code&gt; &lt;code&gt;patch,&lt;/code&gt; &lt;code&gt;post,&lt;/code&gt; &lt;code&gt;put&lt;/code&gt;), and the folder structure defines the route.&lt;/p&gt;

&lt;p&gt;Create a file &lt;code&gt;src/api/post/post.index.ts&lt;/code&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Database&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;query:database&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="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handleRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Request&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;formData&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;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;formData&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;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;formData&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kr"&gt;string&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;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;formData&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;content&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kr"&gt;string&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;db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Database&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;blog.sql&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;INSERT INTO post (title, content) VALUES (?, ?)&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="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;content&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;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&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;redirect&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;url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;origin&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="mi"&gt;303&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;The &lt;code&gt;handleRequest&lt;/code&gt; function is Query's entry point for each function route. It receives a &lt;code&gt;Request&lt;/code&gt; object as a parameter and returns a &lt;code&gt;Response&lt;/code&gt;. The &lt;code&gt;Request&lt;/code&gt; object contains information about the incoming HTTP request, such as the URL, headers, and body. You can use this information to process the request and generate an appropriate response.&lt;/p&gt;

&lt;p&gt;Inside the &lt;code&gt;handleRequest&lt;/code&gt; function, you can access the database using the &lt;code&gt;Database&lt;/code&gt; class imported from &lt;code&gt;query:database.&lt;/code&gt; To create a new instance of the &lt;code&gt;Database&lt;/code&gt; class, you need to provide the name of the database file. We use &lt;code&gt;blog.sql&lt;/code&gt; as the database file name in this example.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;Database&lt;/code&gt; class provides a &lt;code&gt;query&lt;/code&gt; method that allows you to execute SQL queries against the SQLite database. You can use placeholders (&lt;code&gt;?&lt;/code&gt;) in your SQL queries to prevent SQL injection attacks. The placeholder values are passed as an array in the second argument of the &lt;code&gt;query&lt;/code&gt; method.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: Run the application
&lt;/h2&gt;

&lt;p&gt;Start the Query development server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;query dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Visit &lt;code&gt;http://localhost:3000&lt;/code&gt; in your browser to see your blog in action!&lt;/p&gt;

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

&lt;p&gt;This example shows how Query simplifies web development by providing an integrated approach to handling databases, API routes, and server-side rendering.&lt;/p&gt;

&lt;p&gt;Query uses SQLite databases, which are lightweight, file-based databases that are easy to set up and use. You can define your database schema using SQL files and control their version with your application code.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;handleRequest&lt;/code&gt; function is the entry point for each API route and allows you to process incoming requests and generate appropriate responses. By importing the &lt;code&gt;Database&lt;/code&gt; class from &lt;code&gt;query:database&lt;/code&gt;, you can easily interact with the SQLite database and execute SQL queries using the &lt;code&gt;query&lt;/code&gt; method.&lt;/p&gt;

&lt;p&gt;Query's combination of HTML and TypeScript enables you to define the static structure of your pages and handle dynamic content and data fetching. The &lt;code&gt;handleRequest&lt;/code&gt; function in TypeScript files can access the database, fetch data, and generate the final HTML response.&lt;/p&gt;

&lt;p&gt;With Query, you can focus on building your application's functionality without worrying about setting up and managing separate services for the database, backend, and frontend.&lt;/p&gt;

&lt;p&gt;Related links:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/gc-victor/query-minimal-blog" rel="noopener noreferrer"&gt;Query Minimal Blog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://qery.io" rel="noopener noreferrer"&gt;Query Website&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/gc-victor/query" rel="noopener noreferrer"&gt;Query - GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://qery.io/docs/introduction.html" rel="noopener noreferrer"&gt;Query Introduction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://qery.io/docs/cli/function.html" rel="noopener noreferrer"&gt;Query Function&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>Cache, Store, and Serve All in One: Manage Your Website with SQLite Power</title>
      <dc:creator>Víctor García</dc:creator>
      <pubDate>Tue, 16 Apr 2024 13:40:05 +0000</pubDate>
      <link>https://dev.to/gc-victor/query-mental-model-38b0</link>
      <guid>https://dev.to/gc-victor/query-mental-model-38b0</guid>
      <description>&lt;p&gt;&lt;a href="https://qery.io" rel="noopener noreferrer"&gt;Query&lt;/a&gt; is a one-file system that uses SQLite to cover most of the full-stack development and infrastructure needs for small websites.&lt;/p&gt;

&lt;h2&gt;
  
  
  Query Mental Model
&lt;/h2&gt;

&lt;p&gt;This is a mental model to guide you when working with Query.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;I &lt;strong&gt;do not need a database server&lt;/strong&gt; (PostgreSQL or MySQL), as I can connect to my SQLite databases remotely using the Query APIs, the CLI, and the functions.&lt;/li&gt;
&lt;li&gt;I &lt;strong&gt;do not need a JavaScript runtime&lt;/strong&gt; (NodeJS, Deno, or Bun), as Query offers its own.&lt;/li&gt;
&lt;li&gt;I &lt;strong&gt;do not need a JavaScript backend framework&lt;/strong&gt; (NextJS, Remix or Astro), as Query provides functions to serve Pages and APIs.&lt;/li&gt;
&lt;li&gt;I &lt;strong&gt;do not need a caching system&lt;/strong&gt; (Redis) for my function, as Query caches them in SQLite and serves them.&lt;/li&gt;
&lt;li&gt;I &lt;strong&gt;do not need a storage system&lt;/strong&gt; (S3) for my assets, as Query stores them in SQLite and serves them.&lt;/li&gt;
&lt;li&gt;I &lt;strong&gt;do not need a scaffolding tool&lt;/strong&gt; to generate code, as Query offers its own.&lt;/li&gt;
&lt;li&gt;I &lt;strong&gt;do not need to develop a back office admin area&lt;/strong&gt;, thanks to the Query generator, as I can build one just by executing a command.&lt;/li&gt;
&lt;li&gt;I &lt;strong&gt;can deploy in a couple of seconds&lt;/strong&gt; to Query.&lt;/li&gt;
&lt;li&gt;I &lt;strong&gt;can distribute it in multiple regions&lt;/strong&gt;, thanks to Fly.io and LiteFS.&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;The following links are related to each mental model concept.&lt;/p&gt;

&lt;p&gt;[1] &lt;a href="https://github.com/gc-victor/query?tab=readme-ov-file#query-endpoint" rel="noopener noreferrer"&gt;Query API&lt;/a&gt;&lt;br&gt;
[1] &lt;a href="https://github.com/gc-victor/query?tab=readme-ov-file#shell" rel="noopener noreferrer"&gt;Shell&lt;/a&gt;&lt;br&gt;
[1] &lt;a href="https://github.com/gc-victor/query?tab=readme-ov-file#function" rel="noopener noreferrer"&gt;Functions&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[2] &lt;a href="https://github.com/gc-victor/query/tree/main/crates/runtime" rel="noopener noreferrer"&gt;Query JavaScript Runtime&lt;/a&gt;&lt;br&gt;
[2] &lt;a href="https://github.com/gc-victor/query/tree/main/crates/runtime/runtime-compat" rel="noopener noreferrer"&gt;Runtime Compatibility&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[3] &lt;a href="https://github.com/gc-victor/query?tab=readme-ov-file#function" rel="noopener noreferrer"&gt;Functions&lt;/a&gt;&lt;br&gt;
[3] &lt;a href="https://github.com/gc-victor/query/tree/main?tab=readme-ov-file#folder-structure-example" rel="noopener noreferrer"&gt;File-System Based Router&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[4] &lt;a href="https://github.com/gc-victor/query?tab=readme-ov-file#query-cache-control" rel="noopener noreferrer"&gt;Query Cache Control&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[5] &lt;a href="https://github.com/gc-victor/query/tree/main?tab=readme-ov-file#generator" rel="noopener noreferrer"&gt;Query Generator&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[6] &lt;a href="https://github.com/gc-victor/query/tree/main?tab=readme-ov-file#asset" rel="noopener noreferrer"&gt;Assets&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[7] &lt;a href="https://github.com/gc-victor/query/tree/main?tab=readme-ov-file#generator" rel="noopener noreferrer"&gt;Query Generator&lt;/a&gt;&lt;br&gt;
[7] &lt;a href="https://github.com/gc-victor/query/tree/main?tab=readme-ov-file#templates" rel="noopener noreferrer"&gt;Query Generator Templates&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[8] &lt;a href="https://github.com/gc-victor/query/tree/main?tab=readme-ov-file#example" rel="noopener noreferrer"&gt;Query Function CLI&lt;/a&gt;&lt;br&gt;
[8] &lt;a href="https://github.com/gc-victor/query/tree/main?tab=readme-ov-file#asset" rel="noopener noreferrer"&gt;Query Assets CLI&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[9] &lt;a href="https://fly.io/" rel="noopener noreferrer"&gt;Fly.io&lt;/a&gt;&lt;br&gt;
[9] &lt;a href="https://fly.io/docs/litefs/" rel="noopener noreferrer"&gt;LiteFS&lt;/a&gt;&lt;/p&gt;

</description>
      <category>rust</category>
      <category>javascript</category>
      <category>sqlite</category>
      <category>redis</category>
    </item>
    <item>
      <title>Create Your Side Project With A Single Command</title>
      <dc:creator>Víctor García</dc:creator>
      <pubDate>Tue, 05 Mar 2024 11:12:23 +0000</pubDate>
      <link>https://dev.to/gc-victor/create-your-side-project-with-a-single-command-4hn0</link>
      <guid>https://dev.to/gc-victor/create-your-side-project-with-a-single-command-4hn0</guid>
      <description>&lt;p&gt;&lt;a href="https://github.com/gc-victor/query" rel="noopener noreferrer"&gt;Query&lt;/a&gt; offers a powerful code generator that assists developers in creating side projects quickly and efficiently. With Query's predefined templates, developers can automate the creation of APIs, Admin UI, database migrations, and validations, making coding effortless, maximizing efficiency, customization, and simplicity, enabling developers to create quality projects quickly.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/gc-victor/query-app" rel="noopener noreferrer"&gt;Query App&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/gc-victor/query?tab=readme-ov-file#generator" rel="noopener noreferrer"&gt;Query Generator&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Give it a try!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>sqlite</category>
      <category>rust</category>
    </item>
    <item>
      <title>Effortless Function as a Service: A Simple Guide to Implementing it with Query</title>
      <dc:creator>Víctor García</dc:creator>
      <pubDate>Thu, 21 Dec 2023 10:59:50 +0000</pubDate>
      <link>https://dev.to/gc-victor/effortless-function-as-a-service-a-simple-guide-to-implementing-it-with-query-3ha0</link>
      <guid>https://dev.to/gc-victor/effortless-function-as-a-service-a-simple-guide-to-implementing-it-with-query-3ha0</guid>
      <description>&lt;p&gt;&lt;a href="https://github.com/gc-victor/query" rel="noopener noreferrer"&gt;Query&lt;/a&gt; is a Rust server that provides an &lt;a href="https://github.com/gc-victor/query?tab=readme-ov-file#apis" rel="noopener noreferrer"&gt;API&lt;/a&gt;, &lt;a href="https://github.com/gc-victor/query?tab=readme-ov-file#cli" rel="noopener noreferrer"&gt;CLI&lt;/a&gt;, and authentication for remote interaction with SQLite databases. It has introduced &lt;a href="https://github.com/gc-victor/query?tab=readme-ov-file#function" rel="noopener noreferrer"&gt;"functions"&lt;/a&gt; to enhance your product with hosted JavaScript code accessing remote &lt;a href="https://www.sqlite.org/index.html" rel="noopener noreferrer"&gt;SQLite&lt;/a&gt; databases.&lt;/p&gt;

&lt;p&gt;Let's explore a practical example of a Query function:&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="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handleRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&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;db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Database&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;example.sql&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;result&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;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;SELECT * FROM example WHERE id = ?&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="mi"&gt;1&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;new&lt;/span&gt; &lt;span class="nc"&gt;Response&lt;/span&gt;&lt;span class="p"&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="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;content-type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;application/json&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;In this example, the function fetches data from a database table and responds with a JSON object containing the result.&lt;/p&gt;

&lt;p&gt;A Query function follows a specific format. It exports an asynchronous function named &lt;code&gt;handleRequest&lt;/code&gt; that takes a &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Request" rel="noopener noreferrer"&gt;Request&lt;/a&gt; and returns a &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Response" rel="noopener noreferrer"&gt;Response&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A connection to a database is required to interact with databases using the Query function. It can be achieved by utilizing the &lt;code&gt;Database&lt;/code&gt; constructor.&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;db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Database&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;example.sql&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;Database&lt;/code&gt; constructor takes the name of the database. Once connected, it provides two essential methods:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;query&lt;/code&gt;: Reads data from the database.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;execute&lt;/code&gt;: Writes data to the database.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both &lt;code&gt;query&lt;/code&gt; and &lt;code&gt;execute&lt;/code&gt; can accept parameters as an array or an object with placeholders like &lt;code&gt;:AAA&lt;/code&gt;, &lt;code&gt;$AAA&lt;/code&gt;, or &lt;code&gt;@AAA&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Remember, when working with Query and &lt;a href="https://fly.io/docs/litefs/config/#http-proxy-server" rel="noopener noreferrer"&gt;LiteFS proxy&lt;/a&gt;, use &lt;code&gt;GET&lt;/code&gt; to read data and &lt;code&gt;DELETE|POST|PUT|PATCH&lt;/code&gt; to write data.&lt;/p&gt;

&lt;p&gt;Query follows a specific folder structure to organize functions and define routes. Here's an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;functions
├── get.index.js // GET &lt;span class="s2"&gt;"/"&lt;/span&gt;
├── post.index.js // POST &lt;span class="s2"&gt;"/"&lt;/span&gt;
├── example
    ├── get.index.js // GET &lt;span class="s2"&gt;"/example"&lt;/span&gt;
    ├── get.[slug].js // GET &lt;span class="s2"&gt;"/example/:slug"&lt;/span&gt;
    &lt;span class="o"&gt;[&lt;/span&gt;slug]
    ├── get.index.js  // GET &lt;span class="s2"&gt;"/:slug"&lt;/span&gt;
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The prefix determines the method used in a file &lt;code&gt;(delete|get|patch|post|put).*&lt;/code&gt;. The remaining part of the file name defines the final segment of the route. For instance, if the file name ends with &lt;code&gt;index&lt;/code&gt;, it represents the root of the route.&lt;/p&gt;

&lt;p&gt;If you're looking to deploy and replicate your databases across the globe quickly, &lt;a href="//fly.io/"&gt;Fly.io&lt;/a&gt; provides a seamless solution to run a Query Server in just a few minutes.&lt;/p&gt;

&lt;p&gt;To incorporate Query into your deployment, your &lt;a href="https://github.com/gc-victor/query?tab=readme-ov-file#run-a-query-server-on-flyio" rel="noopener noreferrer"&gt;Dockerfile needs to include the Query Server&lt;/a&gt;. Consider using a multistage Dockerfile, with the final stage being a compatible &lt;code&gt;x86_64-unknown-linux-gnu&lt;/code&gt; image, such as &lt;code&gt;debian:&amp;lt;suite&amp;gt;-slim&lt;/code&gt;. Refer to the &lt;a href="https://fly.io/docs/litefs/speedrun/" rel="noopener noreferrer"&gt;LiteFS documentation&lt;/a&gt; for critical information on this essential system component.&lt;/p&gt;

&lt;p&gt;Here is a sample Dockerfile for your Query Server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; debian:12-slim&lt;/span&gt;

&lt;span class="k"&gt;ADD&lt;/span&gt;&lt;span class="s"&gt; litefs.yml /etc/litefs.yml&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --from=flyio/litefs:0.5 /usr/local/bin/litefs /usr/local/bin/litefs&lt;/span&gt;

&lt;span class="k"&gt;RUN &lt;/span&gt;apt-get update &lt;span class="nt"&gt;-qq&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    apt-get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; &lt;span class="nt"&gt;--no-install-recommends&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    ca-certificates &lt;span class="se"&gt;\
&lt;/span&gt;    sqlite3 &lt;span class="se"&gt;\
&lt;/span&gt;    fuse3 &lt;span class="se"&gt;\
&lt;/span&gt;    curl

&lt;span class="c"&gt;# Download and install Query Server&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;curl &lt;span class="nt"&gt;--proto&lt;/span&gt; &lt;span class="s1"&gt;'=https'&lt;/span&gt; &lt;span class="nt"&gt;--tlsv1&lt;/span&gt;.2 &lt;span class="nt"&gt;-LsSf&lt;/span&gt; https://github.com/gc-victor/query/releases/latest/download/query-server-installer.sh | sh

&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="s"&gt; 3000&lt;/span&gt;

&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["litefs", "mount"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Additionally, to kickstart the server, add this command to the &lt;a href="https://fly.io/docs/litefs/config/" rel="noopener noreferrer"&gt;litefs.yml&lt;/a&gt; configuration file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="nn"&gt;...&lt;/span&gt;
&lt;span class="na"&gt;exec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;cmd&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;~/.cargo/bin/query-server"&lt;/span&gt;
&lt;span class="nn"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With these components in place, your Query Server will be ready to deploy on Fly, providing a robust and globally accessible solution.&lt;/p&gt;

&lt;p&gt;Let's install the toolset to deploy the functions.&lt;/p&gt;

&lt;p&gt;We have to install the &lt;a href="https://github.com/gc-victor/query?tab=readme-ov-file#cli" rel="noopener noreferrer"&gt;Query CLI&lt;/a&gt;. It is a powerful tool that lets you manage your remote SQLite databases with ease and safety.&lt;/p&gt;

&lt;p&gt;Form macOS and Linux (not NixOS, Alpine, or Asahi):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;--proto&lt;/span&gt; &lt;span class="s1"&gt;'=https'&lt;/span&gt; &lt;span class="nt"&gt;--tlsv1&lt;/span&gt;.2 &lt;span class="nt"&gt;-LsSf&lt;/span&gt; https://github.com/gc-victor/query/releases/latest/download/query-installer.sh | sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The functions will bundle using &lt;a href="https://esbuild.github.io" rel="noopener noreferrer"&gt;esbuild&lt;/a&gt;. For that, it is required to install esbuild globally:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--global&lt;/span&gt; esbuild
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, to deploy the functions, run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;query &lt;span class="k"&gt;function&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With their structured approach and database integration, &lt;a href="https://github.com/gc-victor/query?tab=readme-ov-file#function" rel="noopener noreferrer"&gt;Query functions&lt;/a&gt; offer a robust foundation for building scalable and efficient &lt;a href="https://en.wikipedia.org/wiki/Function_as_a_service" rel="noopener noreferrer"&gt;Function as a Service (FaaS)&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>sqlite</category>
      <category>rust</category>
      <category>litefs</category>
    </item>
    <item>
      <title>Simplifying the Management of Remote SQLite Databases</title>
      <dc:creator>Víctor García</dc:creator>
      <pubDate>Mon, 27 Nov 2023 09:49:38 +0000</pubDate>
      <link>https://dev.to/gc-victor/simplifying-the-management-of-remote-sqlite-databases-55e0</link>
      <guid>https://dev.to/gc-victor/simplifying-the-management-of-remote-sqlite-databases-55e0</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;With the growing popularity of &lt;a href="https://www.sqlite.org/index.html" rel="noopener noreferrer"&gt;SQLite&lt;/a&gt; usage in websites, particularly with &lt;a href="https://fly.io/docs/litefs/" rel="noopener noreferrer"&gt;LiteFS&lt;/a&gt;, there is an increasing demand to manage remote databases. &lt;a href="https://github.com/gc-victor/query" rel="noopener noreferrer"&gt;Query&lt;/a&gt; aims to give you straightforward access to your remote databases.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3rbzit9z9il2lqon0k4k.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%2F3rbzit9z9il2lqon0k4k.png" alt="Kent C. Dodds Tweet about this article" width="800" height="387"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Query?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/gc-victor/query" rel="noopener noreferrer"&gt;Query&lt;/a&gt; is a Rust server that runs alongside your application and enhances its functionality without the application's knowledge. Query provides an &lt;a href="https://github.com/gc-victor/query/tree/main?tab=readme-ov-file#apis" rel="noopener noreferrer"&gt;API&lt;/a&gt;, &lt;a href="https://github.com/gc-victor/query/tree/main?tab=readme-ov-file#cli" rel="noopener noreferrer"&gt;CLI&lt;/a&gt;, and an authentication system that enables remote interaction with your SQLite databases.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;/query&lt;/code&gt; entry point of Query is both powerful and simple, utilizing a basic payload consisting of a database name, a query, and parameters to send requests to remote databases.&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;"db_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"kv.sql"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"query"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"INSERT INTO kv (key, value) VALUES (?, ?);"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"params"&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="s2"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&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;p&gt;It also provides &lt;a href="https://github.com/gc-victor/query/tree/main?tab=readme-ov-file#function" rel="noopener noreferrer"&gt;functions&lt;/a&gt; (without sandboxing by default) like &lt;a href="https://vercel.com/features/edge-functions" rel="noopener noreferrer"&gt;Edge Functions from Vercel&lt;/a&gt; or &lt;a href="https://deno.com/subhosting" rel="noopener noreferrer"&gt;Deno subhosting&lt;/a&gt; or &lt;a href="https://workers.cloudflare.com" rel="noopener noreferrer"&gt;Cloudflare Workers&lt;/a&gt;, but with direct access to your databases. They are JavaScript functions executed in Rust using a runtime based on &lt;a href="https://deno.com" rel="noopener noreferrer"&gt;Deno&lt;/a&gt;. The functions are stored in a database and can be replicated through LiteFS, putting them closer to the user.&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="c1"&gt;// get.index.js&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handleRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&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;db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Database&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;example.sql&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;result&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;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;SELECT * FROM example WHERE id = ?&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="mi"&gt;1&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;new&lt;/span&gt; &lt;span class="nc"&gt;Response&lt;/span&gt;&lt;span class="p"&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="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;}),&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;content-type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;application/json&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;Query allows you to create &lt;a href="https://github.com/gc-victor/query/tree/main?tab=readme-ov-file#branch" rel="noopener noreferrer"&gt;branches&lt;/a&gt;, it  duplicates a database to be utilized in development environments.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;query branch &amp;lt;SUBCOMMAND&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Additionally, Query provides a basic &lt;a href="https://github.com/gc-victor/query/tree/main?tab=readme-ov-file#migration" rel="noopener noreferrer"&gt;migration&lt;/a&gt; system that manages your databases by sending a batch of queries.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;query migration &amp;lt;DB_NAME&amp;gt; &amp;lt;PATH&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Benefits of using Query
&lt;/h2&gt;

&lt;p&gt;The benefits of using Query are endless, as it provides a robust API on top of your databases.&lt;/p&gt;

&lt;p&gt;With &lt;a href="https://github.com/gc-victor/query/tree/main?tab=readme-ov-file#cli" rel="noopener noreferrer"&gt;Query CLI&lt;/a&gt; you can safely manage your databases, from creating a branch to testing a migration before executing it in production to a function that receives a request from a webhook coming from a headless CMS and manipulates the data received before inserting it into the database.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbwpc6w9b9pt3p4j3hrsb.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%2Fbwpc6w9b9pt3p4j3hrsb.png" alt="Query Studio" width="800" height="372"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/gc-victor/query-studio" rel="noopener noreferrer"&gt;Query Studio&lt;/a&gt; showcases the power of Query. It is an online SQLite editor for Query, allowing you to access databases using a UI built with &lt;a href="https://bun.sh" rel="noopener noreferrer"&gt;Bun&lt;/a&gt;. Using the Query API, Query Studio facilitates the creation, reading, updating, and deletion of data from databases and column fields.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to use Query
&lt;/h2&gt;

&lt;p&gt;We recommend using Query with &lt;a href="https://fly.io" rel="noopener noreferrer"&gt;Fly&lt;/a&gt;. It will help you deploy your server in minutes and replicate your databases worldwide.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://fly.io/docs/hands-on/" rel="noopener noreferrer"&gt;Hands-on Fly guide&lt;/a&gt; covers CLI installation, sign-up, and sign-in for new Fly users.&lt;/p&gt;

&lt;p&gt;There are two ways to use Query. You can either use it as a standalone service or use it with a proxy to connect to your app. You can access your databases directly from your application and Query using the &lt;a href="https://github.com/gc-victor/query#query-server-with-proxy" rel="noopener noreferrer"&gt;Query Proxy&lt;/a&gt;. On the other hand, using &lt;a href="https://github.com/gc-victor/query#query-as-an-isolated-service" rel="noopener noreferrer"&gt;Query as an isolated service&lt;/a&gt; allows you to access the databases through HTTP requests using the API.&lt;/p&gt;

&lt;p&gt;Using the proxy instead of the isolated service offers the advantage of easier replication and scaling, as Query and your application share the same VM.&lt;/p&gt;

&lt;p&gt;If you are an &lt;a href="https://www.epicweb.dev/epic-stack" rel="noopener noreferrer"&gt;Epic Stack&lt;/a&gt; user or want to explore an example using it with Query, we have published a &lt;a href="https://github.com/gc-victor/epic-stack-with-query" rel="noopener noreferrer"&gt;repository&lt;/a&gt; for you to review. You can find the example in the &lt;a href="https://github.com/epicweb-dev/epic-stack/blob/main/docs/examples.md" rel="noopener noreferrer"&gt;Epic Stack documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;There is an &lt;a href="https://github.com/gc-victor/query/tree/main/examples/proxy" rel="noopener noreferrer"&gt;example&lt;/a&gt; on the Query repository for &lt;a href="https://bun.sh" rel="noopener noreferrer"&gt;Bun&lt;/a&gt; users to test the proxy feature.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to get involved?
&lt;/h2&gt;

&lt;p&gt;Get involved with Query by visiting the &lt;a href="https://github.com/gc-victor/query" rel="noopener noreferrer"&gt;GitHub Page&lt;/a&gt; to explore the codebase and discussions. Identify areas to contribute through existing issues, participate in discussions, and submit code enhancements via pull requests. Please spread the word to build a vibrant community around Query.&lt;/p&gt;

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

&lt;p&gt;Query is an excellent tool to empower all your LiteFS projects. I strongly suggest exploring its features; you will realize its vast potential.&lt;/p&gt;

&lt;p&gt;References:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/gc-victor/query" rel="noopener noreferrer"&gt;https://github.com/gc-victor/query&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/gc-victor/query-studio" rel="noopener noreferrer"&gt;https://github.com/gc-victor/query-studio&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/gc-victor/epic-stack-with-query" rel="noopener noreferrer"&gt;https://github.com/gc-victor/epic-stack-with-query&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.sqlite.org/index.html" rel="noopener noreferrer"&gt;https://www.sqlite.org/index.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://fly.io/docs/hands-on/" rel="noopener noreferrer"&gt;https://fly.io/docs/hands-on/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://fly.io/docs/litefs/" rel="noopener noreferrer"&gt;https://fly.io/docs/litefs/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.epicweb.dev/epic-stack" rel="noopener noreferrer"&gt;https://www.epicweb.dev/epic-stack&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bun.sh" rel="noopener noreferrer"&gt;https://bun.sh&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://deno.com" rel="noopener noreferrer"&gt;https://deno.com&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>rust</category>
      <category>sqlite</category>
      <category>litefs</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
