<?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: Adalbertus Chris</title>
    <description>The latest articles on DEV Community by Adalbertus Chris (@adalbertuschris).</description>
    <link>https://dev.to/adalbertuschris</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%2F1212398%2Fd2403d88-6671-4712-8ca6-baf46a4ceacb.png</url>
      <title>DEV Community: Adalbertus Chris</title>
      <link>https://dev.to/adalbertuschris</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/adalbertuschris"/>
    <language>en</language>
    <item>
      <title>Is React a good fit for the future of AI-generated UI?</title>
      <dc:creator>Adalbertus Chris</dc:creator>
      <pubDate>Sun, 16 Nov 2025 14:39:03 +0000</pubDate>
      <link>https://dev.to/adalbertuschris/is-react-a-good-fit-for-the-future-of-ai-generated-ui-5dbb</link>
      <guid>https://dev.to/adalbertuschris/is-react-a-good-fit-for-the-future-of-ai-generated-ui-5dbb</guid>
      <description>&lt;p&gt;Recently I’ve been thinking about where frontend development is heading — especially now that AI-assisted UI generation and design-code workflows are becoming more realistic.&lt;/p&gt;

&lt;p&gt;React is one of the most popular frontend libraries, but its architecture raises an important question:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is React the right tool for a future where UI and logic could be handled by different roles?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For example: designers (with help from AI tools) can generate the UI structure, while frontend developers can focus on the logic.&lt;/p&gt;

&lt;p&gt;Unlike frameworks such as Angular, Vue, Svelte, and others that separate markup (html) and logic (ts/js), React mixes markup, logic, state, and behavior all into the same block of code. That’s convenient for developers, but it can introduces challenges for design-to-code AI tools.&lt;/p&gt;

&lt;p&gt;Tools that generate only templates (HTML) and CSS can produce cleaner and more predictable output. But when markup and logic are tightly coupled, it becomes harder to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;keep code clean&lt;/li&gt;
&lt;li&gt;track only logic or only template changes&lt;/li&gt;
&lt;li&gt;automate UI generation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Is template, logic separation feels much more aligned with the direction automated UI generation heading? Designers or AI systems could generate clean templates, and developers could plug in the logic without responsibilities bleeding together. Could React’s architecture limit its effectiveness for future design-to-code workflows, generating messy code that’s difficult to maintain and forcing full-file reviews whenever designs change?&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>ai</category>
      <category>react</category>
      <category>programming</category>
    </item>
    <item>
      <title>Frontend Evolution — Rethinking Frontend - part 3 - introduction to jModel</title>
      <dc:creator>Adalbertus Chris</dc:creator>
      <pubDate>Sat, 29 Mar 2025 18:11:44 +0000</pubDate>
      <link>https://dev.to/adalbertuschris/frontend-evolution-rethinking-frontend-part-3-introduction-to-jmodel-5gjk</link>
      <guid>https://dev.to/adalbertuschris/frontend-evolution-rethinking-frontend-part-3-introduction-to-jmodel-5gjk</guid>
      <description>&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;jModel is a prototype library designed for managing client-side models (business logic) in a simple, flexible, and efficient way. It offers built-in tools for dependency injection, state management, and validation. This article explores the core concepts of jModel and its role in building modern web applications.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Minimalist API – Focused on simplicity and ease of use&lt;/li&gt;
&lt;li&gt;Own Dependency Injection (DI) – Supports lazy initialization, allowing dependencies to be registered only when first used&lt;/li&gt;
&lt;li&gt;Validation Tools – Built-in utilities to handle data validation (at the model level)&lt;/li&gt;
&lt;li&gt;State Management – Reactive model management with efficient updates&lt;/li&gt;
&lt;li&gt;Performance Optimization – Tree-shakable, ensuring only used code is included in the final bundle&lt;/li&gt;
&lt;li&gt;Framework Agnostic – Can be integrated into different frontend frameworks/libraries through adapters&lt;/li&gt;
&lt;li&gt;Cross-Platform Compatibility – Works on both browsers and Node.js without relying on browser-specific APIs&lt;/li&gt;
&lt;li&gt;Data Management – Enables switching between various storage and caching solutions depending on the platform&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Model Definition
&lt;/h2&gt;

&lt;p&gt;Similar to writing traditional services for business logic, the first step is to define a model object. A typical setup includes a token for dependency injection, lifecycle option, providers, and a model function factory.&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;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;userSource&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;TOKEN&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="nc"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;USER_SOURCE&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;LIFETIME&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="nx"&gt;Lifetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;scoped&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;PROVIDERS&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;USER_REPOSITORY&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="nx"&gt;userRepository&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;USER_STORE&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="nx"&gt;userStore&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;USER_MAP&lt;/span&gt;&lt;span class="p"&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;mapUserToString&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;FACTORY&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="nx"&gt;userSourceFactory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Key elements&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;TOKEN: A unique identifier used for dependency injection&lt;/li&gt;
&lt;li&gt;LIFETIME: Determines how long the model is retained in the dependency injection container (e.g., scoped, singleton).&lt;/li&gt;
&lt;li&gt;PROVIDERS: Specifies dependencies, which can be other models or standalone functions like &lt;code&gt;mapUserToString&lt;/code&gt;. It uses TOKENS as keys, allowing a single token (e.g., &lt;code&gt;USER_REPOSITORY&lt;/code&gt;) to have different implementations across models.&lt;/li&gt;
&lt;li&gt;FACTORY: Specifies how the model is created.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;userRepository&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;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;USER_REPOSITORY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Token&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;UserRepository&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="s1"&gt;USER_REPOSITORY&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;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;userRepository&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;TOKEN&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="nx"&gt;USER_REPOSITORY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;LIFETIME&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="nx"&gt;Lifetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;scoped&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;FACTORY&lt;/span&gt;&lt;span class="p"&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="na"&gt;get&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;userGet&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;getUserNames&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;userNamesGetAll&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;userSourceFactory&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;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;userSourceFactory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;inject&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;Context&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;setRandomUsername&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;refs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;inject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;USER_STORE&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;refs&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 model factory function provides access to the execution context, allowing to inject dependencies. Also all methods defined within it, such as &lt;code&gt;setRandomUsername&lt;/code&gt;, will execute within the model's context.&lt;/p&gt;

&lt;h2&gt;
  
  
  Execution Context
&lt;/h2&gt;

&lt;p&gt;Execution context (Context) has two methods:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;inject&lt;/strong&gt; - it allow to inject dependencies available in the same scope or singletones&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;execute&lt;/strong&gt; - it allow to execute different method in the same context&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;setRandomUsername&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;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;setRandomUsername&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;inject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;USER_STORE&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;randomUsername&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;getRandomUsername&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setUserName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;randomUsername&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;getRandomUsername&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;repository&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;inject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;USER_REPOSITORY&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;mapUserDataToString&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;inject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;USER_MAP&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;userNames&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;repository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;userNamesGetAll&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;mapUserDataToString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userNames&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the functions above, dependencies are injected from model providers such as &lt;code&gt;USER_STORE&lt;/code&gt;, &lt;code&gt;USER_REPOSITORY&lt;/code&gt;, and &lt;code&gt;USER_MAP&lt;/code&gt;. The execute function is also used to call &lt;code&gt;getRandomUsername&lt;/code&gt; within the same context as &lt;code&gt;setRandomUsername&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Reactive State Management
&lt;/h2&gt;

&lt;p&gt;jModel supports reactive state management which can be created by calling &lt;code&gt;createReactiveModel&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;userStoreFactory&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;userStoreFactory&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;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createReactiveModel&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&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;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getRef&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;schema&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;schema&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;setUserName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;refs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;name&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="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;getRef&lt;/code&gt; method allows to select fields that need to be observed for changes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Integration with UI Frameworks
&lt;/h2&gt;

&lt;p&gt;jModel can be easily integrated with UI frameworks like Angular by using &lt;code&gt;ngContextBuilder&lt;/code&gt; adapter.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Injectable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserComponentContext&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;ngContextBuilder&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;userSource&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;UserComponentContext usage&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;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserComponent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;inject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;UserComponentContext&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;userName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;refToSignal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;refs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nf"&gt;setRandomUsername&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setRandomUsername&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;refToSignal&lt;/code&gt; is another adapter which transform jModel reactive field into Angular signal&lt;/p&gt;

&lt;h2&gt;
  
  
  Model Validation
&lt;/h2&gt;

&lt;p&gt;jModel also includes built-in validation utilities.&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;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;userUpsertStoreFactory&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;userModel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createReactiveModel&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;$field&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;span class="na"&gt;validators&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;required&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="na"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;$field&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;span class="na"&gt;validators&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;required&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;userModel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getRefs&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;USER_UPSERT_STORE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="nx"&gt;Token&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;ReturnType&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;userUpsertStoreFactory&lt;/span&gt;&lt;span class="o"&gt;&amp;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="s1"&gt;USER_UPSERT_STORE&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;userUpsertStore&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;TOKEN&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="nx"&gt;USER_UPSERT_STORE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;LIFETIME&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="nx"&gt;Lifetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;scoped&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;FACTORY&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="nx"&gt;userUpsertStoreFactory&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;$field&lt;/code&gt; method allow to add validators to model fields.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;getRefs&lt;/code&gt; method transforms all fields into observable fields, enabling them to be tracked for changes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Model usage (with two way data binding)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Injectable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserUpsertComponentContext&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;ngContextBuilder&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;userUpsertSource&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserUpsertPageComponent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;ctx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;inject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;UserUpsertComponentContext&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;form&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;model&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="c1"&gt;// jModel library  provides special utilities such as: &lt;/span&gt;
  &lt;span class="c1"&gt;// isFirstChange, isValid, disable, isDisabled etc.&lt;/span&gt;
  &lt;span class="nf"&gt;isTouched&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ref&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="nf"&gt;isFirstChange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ref&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;Model usage in HTML&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;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;[(ngModel)]=&lt;/span&gt;&lt;span class="s"&gt;"form.firstName.$value"&lt;/span&gt;
    &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"firstName"&lt;/span&gt;
  &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  Value: {{ form.firstName.$value }}
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;*ngIf=&lt;/span&gt;&lt;span class="s"&gt;"isTouched(form.firstName) &amp;amp;&amp;amp; form.firstName.$errors"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    Errors: {{ form.firstName.$errors | json }}
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every ref field has &lt;code&gt;$value&lt;/code&gt; field which allow to get current value or set new one and  &lt;code&gt;$errors&lt;/code&gt; field which allow to get all validation errors.&lt;/p&gt;

&lt;p&gt;This is a brief introduction to the jModel library. Below, you'll find links to the project repository and an example application.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Project link:&lt;/strong&gt; &lt;a href="https://github.com/x-model/jmodel" rel="noopener noreferrer"&gt;https://github.com/x-model/jmodel&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;App example:&lt;/strong&gt; &lt;a href="https://github.com/x-model/jmodel/tree/develop/apps/swapp" rel="noopener noreferrer"&gt;https://github.com/x-model/jmodel/tree/develop/apps/swapp&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Would love to hear your thoughts!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>frontend</category>
      <category>programming</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Frontend Evolution — Rethinking Frontend - part 2</title>
      <dc:creator>Adalbertus Chris</dc:creator>
      <pubDate>Sat, 15 Mar 2025 14:02:51 +0000</pubDate>
      <link>https://dev.to/adalbertuschris/frontend-evolution-rethinking-frontend-part-2-491l</link>
      <guid>https://dev.to/adalbertuschris/frontend-evolution-rethinking-frontend-part-2-491l</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Based on feedback, I have refined the goals to bring more clarity to the concept of frontend evolution. The primary objective is to restructure Frontend Developer responsibilities to reduce complexity and improve efficiency.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Change Frontend Development Responsibilities?
&lt;/h3&gt;

&lt;p&gt;Currently, Frontend Developers handle too many responsibilities—UI implementation, business logic, state management, API handling, performance optimization, accessibility, and more. This overload increases complexity, slows down development, and blurs role boundaries.&lt;/p&gt;

&lt;h3&gt;
  
  
  Splitting Frontend Responsibilities: UI &amp;amp; Model
&lt;/h3&gt;

&lt;p&gt;To simplify frontend work, we can split frontend responsibilities into two distinct layers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;UI Layer (Presentation &amp;amp; Interaction)&lt;/li&gt;
&lt;li&gt;Model Layer (Business Logic &amp;amp; Data Handling)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once we establish this separation, we can determine who should handle each part.&lt;/p&gt;

&lt;h3&gt;
  
  
  Who Should Handle the UI Layer?
&lt;/h3&gt;

&lt;p&gt;The UI layer should remain simple, including HTML, CSS, and basic JavaScript for animations and data transformations. Since UI Designers already work on UI, their responsibilities can be slightly extended to include implementation (creating UI components).&lt;/p&gt;

&lt;p&gt;Understanding HTML and CSS doesn’t require deep programming skills, making it feasible for Web Designers to handle this part, especially with the assistance of AI tools. This allows for a more efficient workflow, where designers can directly translate their designs into functional UI components without relying on additional Frontend Developers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Who Should Handle the Model Layer?
&lt;/h3&gt;

&lt;p&gt;The model layer includes business logic, state management, API communication, validation, caching etc. Backend Developers already work on business logic and have strong programming skills. &lt;br&gt;
Since this layer is purely logic-based (no styling), Backend Developers can easily manage it, even in JS/TS (language has no big meaning when someone has programming skills).&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Doesn't Splitting Layers Alone Solve the Problem?
&lt;/h3&gt;

&lt;p&gt;Separating the model from the UI without redefining roles doesn’t simplify frontend development — it adds complexity and increases the workload for Frontend Developers. The key is not just separation but clear role definitions to ensure responsibilities are effectively distributed.&lt;/p&gt;

&lt;h3&gt;
  
  
  New Role Specializations in Web Development
&lt;/h3&gt;

&lt;p&gt;By following this structure, we can introduce clearer role definitions:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;UI/UX Developer&lt;/strong&gt; &lt;br&gt;
This role extends UI/UX Designers' responsibilities beyond just design, allowing them to implement components using HTML, CSS, and basic JavaScript. UI/UX Developers don’t need to worry about logic, they focus purely on UI implementation.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Create UI designs and UX workflows&lt;/li&gt;
&lt;li&gt;Implement UI components using HTML, CSS, and minimal JavaScript (for animations, transformations)&lt;/li&gt;
&lt;li&gt;Handle UI interactions (button clicks, transitions, hover effects, etc.)&lt;/li&gt;
&lt;li&gt;Ensure accessibility, responsiveness, and usability&lt;/li&gt;
&lt;li&gt;Integrate ready-made methods, services, and models provided by Model Developers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Benefits of this role:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Stronger collaboration between design &amp;amp; development – designers don’t just hand off static designs, they actively build UI components&lt;/li&gt;
&lt;li&gt;Reduces miscommunication – eliminates the extra layer of frontend developers, making collaboration more direct&lt;/li&gt;
&lt;li&gt;Faster development – UI/UX Developers work directly with Model Developers, reducing dependency on Frontend Developers&lt;/li&gt;
&lt;li&gt;Improves AI-assisted UI generation – having logic-free UI components makes it easier to automate UI generation in the future&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Model Developer&lt;/strong&gt;&lt;br&gt;
This role extends Backend Developers' responsibilities to include frontend business logic, state management, API handling, validations etc.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Focus on business logic (backend and frontend),&lt;/li&gt;
&lt;li&gt;Handle API calls, data fetching, state management, data transformations, validations, caching etc.&lt;/li&gt;
&lt;li&gt;Create services and utilities that UI components use&lt;/li&gt;
&lt;li&gt;Collaborate with UI/UX Developers to define proper models&lt;/li&gt;
&lt;li&gt;Manage frontend architecture, routing, and core features (with Frontend Developer support)&lt;/li&gt;
&lt;li&gt;Ensure performance optimization and frontend security (with Frontend Developer support)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Benefits of this role:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Data consistency across backend &amp;amp; frontend – Model Developers define and maintain data structures (models) across both layers&lt;/li&gt;
&lt;li&gt;Reduces miscommunication – eliminates the extra layer of Frontend Developers, making collaboration more direct&lt;/li&gt;
&lt;li&gt;Faster development and easier API Integration, better synchronization - Model Developers work directly with UI/UX Developers reducing dependency on Frontend Developers&lt;/li&gt;
&lt;li&gt;Having a single person who handle models ensures they stay in sync, API payloads are adjusted to UI requirements&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Frontend Developer / Lead / Architect / Mentor&lt;/strong&gt;&lt;br&gt;
A Frontend Developer ensures that UI/UX Developers and Model Developers follow best practices in frontend development. Switching to new roles without prior expertise in certain areas can be challenging, so guidance from experts is essential for a smooth transition.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Provide guidance to UI/UX Developers on creating well-structured and maintainable components&lt;/li&gt;
&lt;li&gt;Help Model Developers with frontend complexity (state management, reactivity etc.)&lt;/li&gt;
&lt;li&gt;Review &amp;amp; optimize frontend logic for performance and best practices&lt;/li&gt;
&lt;li&gt;Handle complex frontend scenarios (e.g., advanced state management, SSR, performance improvements)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In every team, we can have Backend Developers, Model Developers, UI/UX Developers, and a Frontend Developers. This specializations brings flexibility and scalability to Web Development.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Is This Role Specialization Better Than the Traditional Approach?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;This role specialization allows teams to be more structured, efficient, and scalable. It reduces the workload on Frontend Developers, improves collaboration, and makes it easier to adopt new technologies&lt;/li&gt;
&lt;li&gt;Improves team efficiency – reduces unnecessary communication and clarifies responsibilities&lt;/li&gt;
&lt;li&gt;Enhances specialization – each team member focuses on their strengths, reducing cognitive load&lt;/li&gt;
&lt;li&gt;Lighter UI frameworks – by removing logic from UI, frameworks can be leaner and focus only on rendering and interactions&lt;/li&gt;
&lt;li&gt;Design-to-code workflow is more direct – UI/UX Developers can instantly apply design adjustments without delays&lt;/li&gt;
&lt;li&gt;Ensure data consistency across the backend and frontend model layers with cleaner solutions&lt;/li&gt;
&lt;li&gt;Reduces UI-Model mistakes – clearer role separation minimizes miscommunication&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Challenges &amp;amp; Potential Issues
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;UI/UX Developers need some coding skills – HTML, CSS, and basic JavaScript should be part of their skill set. AI tools can assist in simplifying this learning curve.&lt;/li&gt;
&lt;li&gt;Risk of tight coupling between UI &amp;amp; backend logic – a clear separation of concerns is necessary. Frontend Developers should review implementations to prevent coupling issues&lt;/li&gt;
&lt;li&gt;Handling complex tasks – Frontend Developers still play a role in advanced scenarios&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What's Next?
&lt;/h3&gt;

&lt;p&gt;When the roles are defined, the next step is to focus on tools. UI Layer tools should be easy to use for UI/UX Developers, and Model Layer tools should be suitable for Model Developers. Currently I'm focusing on building Model tools (UI Model Library).&lt;/p&gt;

&lt;p&gt;The next article will take a closer look at the UI Model Library, which trying to provide a simple, framework-independent way to manage models in frontend applications.&lt;/p&gt;

&lt;p&gt;Would love to hear your thoughts! 🚀&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>frontend</category>
      <category>backend</category>
    </item>
    <item>
      <title>Frontend Evolution - Rethinking Frontend</title>
      <dc:creator>Adalbertus Chris</dc:creator>
      <pubDate>Mon, 24 Feb 2025 20:29:50 +0000</pubDate>
      <link>https://dev.to/adalbertuschris/frontend-evolution-rethinking-frontend-4iha</link>
      <guid>https://dev.to/adalbertuschris/frontend-evolution-rethinking-frontend-4iha</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Frontend development has evolved significantly over the years, becoming increasingly complex. Frontend developers must be familiar with various frameworks, libraries, tools, and solutions. They need expertise in multiple areas, including UI, business logic, design tools etc. This complexity leads to blurred boundaries between responsibilities, making development slower, more expensive, and harder to maintain.&lt;/p&gt;

&lt;p&gt;This article explores the concept of frontend evolution, advocating for a clear separation between the UI and model layers to improve efficiency, maintainability, and scalability.&lt;/p&gt;

&lt;h2&gt;
  
  
  Current Frontend Challenges
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Mixing Model with UI&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Many frameworks tightly integrate logic, state management, validation, API handling within UI components. This coupling makes it difficult to refactor and adapt to new technologies efficiently.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Technology Stack Complexity&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Developers must learn and work with numerous frameworks, libraries, and tools.&lt;/p&gt;

&lt;p&gt;Redundant libraries exist across UI frameworks, each handling similar tasks e.g., state management (Zustand, Redux, MobX, VueX, Pinia, NGRX, NGXS, Akita etc.), validation, API communication.&lt;/p&gt;

&lt;p&gt;We have one programming language but numerous solutions, with many UI frameworks differing in many cases only in syntax and coding style.&lt;/p&gt;

&lt;p&gt;Too many solutions make slows down the progress of the frontend part.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Frontend Developer Skills and Responsibilities&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Currently, frontend developers must be skilled in multiple areas: working with design tools, know frontend frameworks, know concepts like DI, reactivity, browser behavior, REST API principles, has knowledge about accessibility, responsive UI, security, performance optimization and more.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Inefficient Collaboration&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Frontend developers constantly need to sync with designers and backend developers. Misunderstandings can happen—sometimes the backend doesn't provide exactly what's needed, or designs are missing details, leading to extra discussions.&lt;/p&gt;

&lt;p&gt;Frontend developers often act as mediators, making sure designs are feasible while coordinating with backend teams to connect everything properly. This back-and-forth takes time, slows development, and reduces efficiency.&lt;/p&gt;

&lt;h2&gt;
  
  
  Goals
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Separate model from UI&lt;/strong&gt; – Clearly separate the data logic from how it's presented in the user interface.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Make frontend simpler&lt;/strong&gt; – Reduce unnecessary complexity for easier development. Reduce reliance on multiple libraries that serve the same purpose.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;More precise role specializations&lt;/strong&gt; – Define clearer roles to reduce cognitive load. Make each role easier by reducing what they need to handle.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Improve collaboration&lt;/strong&gt; – Make teamwork more efficient by reducing unnecessary communication, clarifying responsibilities, and ensuring smoother coordination between team members.&lt;/p&gt;

&lt;h2&gt;
  
  
  Proposed Solutions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Separate UI and Model&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;UI Layer (Frontend UI)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Focuses solely on rendering, styling, animations, and user interactions.&lt;/li&gt;
&lt;li&gt;Handled by UI/UX developers with minimal programming expertise.&lt;/li&gt;
&lt;li&gt;Can be AI-assisted to generate components and establish links with models.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Model Layer (Frontend Model + Backend)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Focuses on state management, validation, API interactions, caching, business logic.&lt;/li&gt;
&lt;li&gt;Developed by model developers, ensuring consistency with backend logic.&lt;/li&gt;
&lt;/ul&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%2Favlb1xw8exmws9yw78bx.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%2Favlb1xw8exmws9yw78bx.png" alt="Frontent, Backend diagram" width="800" height="278"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;New Role Specialization in Web Development&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;UX/UI Developer (Responsible for UI Layer)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Design preparation&lt;/li&gt;
&lt;li&gt;Build views using HTML, CSS, basic JavaScript, and UI framework syntax&lt;/li&gt;
&lt;li&gt;Ensure accessibility, responsiveness, and compliance with UX best practices&lt;/li&gt;
&lt;li&gt;Link UI components with the application's model without implementing business logic&lt;/li&gt;
&lt;li&gt;Can leverage AI-assisted tools&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Model Developer (Responsible for Model Layer)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Focuses on business logic&lt;/li&gt;
&lt;li&gt;Handles both backend and frontend model responsibilities - works on typical backend tasks and creates and manages the frontend application model including authorization, state management, validation, caching, data synchronization with the API&lt;/li&gt;
&lt;li&gt;Ensures data consistency between frontend and backend&lt;/li&gt;
&lt;li&gt;Troubleshoots issues with data flow and application performance&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Frontend Developer (Optional)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Acts as a bridge between UI and model when needed in complex applications&lt;/li&gt;
&lt;li&gt;Has advanced knowledge of frontend frameworks and integrations&lt;/li&gt;
&lt;/ul&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%2Fvzw70crtlmoyrt3mhukx.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%2Fvzw70crtlmoyrt3mhukx.png" alt="UI layer, Model layer" width="800" height="311"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Benefits of this approach
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Separating the model (logic) from the UI makes the UI simpler, enhances maintainability&lt;/li&gt;
&lt;li&gt;UI frameworks/libraries can become lighter and more focused on rendering and interactions&lt;/li&gt;
&lt;li&gt;A separate model allows for creating a universal, reusable model that can work across different UI frameworks (React, Angular, Vue, Svelte) and platforms (e.g., web, mobile)&lt;/li&gt;
&lt;li&gt;By separating the model from the UI, changing UI technologies is more straightforward, enabling easier adoption of new technologies or switching between UI frameworks without having to rebuild the entire application&lt;/li&gt;
&lt;li&gt;It can reduce development time, enhance coordination and collaboration, improve productivity, and lower costs by eliminating the need for an additional role between the UI and model (no “mediator” between the UI and backend)&lt;/li&gt;
&lt;li&gt;Teams can work more efficiently, when each member focusing on their strengths and specializations, which reduces cognitive load — UI Developers focus on design, appearance, and interactions, while Model Developers handle business logic and data management&lt;/li&gt;
&lt;li&gt;Sometimes, designs are hard to turn into HTML and styles. If one person handles both, we avoid wasting time redoing things. Designs are usually static, but when the UI connects to data, style adjustments can be needed and UX/UI Developers can handle it at once&lt;/li&gt;
&lt;li&gt;The Model Developer doesn’t have to worry about styling, responsiveness, or UX. They focus on tasks like data transformation and validation, which are more aligned with backend work. When one person handles specific tasks like endpoint models, authorization, and validation, there's no need for constant consultations on how to deliver data, coordination, or solution explanations. The only requirement is to establish a clear model contract with the UX/UI Developer&lt;/li&gt;
&lt;li&gt;Backend developers can easily transition into the role of Model Developer thanks to their expertise in business logic&lt;/li&gt;
&lt;li&gt;Clearer specializations enhance code quality and the final product—it's challenging for one person, like a frontend developer, to master all areas of web development. Specialists in each domain produce higher-quality code due to their deep expertise&lt;/li&gt;
&lt;li&gt;A clearer role division reduces mistakes between the UI and model layers&lt;/li&gt;
&lt;li&gt;It can reduce cognitive load and the learning curve for each developer&lt;/li&gt;
&lt;li&gt;In some companies, there isn't enough full-time work for designers, but it’s great to have one. However, with a UI/UX developer, the company always has access to design expertise&lt;/li&gt;
&lt;li&gt;Separating the model from the UI (browser APIs) opens the door for WASM adoption:

&lt;ul&gt;
&lt;li&gt;The model can be written in any WebAssembly-compatible language (e.g., Rust, Go, C++, Python)&lt;/li&gt;
&lt;li&gt;This can improve performance, as the model runs natively in the browser&lt;/li&gt;
&lt;li&gt;Maybe there will be possibility to sharing logic between the backend and frontend, reducing code duplication (e.g., types, validations) and saving time spending on writing the same things&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;To make this separation I started prototyping UI Model Library in JS/TS for better visualization what Model Layer should include&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;UI Model Library - Basic requirements&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Include built-in Dependency Injection, validation, state management, caching, API handling, reactivity&lt;/li&gt;
&lt;li&gt;Universal solution that works with various UI frameworks&lt;/li&gt;
&lt;li&gt;APIs should be standardized (e.g., method names, data consumption), similar to how web standards work for browsers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The next article will explore the UI Model library in more detail.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>frontend</category>
      <category>ux</category>
      <category>programming</category>
    </item>
    <item>
      <title>Fragments — incoming new feature for Angular Developers</title>
      <dc:creator>Adalbertus Chris</dc:creator>
      <pubDate>Tue, 21 Nov 2023 22:40:36 +0000</pubDate>
      <link>https://dev.to/adalbertuschris/fragments-incoming-new-feature-for-angular-developers-nm5</link>
      <guid>https://dev.to/adalbertuschris/fragments-incoming-new-feature-for-angular-developers-nm5</guid>
      <description>&lt;p&gt;&lt;strong&gt;What are fragments?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A fragment is an independent block of logic. In simpler terms, a fragment is just a method. Just like the service allows for the injection of dependencies, can maintain its own state, and has access to the executing context — such as other fragments and methods defined within that context. Let’s compare the standard approach using services with the use of fragments.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AXoPW-xJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3mr0oyzhningybqv5ocv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AXoPW-xJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3mr0oyzhningybqv5ocv.png" alt="standard vs fragment approach" width="800" height="366"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In picture above you can notice that approach with fragments is more granular, allowing us to split our code into smaller blocks for flexible use.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What are the benefits of using fragments?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example 1&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let’s assume we have 3 services: Service A, Service B, and Service C as on picture below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MSUkc-Yl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/klcklagdkmbpo3cblrwo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MSUkc-Yl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/klcklagdkmbpo3cblrwo.png" alt="Example 1.1" width="800" height="374"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We received a new requirement to use our method C1 in the app component. Initially, the thought was to inject Service C into the app component. However, this would lead to a larger main bundle containing unnecessary code (such as method A1 and method B1), which is not desirable.&lt;/p&gt;

&lt;p&gt;Another option is to move method C1 to new service and let’s assume that method C1 relies on method B2 from Service B. So this approach still require injecting Service B and would consequently include unnecessary code (specifically method B1) in the main bundle. Additionally, we cannot move method B2 to this new service, because we also use it in a different place.&lt;/p&gt;

&lt;p&gt;Finally we decided to create 2 new services: Service D with method C1, Service E with method B2 (see picture below). We ended up with services, each having only a single method and subsequently, our next step is to properly register all services in the providers and ensure their correct injection.&lt;/p&gt;

&lt;p&gt;This rebuilding process consumed a significant amount of time and posed a risk of introducing bugs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iRwP7qEC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tajm506b7fzw4kwz1km3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iRwP7qEC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tajm506b7fzw4kwz1km3.png" alt="Example 1.2" width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We ended up with services, each having only a single method, so a more effective strategy would be to use fragments. This approach should prevents situations like the one mentioned above. When new logic is required, we simply add our new fragment to a specific context, leaving the remaining code untouched. If there’s a need for different behavior (logic) within a context, you have the option to replace fragments with others.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example 2&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let’s consider the scenario where we have three services: Service A, Service B, and Service C, each with some repetitive code and we decided to introduce inheritance for them. We created base class with one method X and also we have few fields there, which every service use. However, we have to add new feature which requires the addition of two services: Service D and Service E. These services need a different method than method X, but also use the same fields from base class. What options are available to us? We’re unable to introduce a new base class due to the limitation of inheriting from only one class. An alternative possibility is introducing an additional base parent class (as shown in the picture below):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VUd_C89W--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e1olj3orcy25bmmslg7z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VUd_C89W--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e1olj3orcy25bmmslg7z.png" alt="Example 2" width="800" height="441"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s say we stick with this solution, but during our app’s development, we need to add two more services: F and G. These services operate with different logic and do not use all fields from the base class. We realize that inheritance wasn’t the most suitable choice and end up rewriting everything for example into separate base services, each with a single method. This process consumed again a significant amount of time and posed a risk of introducing bugs.&lt;/p&gt;

&lt;p&gt;In the fragment-based approach, we’re able to define three distinct fragments and effortlessly include them in the Context. This eliminates the need to spend time contemplating a better solution such as inheritance or composition.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example 3&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let’s assume that we wrote apiService as on picture below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iT5Y3RC7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ob2su4356nd09f3u08t7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iT5Y3RC7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ob2su4356nd09f3u08t7.png" alt="Example 3.1" width="800" height="367"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The code repeats, particularly in result mapping and it can be identical across all upcoming API services. Although a base class could resolve this, it might lead to a scenario similar to &lt;strong&gt;Example 2&lt;/strong&gt;. Therefore, opting to use Fragments is a more preferable solution. The image below shows code using fragments:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ruGnZXa0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yzcbkmjnt8ci6m07ov34.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ruGnZXa0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yzcbkmjnt8ci6m07ov34.png" alt="Example 3.2" width="800" height="548"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Each new API file will contain only a few lines of code, and we can easily modify its implementation if needed.&lt;/p&gt;

&lt;p&gt;You’ve seen the advantages of using fragments in the examples above, but there’s more to explore. Let’s take a deeper dive into fragments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fragment templates&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Each fragment has to be created from a template. In &lt;strong&gt;Example 3&lt;/strong&gt;, we created our fragment using the apiFragment template. Templates help us efficiently handle repetitive behaviors and activities. Currently, the fragments library contains a few predefined templates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;pureFragment&lt;/strong&gt; — it executes the fragment function, if there’s a change in the fragment input&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;memoFragment&lt;/strong&gt; — executes the fragment function once, remembers the result, and returns the memoized result for another executions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;apiFragment&lt;/strong&gt; — contains built-in tools for handling API communication&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;storeFragment&lt;/strong&gt; — contains built-in tools for managing state, it shares similar behavior with memoFragment&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;formFragment&lt;/strong&gt; — contains built-in tools for managing forms, it shares similar behavior with memoFragment&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Currently, we have only a few predefined templates, but new ones, like debounceFragment, will be added in the future. The library also allows us to create custom templates using a dedicated builder API, providing the flexibility to construct templates tailored to our specific requirements.&lt;/p&gt;

&lt;p&gt;In this example below, you can see how we can use the &lt;strong&gt;formFragment&lt;/strong&gt; template to create our fragment&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sQ_mWIuk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mfwx3gcsle1pah0upnn9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sQ_mWIuk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mfwx3gcsle1pah0upnn9.png" alt="form fragment example" width="800" height="277"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As mentioned before, the &lt;strong&gt;formFragment&lt;/strong&gt; template comes with built-in tools necessary for creating and managing forms. This eliminates the need to create a service and inject all dependencies into it (such as &lt;em&gt;&lt;strong&gt;formBuilder&lt;/strong&gt;&lt;/em&gt; in this case). Additionally, it includes the &lt;em&gt;&lt;strong&gt;_observe&lt;/strong&gt;&lt;/em&gt; method allowing for subscription to form value changes, and it automatically unsubscribes it when the fragment is destroyed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Context&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The context is also a crucial element in fragments, as it acts as the connection between them. Let’s explore code below to see how context can be used:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--E07tq0-9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t75rzwwxgoqxtg9hamjs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--E07tq0-9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t75rzwwxgoqxtg9hamjs.png" alt="context example" width="800" height="264"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see above Context connects fragments. When different behavior is needed, it’s easy to replace fragments. Creating and using a Context is similar to services: adding it to providers, injecting it into components, and call actions.&lt;/p&gt;

&lt;p&gt;In fragments, they can access the context where they’re executed. See the picture below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Arvo6vBv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uhzhcahfk7k9r5bwrogf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Arvo6vBv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uhzhcahfk7k9r5bwrogf.png" alt="fragment with context - example" width="800" height="369"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the &lt;em&gt;&lt;strong&gt;draw$&lt;/strong&gt;&lt;/em&gt; fragment, we have access to the &lt;em&gt;&lt;strong&gt;store$&lt;/strong&gt;&lt;/em&gt; fragment, &lt;em&gt;&lt;strong&gt;compare&lt;/strong&gt;&lt;/em&gt; method. The &lt;em&gt;&lt;strong&gt;compare&lt;/strong&gt;&lt;/em&gt; method may have different implementations based on the context it’s used within. Therefore, in fragments, we’re not limited to one specific type of context, we can use abstraction, as shown in the image above. For instance, within the &lt;em&gt;&lt;strong&gt;draw$&lt;/strong&gt;&lt;/em&gt; fragment, we can use either &lt;strong&gt;PeopleComponentContext&lt;/strong&gt; or &lt;strong&gt;StarshipComponentContext&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Every context needs to be registered in providers. This allows us to manage the lifespan of the context and all the fragments included within it. By adding the context to component providers, both the context and its fragments will remain alive as long as the component exists.&lt;/p&gt;

&lt;p&gt;Fragments is an open-source library that will soon be available in beta version on npm. You can find the entire code at &lt;a href="https://github.com/webfragments"&gt;https://github.com/webfragments&lt;/a&gt;. I encourage leaving feedback, opinions, or any other ideas in the comments section.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Summary&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Working with fragments can be simpler than using the standard service approach. It eliminates complexities like classes and inheritance. This idea makes code more flexible, by splitting it into smaller parts can improve performance. We can create shareable fragments, build our libraries, and reuse them in various projects. Fragments are also tree-shakeable.&lt;/p&gt;

</description>
      <category>angular</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
