<?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: Elanat Framework</title>
    <description>The latest articles on DEV Community by Elanat Framework (@elanatframework).</description>
    <link>https://dev.to/elanatframework</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1106033%2Fd06a8be3-da79-4eeb-ad53-1401e09446cc.png</url>
      <title>DEV Community: Elanat Framework</title>
      <link>https://dev.to/elanatframework</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/elanatframework"/>
    <language>en</language>
    <item>
      <title>WebForms Core 2.2 Development Has Begun</title>
      <dc:creator>Elanat Framework</dc:creator>
      <pubDate>Thu, 24 Sep 2026 22:54:13 +0000</pubDate>
      <link>https://dev.to/elanatframework/webforms-core-22-development-has-begun-4a2b</link>
      <guid>https://dev.to/elanatframework/webforms-core-22-development-has-begun-4a2b</guid>
      <description>&lt;h2&gt;
  
  
  A New Stateless Architecture for Server-Orchestrated UI
&lt;/h2&gt;

&lt;p&gt;Unlike many server-driven UI approaches, including &lt;strong&gt;Blazor Server&lt;/strong&gt;, &lt;a href="https://github.com/webforms-core" rel="noopener noreferrer"&gt;WebForms Core&lt;/a&gt; introduces a fundamentally different architectural model: &lt;strong&gt;server-orchestrated UI built on a stateless server and server-defined UI structure&lt;/strong&gt;. While Blazor Server maintains a stateful server-side circuit for each connected browser context, WebForms Core does not require the server to maintain a persistent component tree, render tree, or mirrored DOM state for each user. Instead, the server defines UI operations through the WebForms class and generates commands that WebFormsJS executes against the actual HTML document in the browser. This creates a clean separation between &lt;strong&gt;server-defined UI structure and client-side DOM execution&lt;/strong&gt;, while preserving the stateless nature of the server architecture. The result is a lightweight and scalable model in which the server orchestrates the interface without becoming the permanent owner of its browser-side state. WebForms Core therefore approaches Server-Driven UI from a different direction: not by keeping the UI alive on the server, but by &lt;strong&gt;describing and orchestrating UI transformations from a stateless server&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;WebForms Core 2.2 is focused on taking the server-orchestrated UI model to a higher level. The goal is not simply to add more commands, but to provide better mechanisms for &lt;strong&gt;rendering, state management, data transformation, formatting, arithmetic operations, and extensibility&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The direction of 2.2 is to make complex UI operations more expressive while keeping the WebForms Core architecture server-oriented, HTML-native, and independent of a separate frontend framework.&lt;/p&gt;

&lt;h2&gt;
  
  
  A More Expressive WebForms Model
&lt;/h2&gt;

&lt;p&gt;WebForms Core uses a server-side WebForms class to generate commands that are executed by WebFormsJS in the browser:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Server
   ↓
WebForms
   ↓
Commands
   ↓
WebFormsJS
   ↓
HTML DOM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With 2.2, the focus is moving toward higher-level operations.&lt;/p&gt;

&lt;p&gt;Instead of requiring developers to construct every transformation from small DOM commands, WebForms Core can increasingly perform formatting, text processing, arithmetic calculations, rendering operations, state detection, and other transformations directly within the WebForms execution model.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgy5rtfvkjie5mr8ty8x7.jpg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgy5rtfvkjie5mr8ty8x7.jpg" alt="WebForms Core 2.2" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Isolated DOM Operations
&lt;/h2&gt;

&lt;p&gt;One of the new capabilities in WebForms Core 2.2 is &lt;code&gt;Isole&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Isole&lt;/code&gt; provides a high-level abstraction for working with the Transient DOM. It automatically performs the transient DOM initialization and completion around a group of operations.&lt;/p&gt;

&lt;p&gt;This removes the need to manually manage the underlying &lt;code&gt;StartTransientDOM&lt;/code&gt; and &lt;code&gt;EndTransientDOM&lt;/code&gt; operations.&lt;/p&gt;

&lt;p&gt;The result is a simpler way to isolate a complex group of DOM transformations while keeping them within the existing WebForms execution hierarchy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rendering and State Management
&lt;/h2&gt;

&lt;p&gt;Rendering and state management are among the most important architectural directions in WebForms Core 2.2.&lt;/p&gt;

&lt;p&gt;Complex UI updates are rarely just a single DOM operation. A rendering process may involve multiple transformations, temporary states, repeated template binding, state detection, and potentially restoring the previous state.&lt;/p&gt;

&lt;p&gt;WebForms Core 2.2 is therefore introducing mechanisms that allow these operations to be treated as part of a larger rendering process.&lt;/p&gt;

&lt;h3&gt;
  
  
  Snapshot and Rollback
&lt;/h3&gt;

&lt;p&gt;Snapshot and rollback provide a mechanism for preserving and restoring the HTML state of an element.&lt;/p&gt;

&lt;p&gt;A snapshot can preserve the &lt;code&gt;outerHTML&lt;/code&gt; of a target before a transformation. The element can then be modified, rendered, or repeatedly bound to a template. If necessary, the previous state can be restored.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Current DOM State
    ↓
Snapshot
    ↓
Transform
    ↓
New DOM State
    ↓
Rollback
    ↓
Previous DOM State
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is particularly useful for complex rendering scenarios where several operations need to work against the same original state.&lt;/p&gt;

&lt;p&gt;It also provides a foundation for higher-level rendering operations in which snapshot and rollback do not need to be explicitly managed by the developer.&lt;/p&gt;

&lt;h3&gt;
  
  
  Hash-Based State Detection
&lt;/h3&gt;

&lt;p&gt;WebForms Core 2.2 also introduces &lt;code&gt;GetTagHash&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The operation generates a hash from the HTML representation of a tag. The hash can be stored and later compared with a new hash to determine whether the HTML state has changed.&lt;/p&gt;

&lt;p&gt;This provides a lightweight mechanism for detecting UI state changes without requiring the server to maintain a mirror of the browser DOM.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HTML
 ↓
GetTagHash
 ↓
Hash
 ↓
Store
 ↓
Later
 ↓
GetTagHash
 ↓
Compare
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This capability can become useful for state validation, conditional rendering, optimization, and future rendering mechanisms.&lt;/p&gt;

&lt;h3&gt;
  
  
  Rendering Without Mirroring the DOM
&lt;/h3&gt;

&lt;p&gt;These mechanisms follow an important principle of WebForms Core.&lt;/p&gt;

&lt;p&gt;The server does not need to maintain a complete representation of the browser's DOM.&lt;/p&gt;

&lt;p&gt;Instead, the server can describe a transformation, while WebFormsJS performs that transformation against the actual HTML document in the browser.&lt;/p&gt;

&lt;p&gt;This keeps the architecture server-orchestrated without turning the server into a permanent DOM state manager.&lt;/p&gt;

&lt;h2&gt;
  
  
  Formatting Data
&lt;/h2&gt;

&lt;p&gt;WebForms Core 2.2 introduces formatting operations for cached and saved values.&lt;/p&gt;

&lt;p&gt;This allows common formatting tasks to be performed directly inside the WebForms execution model.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;4200
↓
4,200
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A time value can also be normalized:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;23:1:8
↓
23:01:08
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Formatting can use regular expressions, making the mechanism useful for both simple formatting and more advanced text transformations.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(\d)(?=(\d{3})+$)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;can be used to transform a numeric string into a thousands-separated representation.&lt;/p&gt;

&lt;p&gt;This removes the need for repetitive conditional operations for common formatting scenarios.&lt;/p&gt;

&lt;h2&gt;
  
  
  Arithmetic Operations
&lt;/h2&gt;

&lt;p&gt;WebForms Core 2.2 also brings arithmetic operations directly into the WebForms command model.&lt;/p&gt;

&lt;p&gt;The supported operations include:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;+
-
*
/
%
//
**
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These operations make it possible to perform calculations directly on values used by WebForms commands.&lt;/p&gt;

&lt;p&gt;For example, a value can be increased, decreased, multiplied, divided, processed with modulo or integer division, or used in an exponentiation operation without requiring custom JavaScript.&lt;/p&gt;

&lt;p&gt;This is particularly useful when arithmetic is part of a larger server-orchestrated UI operation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Text Operations
&lt;/h2&gt;

&lt;p&gt;Text operations are another significant part of WebForms Core 2.2.&lt;/p&gt;

&lt;p&gt;Instead of requiring developers to repeatedly save intermediate values and manually manipulate strings, WebForms Core can perform common string operations directly within the WebForms execution flow.&lt;/p&gt;

&lt;p&gt;Operations include capabilities such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Substring
TextBefore
TextAfter
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and other string transformations.&lt;/p&gt;

&lt;p&gt;These operations make it possible to extract and transform parts of values directly in WebForms commands.&lt;/p&gt;

&lt;p&gt;For example, a value can be processed by extracting a specific substring, obtaining the text before or after a specified value, and then passing the result to another operation.&lt;/p&gt;

&lt;p&gt;This creates a much more expressive data-transformation model:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Fetch
  ↓
Text Operation
  ↓
Arithmetic
  ↓
Format
  ↓
Render
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The significance is not the individual string methods themselves. The important part is that &lt;strong&gt;data transformation becomes a native part of the WebForms execution model&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Regex-Based Tag Selection
&lt;/h2&gt;

&lt;p&gt;WebForms Core 2.2 also introduces the ability to select tags using regular expressions against their HTML representation.&lt;/p&gt;

&lt;p&gt;This provides another mechanism for locating elements when conventional selectors are not sufficient.&lt;/p&gt;

&lt;p&gt;A developer can work with the HTML representation of elements and use a regular expression to identify matching tags for further operations.&lt;/p&gt;

&lt;p&gt;This extends the selection capabilities of WebForms Core beyond conventional CSS-oriented targeting.&lt;/p&gt;

&lt;h2&gt;
  
  
  Comments and Debugging
&lt;/h2&gt;

&lt;p&gt;A &lt;code&gt;Comment&lt;/code&gt; capability has also been introduced.&lt;/p&gt;

&lt;p&gt;It allows developers to place comments within the generated WebForms command structure.&lt;/p&gt;

&lt;p&gt;This is useful when inspecting generated Action Controls and understanding why a particular sequence of commands exists.&lt;/p&gt;

&lt;p&gt;For complex WebForms classes, comments can make the generated command structure easier to understand and debug.&lt;/p&gt;

&lt;p&gt;The feature is intentionally simple, but it becomes increasingly useful as WebForms classes contain more sophisticated rendering and transformation logic.&lt;/p&gt;

&lt;h2&gt;
  
  
  Middleware
&lt;/h2&gt;

&lt;p&gt;WebForms Core 2.2 is also moving toward a middleware-based extension mechanism.&lt;/p&gt;

&lt;p&gt;The purpose is to allow developers to add specialized JavaScript capabilities without modifying the WebFormsJS core.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseMiddleware&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/js/image-quality.js"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A middleware can participate in a processing stage and modify data before it continues through the normal execution flow.&lt;/p&gt;

&lt;p&gt;For example, an image-quality middleware could process uploaded images before they are sent:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FormData
   ↓
Image Quality Middleware
   ↓
XMLHttp.send()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes specialized capabilities possible as independent modules.&lt;/p&gt;

&lt;p&gt;Image processing is only one example. Similar middleware modules could provide compression, client-side transformations, specialized controls, or other browser capabilities.&lt;/p&gt;

&lt;p&gt;The important point is that middleware extends the existing WebForms Core architecture rather than introducing a separate execution model.&lt;/p&gt;

&lt;h2&gt;
  
  
  From Commands to Operations
&lt;/h2&gt;

&lt;p&gt;One of the broader goals of WebForms Core 2.2 is to increase the abstraction level of the WebForms language.&lt;/p&gt;

&lt;p&gt;A WebForms class can increasingly express operations such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Format
Arithmetic
Text Processing
Rendering
State Detection
Snapshot
Rollback
Middleware
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;rather than implementing every behavior as a collection of low-level DOM commands.&lt;/p&gt;

&lt;p&gt;This makes the WebForms class more expressive while preserving the underlying Commander-Executor architecture.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Server-Orchestrated Rendering Architecture
&lt;/h2&gt;

&lt;p&gt;WebForms Core 2.2 continues the evolution of WebForms Core as a &lt;strong&gt;Server-Orchestrated UI technology&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The server remains responsible for describing UI operations through the WebForms class and generated commands.&lt;/p&gt;

&lt;p&gt;WebFormsJS remains responsible for executing those commands against the browser's actual HTML DOM.&lt;/p&gt;

&lt;p&gt;The architecture can therefore be represented as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Server
   ↓
WebForms Class
   ↓
Server Commands
   ↓
WebFormsJS
   ↓
HTML DOM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The new capabilities in 2.2 add higher-level layers around this architecture:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Data
 ↓
Transformation
 ↓
Formatting
 ↓
Rendering
 ↓
State Detection
 ↓
DOM Execution
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This allows WebForms Core to handle increasingly complex interactive interfaces without requiring a separate frontend application or a client-side virtual representation of the UI.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Direction of WebForms Core 2.2
&lt;/h2&gt;

&lt;p&gt;WebForms Core 2.2 is still under development, so additional capabilities and API refinements may be introduced during development.&lt;/p&gt;

&lt;p&gt;However, the direction is already clear.&lt;/p&gt;

&lt;p&gt;The focus is moving from individual DOM manipulation toward a more complete model for &lt;strong&gt;server-orchestrated rendering, data transformation, state management, and extensibility&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The objective is to make complex interactive web applications easier to build while keeping the architecture:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Server-oriented&lt;/li&gt;
&lt;li&gt;HTML-native&lt;/li&gt;
&lt;li&gt;Stateless at the application architecture level&lt;/li&gt;
&lt;li&gt;RESTful&lt;/li&gt;
&lt;li&gt;Compatible with HTTP, WebSocket, and SSE&lt;/li&gt;
&lt;li&gt;Independent of a separate frontend framework&lt;/li&gt;
&lt;li&gt;Extensible through WebForms and WebFormsJS&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;WebForms Core 2.2 is not simply another collection of commands.&lt;/p&gt;

&lt;p&gt;It is an effort to build a more expressive foundation for &lt;strong&gt;Server-Orchestrated UI&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Related links
&lt;/h2&gt;

&lt;p&gt;On Elanat:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://elanat.net/webforms-core" rel="noopener noreferrer"&gt;WebForms Core Page&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://elanat.net/webforms-js" rel="noopener noreferrer"&gt;WebFormsJS Page&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On GitHub:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/webforms-core" rel="noopener noreferrer"&gt;WebForms Core Organizations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/webforms-core/Web_forms" rel="noopener noreferrer"&gt;WebFormsJS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/webforms-core/Web_forms_classes" rel="noopener noreferrer"&gt;WebForms Classes&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>news</category>
      <category>architecture</category>
      <category>frontend</category>
      <category>webformscore</category>
    </item>
    <item>
      <title>Elanat CMS Will Be Retired After Version 2.2: Introducing Gloria, a New Generation CMS</title>
      <dc:creator>Elanat Framework</dc:creator>
      <pubDate>Wed, 23 Sep 2026 20:46:24 +0000</pubDate>
      <link>https://dev.to/elanatframework/elanat-cms-will-be-retired-after-version-22-introducing-gloria-a-new-generation-cms-54cf</link>
      <guid>https://dev.to/elanatframework/elanat-cms-will-be-retired-after-version-22-introducing-gloria-a-new-generation-cms-54cf</guid>
      <description>&lt;p&gt;Elanat has made an important decision regarding the future of its content management system.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Elanat CMS 2.2 will be the final version of Elanat CMS. After version 2.2, Elanat CMS will be permanently retired and no new versions will be released.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This decision does not mean that Elanat is leaving the CMS space. Instead, we have decided to begin a new CMS project with a new name: &lt;strong&gt;Gloria&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Gloria will be a new generation CMS built from the ground up using the latest versions of .NET, the &lt;strong&gt;CodeBehind Framework&lt;/strong&gt;, and &lt;strong&gt;WebForms Core&lt;/strong&gt; technology.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Are We Retiring Elanat CMS?
&lt;/h2&gt;

&lt;p&gt;Elanat CMS has become a very large software system.&lt;/p&gt;

&lt;p&gt;The current project contains approximately:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;2,894 files&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;1,667 folders&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The size of the project is not itself a problem. In fact, this size reflects the amount of functionality and structure that has been developed in Elanat CMS over the years.&lt;/p&gt;

&lt;p&gt;The real challenge is the cost of making fundamental architectural changes to an already large system.&lt;/p&gt;

&lt;p&gt;Elanat CMS was originally designed around an &lt;strong&gt;SSR architecture with vanilla JavaScript&lt;/strong&gt; for client-side interaction. The system also contains many structures that were appropriate for its original architecture and development period.&lt;/p&gt;

&lt;p&gt;Changing fundamental parts of such a large system is possible. We could continue modifying Elanat CMS and gradually replace its internal structures.&lt;/p&gt;

&lt;p&gt;However, we reached the point where continuing to modify the existing system would require increasingly complex changes.&lt;/p&gt;

&lt;p&gt;Instead of continuously modifying an old architecture, we decided that it would be more appropriate to build a new system from the beginning.&lt;/p&gt;

&lt;h2&gt;
  
  
  From Elanat CMS to Gloria
&lt;/h2&gt;

&lt;p&gt;The new system will be called &lt;strong&gt;Gloria&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Gloria will not simply be a new version of Elanat CMS.&lt;/p&gt;

&lt;p&gt;It will be a new CMS project with a new architectural foundation.&lt;/p&gt;

&lt;p&gt;The goal is to use the latest versions of .NET together with the latest capabilities of the &lt;strong&gt;CodeBehind Framework&lt;/strong&gt; and &lt;strong&gt;WebForms Core&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This will allow us to redesign the internal architecture instead of carrying every historical implementation decision from Elanat CMS into the new system.&lt;/p&gt;

&lt;p&gt;One important example is data access.&lt;/p&gt;

&lt;p&gt;Some parts of Elanat CMS rely on structures such as &lt;strong&gt;Stored Procedures&lt;/strong&gt;. In Gloria, we want to move toward modern approaches such as &lt;strong&gt;ORM-based data access&lt;/strong&gt; where appropriate.&lt;/p&gt;

&lt;p&gt;This is one of the reasons why a clean rewrite is more suitable than attempting to transform the existing system piece by piece.&lt;/p&gt;

&lt;h2&gt;
  
  
  Gloria Will Continue the Elanat CMS Philosophy
&lt;/h2&gt;

&lt;p&gt;Although Gloria will be a new system, it will not abandon the concepts that made Elanat CMS what it is.&lt;/p&gt;

&lt;p&gt;Some important concepts and structures will continue in Gloria.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;add-on-oriented architecture&lt;/strong&gt; will remain an important part of the new system.&lt;/p&gt;

&lt;p&gt;The concepts of &lt;strong&gt;components&lt;/strong&gt;, add-ons, and the way different parts of the system are organized will also continue to influence Gloria.&lt;/p&gt;

&lt;p&gt;Naming conventions and several structural ideas from Elanat CMS will be carried forward.&lt;/p&gt;

&lt;p&gt;Therefore, Gloria should not be understood as an unrelated CMS.&lt;/p&gt;

&lt;p&gt;It is better understood as the &lt;strong&gt;next generation of the Elanat CMS direction&lt;/strong&gt;, implemented with a new technical foundation.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Elanat Ecosystem
&lt;/h2&gt;

&lt;p&gt;Elanat's ecosystem currently consists of three major technologies and products:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;CodeBehind Framework&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;WebForms Core&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Elanat CMS&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;CodeBehind is the modern full-stack framework developed by Elanat under ASP.NET Core. It supports multiple development patterns and provides the foundation on which Elanat CMS was built.&lt;/p&gt;

&lt;p&gt;WebForms Core is Elanat's server-side UI manipulation technology. It introduces a server-side WebForms class and a browser-side WebFormsJS runtime for executing commands against the HTML DOM.&lt;/p&gt;

&lt;p&gt;Elanat CMS was built on the CodeBehind Framework and developed as a large, modular CMS with an add-on-oriented architecture.&lt;/p&gt;

&lt;p&gt;The new direction brings these technologies closer together.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Gloria will be built on the latest generation of CodeBehind and WebForms Core.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This means that the new CMS will be developed using the technologies that Elanat has been building and improving independently over recent years.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why a New Name?
&lt;/h2&gt;

&lt;p&gt;We deliberately chose a new name instead of simply calling the project "Elanat CMS 3".&lt;/p&gt;

&lt;p&gt;There is an important reason for this.&lt;/p&gt;

&lt;p&gt;Gloria will not be a normal major version upgrade.&lt;/p&gt;

&lt;p&gt;It will be a new system created from the foundation up.&lt;/p&gt;

&lt;p&gt;Calling it Elanat CMS 3 would suggest that the project is simply continuing the existing codebase with another major version.&lt;/p&gt;

&lt;p&gt;That would not accurately describe what we are doing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Elanat CMS 2.2 is the end of the existing Elanat CMS project. Gloria is the beginning of a new CMS project.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  A Clearer Name and Identity
&lt;/h2&gt;

&lt;p&gt;There was also another consideration behind the decision to introduce a new name.&lt;/p&gt;

&lt;p&gt;The name &lt;strong&gt;Elanat CMS&lt;/strong&gt; is closely associated with &lt;strong&gt;Elanat&lt;/strong&gt;, the organization and technology ecosystem behind the project. Over time, this similarity sometimes created confusion between the name of the CMS itself and the name &lt;strong&gt;Elanat&lt;/strong&gt; as the broader ecosystem.&lt;/p&gt;

&lt;p&gt;Elanat is no longer limited to a single CMS. Its ecosystem now includes &lt;strong&gt;CodeBehind&lt;/strong&gt;, &lt;strong&gt;WebForms Core&lt;/strong&gt;, and &lt;strong&gt;Elanat CMS&lt;/strong&gt;, each representing a different part of the technology stack.&lt;/p&gt;

&lt;p&gt;For this reason, introducing a distinct name for the next-generation CMS will also provide a clearer identity for the product.&lt;/p&gt;

&lt;p&gt;The new name, &lt;strong&gt;Gloria&lt;/strong&gt;, separates the identity of the CMS from the identity of the Elanat ecosystem while preserving the project's connection to its history.&lt;/p&gt;

&lt;p&gt;Gloria will therefore have its own product name, while remaining part of the Elanat ecosystem.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Elanat Logo Will Continue
&lt;/h2&gt;

&lt;p&gt;Although Gloria will have a new name, the project will retain the &lt;strong&gt;Elanat CMS logo&lt;/strong&gt;.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyxcc0vixy1yvk4y7pt2k.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyxcc0vixy1yvk4y7pt2k.png" alt="Gloria CMS" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The logo is part of the visual identity and history of the project, and we want that connection to remain visible.&lt;/p&gt;

&lt;p&gt;Gloria therefore represents a new technical beginning while preserving part of the identity that came from Elanat CMS.&lt;/p&gt;

&lt;p&gt;In this sense, the relationship is simple:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Elanat CMS → Gloria&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The name changes.&lt;/p&gt;

&lt;p&gt;The architecture evolves.&lt;/p&gt;

&lt;p&gt;The experience gained from Elanat CMS remains.&lt;/p&gt;

&lt;p&gt;And the development continues under the Elanat ecosystem.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Happens to Elanat CMS 2.2?
&lt;/h2&gt;

&lt;p&gt;Elanat CMS 2.2 is the final version.&lt;/p&gt;

&lt;p&gt;There will be no Elanat CMS 2.3.&lt;/p&gt;

&lt;p&gt;There will be no Elanat CMS 3.&lt;/p&gt;

&lt;p&gt;After version 2.2, the Elanat CMS project will be considered &lt;strong&gt;retired&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The existing project will remain part of Elanat's open-source history, but active development will move to Gloria.&lt;/p&gt;

&lt;p&gt;The decision also means that we will not attempt to transform the existing Elanat CMS codebase into Gloria through an endless series of migrations.&lt;/p&gt;

&lt;p&gt;Instead, Gloria will start from a clean foundation.&lt;/p&gt;

&lt;h2&gt;
  
  
  A New Beginning
&lt;/h2&gt;

&lt;p&gt;Large software projects accumulate history.&lt;/p&gt;

&lt;p&gt;That history can be valuable because it contains years of development experience, architectural experiments, solutions to real problems, and ideas that have proven useful.&lt;/p&gt;

&lt;p&gt;But history can also make fundamental redesign increasingly difficult.&lt;/p&gt;

&lt;p&gt;Elanat CMS has reached a point where we believe a new beginning is the more appropriate engineering decision.&lt;/p&gt;

&lt;p&gt;We could continue modifying the existing system.&lt;/p&gt;

&lt;p&gt;Instead, we chose to build something new.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Gloria will take the lessons, concepts, structures, and experience of Elanat CMS and combine them with the modern technologies developed by Elanat.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The target is a CMS that is substantially more modern, easier to evolve, and better aligned with the current Elanat technology stack.&lt;/p&gt;

&lt;h2&gt;
  
  
  Repository Transition
&lt;/h2&gt;

&lt;p&gt;The transition to Gloria also includes a change in the project's repository structure.&lt;/p&gt;

&lt;p&gt;The new Gloria project is being developed in a separate repository:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/elanatframework/Gloria" rel="noopener noreferrer"&gt;Gloria on GitHub&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The existing Elanat CMS repository will be archived:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/elanatframework/Elanat" rel="noopener noreferrer"&gt;Elanat CMS on GitHub&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Archiving the repository does not mean that the history of Elanat CMS will be removed. The repository will remain available as an archived record of the project and its development history, while active CMS development moves to Gloria.&lt;/p&gt;

&lt;p&gt;This separation is intentional.&lt;/p&gt;

&lt;p&gt;Elanat CMS represents the previous generation of the CMS, while Gloria represents a new implementation built around the current Elanat technology stack.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Elanat CMS 2.2 is the final release. The Elanat repository will be archived, and active CMS development will continue in the Gloria repository.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  From the Past to the Next Generation
&lt;/h2&gt;

&lt;p&gt;Elanat CMS was an important part of the development of the Elanat ecosystem.&lt;/p&gt;

&lt;p&gt;It helped establish concepts such as an add-on-oriented architecture, modular system design, components, and a CMS structure capable of supporting a wide range of functionality.&lt;/p&gt;

&lt;p&gt;Today, the ecosystem has evolved.&lt;/p&gt;

&lt;p&gt;CodeBehind has become a modern ASP.NET Core framework.&lt;/p&gt;

&lt;p&gt;WebForms Core is a server-side UI manipulation technology for working with HTML through server-generated commands.&lt;/p&gt;

&lt;p&gt;The next step is to bring these technologies together in a new CMS.&lt;/p&gt;

&lt;p&gt;That CMS will be &lt;strong&gt;Gloria&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Elanat CMS 2.2 marks the end of one chapter.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Gloria will begin the next one.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>news</category>
      <category>cms</category>
      <category>dotnet</category>
      <category>webformscore</category>
    </item>
    <item>
      <title>Go WebAssembly Meets WebForms Core 2.1</title>
      <dc:creator>Elanat Framework</dc:creator>
      <pubDate>Wed, 23 Sep 2026 07:49:08 +0000</pubDate>
      <link>https://dev.to/elanatframework/go-webassembly-meets-webforms-core-21-1hkb</link>
      <guid>https://dev.to/elanatframework/go-webassembly-meets-webforms-core-21-1hkb</guid>
      <description>&lt;p&gt;WebAssembly is often used to move application logic into the browser and build increasingly large client-side applications.&lt;/p&gt;

&lt;p&gt;WebForms Core takes a different approach.&lt;/p&gt;

&lt;p&gt;Instead of making WebAssembly the frontend architecture, WebAssembly can be used as an execution layer inside a server-orchestrated UI architecture.&lt;/p&gt;

&lt;p&gt;In this example, Go is compiled to WebAssembly and participates in the WebForms Core execution flow.&lt;/p&gt;

&lt;p&gt;The examples in this article are designed to demonstrate the server-orchestrated capabilities of WebForms Core. They could also be configured differently so that some operations do not require server participation.&lt;/p&gt;

&lt;p&gt;The general architecture is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Server → WebForms → Commands → WebFormsJS → HTML DOM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With WebAssembly, the architecture can also include a local execution layer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Server → WebForms → WebAssembly → WebForms Commands → WebFormsJS → HTML DOM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important idea is that WebAssembly does not have to replace the UI architecture. It can become another execution capability inside that architecture.&lt;/p&gt;




&lt;h2&gt;
  
  
  What is WebForms Core?
&lt;/h2&gt;

&lt;p&gt;WebForms Core is a server-orchestrated UI technology that allows the server to generate commands for manipulating the browser DOM and controlling UI behavior.&lt;/p&gt;

&lt;p&gt;Its architecture can be summarized as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Server → WebForms → Commands → WebFormsJS → HTML DOM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;WebForms Core does not require a separate frontend project, component framework, JSX, or a virtual DOM.&lt;/p&gt;

&lt;p&gt;It works with standard HTML and lets the &lt;code&gt;WebForms&lt;/code&gt; class generate UI operations.&lt;/p&gt;

&lt;p&gt;WebFormsJS is responsible for interpreting and executing the resulting WebForms Core commands in the browser.&lt;/p&gt;

&lt;p&gt;With WebAssembly support, selected methods can also execute locally in the browser.&lt;/p&gt;

&lt;p&gt;This creates an important distinction:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;WebAssembly can provide an execution layer without becoming the UI architecture.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Go WebAssembly
&lt;/h2&gt;

&lt;p&gt;Go is a general-purpose programming language with built-in WebAssembly support.&lt;/p&gt;

&lt;p&gt;Go can compile code directly to the WebAssembly target used by modern browsers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GOOS=js
GOARCH=wasm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A Go WebAssembly module can execute application logic in the browser while communicating with JavaScript through the Go WebAssembly runtime.&lt;/p&gt;

&lt;p&gt;In this example, Go is used together with WebForms Core 2.1.&lt;/p&gt;

&lt;p&gt;The Go module can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;execute numerical methods&lt;/li&gt;
&lt;li&gt;receive parameters from JavaScript&lt;/li&gt;
&lt;li&gt;create WebForms Core commands&lt;/li&gt;
&lt;li&gt;return WebForms Core responses&lt;/li&gt;
&lt;li&gt;generate HTML&lt;/li&gt;
&lt;li&gt;participate in WebForms Core events&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The important detail is that the Go code in this example does not manipulate the browser DOM directly.&lt;/p&gt;

&lt;p&gt;Instead, it can use the &lt;code&gt;WebForms&lt;/code&gt; class to generate a WebForms Core response.&lt;/p&gt;

&lt;p&gt;The response can then be interpreted by WebFormsJS.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbaa9fvw7essvfixz9rkr.jpg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbaa9fvw7essvfixz9rkr.jpg" alt="Go WebAssembly by WebForms Core Technology" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Creating the Go WebAssembly Project
&lt;/h2&gt;

&lt;p&gt;A Go WebAssembly project can be created as a normal Go module.&lt;/p&gt;

&lt;p&gt;A typical project can contain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;your-project-name/
    go.mod
    main.go
    webformscore/
    build.bat
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;go.mod&lt;/code&gt; file defines the Go module:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;module&lt;/span&gt; &lt;span class="n"&gt;your&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;project&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;

&lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="m"&gt;1.25.5&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;webformscore&lt;/code&gt; directory contains the Go implementation of the WebForms Core API.&lt;/p&gt;

&lt;p&gt;The WebAssembly build can be automated with a Windows batch file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight batchfile"&gt;&lt;code&gt;@echo &lt;span class="na"&gt;off&lt;/span&gt;

&lt;span class="kd"&gt;set&lt;/span&gt; &lt;span class="kd"&gt;GOOS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kd"&gt;js&lt;/span&gt;
&lt;span class="kd"&gt;set&lt;/span&gt; &lt;span class="kd"&gt;GOARCH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kd"&gt;wasm&lt;/span&gt;

&lt;span class="kd"&gt;go&lt;/span&gt; &lt;span class="kd"&gt;build&lt;/span&gt; &lt;span class="na"&gt;-o &lt;/span&gt;&lt;span class="kd"&gt;webforms&lt;/span&gt;&lt;span class="na"&gt;-go&lt;/span&gt;.wasm

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="na"&gt;/f &lt;/span&gt;&lt;span class="s2"&gt;"delims="&lt;/span&gt; &lt;span class="vm"&gt;%%i&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'go env GOROOT'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="kd"&gt;set&lt;/span&gt; &lt;span class="kd"&gt;GOROOT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="vm"&gt;%%i&lt;/span&gt;

&lt;span class="nb"&gt;copy&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;%GOROOT%&lt;/span&gt;&lt;span class="s2"&gt;\lib\wasm\wasm_exec.js"&lt;/span&gt; &lt;span class="kd"&gt;wasm_exec&lt;/span&gt;.js

&lt;span class="nb"&gt;pause&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The resulting WebAssembly module is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;webforms-go.wasm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Go WebAssembly Runtime
&lt;/h2&gt;

&lt;p&gt;Unlike a minimal WebAssembly module that can be instantiated directly through the WebAssembly JavaScript API, Go WebAssembly applications use the Go browser runtime.&lt;/p&gt;

&lt;p&gt;The runtime is provided by:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;wasm_exec.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The WebForms Core application therefore keeps both files available to the browser:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/web-assembly/go/
    webforms-go.wasm
    wasm_exec.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;webforms-go.wasm&lt;/code&gt; contains the compiled Go application.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;wasm_exec.js&lt;/code&gt; provides the JavaScript-side Go runtime required to execute the Go WebAssembly module.&lt;/p&gt;

&lt;p&gt;WebForms Core can load this runtime automatically when a Go WebAssembly method is requested.&lt;/p&gt;




&lt;h2&gt;
  
  
  Install the Go Package
&lt;/h2&gt;

&lt;p&gt;The Go implementation of WebForms Core can be installed as a Go module.&lt;/p&gt;

&lt;p&gt;CLI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;go get github.com/webforms-core/go
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;github.com/webforms-core/go&lt;/code&gt; provides the WebForms Core API used by the Go implementation.&lt;/p&gt;




&lt;h2&gt;
  
  
  WebFormsJS Installation via Package
&lt;/h2&gt;

&lt;p&gt;WebFormsJS is available through npm.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;JavaScript in npm:&lt;/strong&gt; &lt;a href="https://www.npmjs.com/package/webformsjs" rel="noopener noreferrer"&gt;webformsjs on npm&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;CLI:&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;webformsjs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;WebFormsJS is also available directly from the following GitHub repository:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/webforms-core/Web_forms" rel="noopener noreferrer"&gt;WebFormsJS GitHub Repository&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you install WebFormsJS through npm, the package can be imported and used directly in your JavaScript project.&lt;/p&gt;

&lt;p&gt;Alternatively, the source files can be obtained from the GitHub repository.&lt;/p&gt;




&lt;h2&gt;
  
  
  Using WebForms Core from Go
&lt;/h2&gt;

&lt;p&gt;The interesting part of this example is that the Go WebAssembly code uses the WebForms Core API directly.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;main.go&lt;/code&gt; file contains the exported JavaScript-facing methods:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"syscall/js"&lt;/span&gt;

    &lt;span class="n"&gt;WebFormsCore&lt;/span&gt; &lt;span class="s"&gt;"your-project-name/webformscore"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;this&lt;/span&gt; &lt;span class="n"&gt;js&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="n"&gt;js&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="kt"&gt;int32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="kt"&gt;int32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;setData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;this&lt;/span&gt; &lt;span class="n"&gt;js&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="n"&gt;js&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;inputPlace&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;backgroundColor&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;fontSize&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;WebFormsCore&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;New&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inputPlace&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetBackgroundColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"-"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetFontSize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"-"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fontSize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;getHtml&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;this&lt;/span&gt; &lt;span class="n"&gt;js&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="n"&gt;js&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;interface&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="s"&gt;"&amp;lt;marquee&amp;gt;Tag From Wasm!&amp;lt;/marquee&amp;gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;js&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Global&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"add"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;js&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FuncOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="n"&gt;js&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Global&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"setData"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;js&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FuncOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;setData&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="n"&gt;js&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Global&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"getHtml"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;js&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FuncOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;getHtml&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="k"&gt;select&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;There are three methods used by the WebForms Core example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;add&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;setData&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;getHtml&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each demonstrates a different way a Go WebAssembly method can participate in the WebForms Core execution model.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;code&gt;add&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;add&lt;/code&gt; method performs a simple calculation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;add(10000, 3)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It returns:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;10003
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The method receives two numeric arguments through the JavaScript-to-Go WebAssembly interface.&lt;/p&gt;

&lt;p&gt;This demonstrates a basic WebAssembly method that returns a value.&lt;/p&gt;

&lt;p&gt;However, WebForms Core can also use WebAssembly methods that produce UI responses.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;code&gt;setData&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;setData&lt;/code&gt; method receives four strings:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;inputPlace
text
backgroundColor
fontSize
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It creates a &lt;code&gt;WebForms&lt;/code&gt; object and generates a WebForms Core response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;WebFormsCore&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;New&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inputPlace&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetBackgroundColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"-"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetFontSize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"-"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fontSize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important detail is that the Go method is not returning JavaScript DOM operations.&lt;/p&gt;

&lt;p&gt;It is generating a WebForms Core response.&lt;/p&gt;

&lt;p&gt;That response can then be interpreted by WebFormsJS.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;code&gt;getHtml&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;The third method returns 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;marquee&amp;gt;&lt;/span&gt;Tag From Wasm!&lt;span class="nt"&gt;&amp;lt;/marquee&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The HTML can then be placed into the browser through a WebForms Core event.&lt;/p&gt;

&lt;p&gt;This demonstrates that a WebAssembly method can also return content that participates in the WebForms Core output flow.&lt;/p&gt;




&lt;h2&gt;
  
  
  The WebForms Class in Go
&lt;/h2&gt;

&lt;p&gt;The important architectural detail is that &lt;code&gt;WebForms&lt;/code&gt; is not a browser component.&lt;/p&gt;

&lt;p&gt;The Go code uses it as a command generator.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;WebFormsCore&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;New&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inputPlace&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetBackgroundColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"-"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetFontSize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"-"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fontSize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The resulting response is interpreted by WebFormsJS in the browser.&lt;/p&gt;

&lt;p&gt;Therefore, the flow becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Go
 ↓
WebForms
 ↓
WebForms Core Commands
 ↓
WebFormsJS
 ↓
HTML DOM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Go does not need to know how WebFormsJS applies the commands to the browser DOM.&lt;/p&gt;

&lt;p&gt;That responsibility belongs to WebFormsJS.&lt;/p&gt;

&lt;p&gt;This separation allows the Go WebAssembly layer to focus on application logic and command generation while WebFormsJS remains the browser-side UI runtime.&lt;/p&gt;




&lt;h2&gt;
  
  
  Go WebAssembly and JavaScript
&lt;/h2&gt;

&lt;p&gt;Go WebAssembly uses &lt;code&gt;syscall/js&lt;/code&gt; to communicate with the browser.&lt;/p&gt;

&lt;p&gt;In this example, the Go methods are registered as JavaScript functions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;js&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Global&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"add"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;js&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FuncOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;js&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Global&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"setData"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;js&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FuncOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;setData&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;js&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Global&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"getHtml"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;js&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FuncOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;getHtml&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes the functions available to the WebAssembly execution layer.&lt;/p&gt;

&lt;p&gt;For example, after the Go runtime is initialized, the JavaScript environment can access:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;add
setData
getHtml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;WebFormsJS can therefore invoke these methods as part of the WebForms Core execution flow.&lt;/p&gt;

&lt;p&gt;The important distinction is that JavaScript provides the browser integration required by the Go WebAssembly runtime, while WebFormsJS provides the WebForms Core browser-side execution environment.&lt;/p&gt;




&lt;h2&gt;
  
  
  Using Go WebAssembly from WebForms Core
&lt;/h2&gt;

&lt;p&gt;The server-side controller can invoke Go WebAssembly methods through the WebForms Core WASM API.&lt;/p&gt;

&lt;p&gt;The controller is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;CodeBehind&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;partial&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;WasmGOController&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;CodeBehindController&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;PageLoad&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HttpContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;WasmPath&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"/web-assembly/go/webforms-go.wasm"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
        &lt;span class="c1"&gt;//string WasmPath = "/web-assembly/go/wasm_exec.js"; &lt;/span&gt;

        &lt;span class="n"&gt;WebForms&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;WebForms&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&amp;lt;b&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Fetch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WasmMethod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;WasmLanguage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GO&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;WasmPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"add"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]));&lt;/span&gt;

        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetWasmEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"WasmEvent"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;HtmlEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OnClick&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;WasmLanguage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GO&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;WasmPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"setData"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"h3Tag"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Text From Wasm"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"lightgreen"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"30px"&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetWasmEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"WasmEventWithOutput"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;HtmlEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OnClick&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;WasmLanguage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GO&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;WasmPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"getHtml"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="s"&gt;"WasmHtmlOutput"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="nf"&gt;Write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ExportToHtmlComment&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 controller does not contain the Go implementation details.&lt;/p&gt;

&lt;p&gt;It defines how the WebAssembly methods participate in the WebForms Core UI flow.&lt;/p&gt;

&lt;p&gt;This is an important separation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Server-side controller
        ↓
WebForms Core definition
        ↓
WebAssembly method
        ↓
WebForms response
        ↓
WebFormsJS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  HTML
&lt;/h2&gt;

&lt;p&gt;The page itself remains ordinary HTML:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;@page
@controller WasmGOController
@layout "/layout.aspx"
@{
  ViewData.Add("title","GO Wasm");
}
&lt;span class="nt"&gt;&amp;lt;h3&amp;gt;&lt;/span&gt;GO Wasm&lt;span class="nt"&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;b&amp;gt;&lt;/span&gt;GO WASM Result: &lt;span class="nt"&gt;&amp;lt;/b&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;br&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"WasmEvent"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Wasm Event&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;br&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;h3&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"h3Tag"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Wasm Tag Changing!&lt;span class="nt"&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"WasmEventWithOutput"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Wasm Event With Output&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"WasmHtmlOutput"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Wasm Html Output&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is no Go-specific markup.&lt;/p&gt;

&lt;p&gt;There is no custom WebAssembly element.&lt;/p&gt;

&lt;p&gt;There is no component declaration.&lt;/p&gt;

&lt;p&gt;The HTML remains standard HTML.&lt;/p&gt;

&lt;p&gt;WebForms Core can assign behavior to these existing HTML elements without requiring the page to be redesigned around WebAssembly.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Interesting Part
&lt;/h2&gt;

&lt;p&gt;The interesting part is not simply that Go can run inside WebAssembly.&lt;/p&gt;

&lt;p&gt;The more important point is that a WebAssembly method can participate in the WebForms Core command architecture.&lt;/p&gt;

&lt;p&gt;A Go method can return a normal value:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Go → Value
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But it can also generate a WebForms Core response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Go → WebForms → Commands → WebFormsJS → DOM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"&amp;lt;b&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Fetch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WasmMethod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;WasmLanguage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GO&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;WasmPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"add"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;3&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;add&lt;/code&gt; method is implemented in Go, but its result can be consumed by WebForms Core.&lt;/p&gt;

&lt;p&gt;The second method is more interesting:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetWasmEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"WasmEvent"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;HtmlEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OnClick&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;WasmLanguage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GO&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;WasmPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"setData"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"h3Tag"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Text From Wasm"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"lightgreen"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"30px"&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;When the button is clicked, WebFormsJS can invoke the Go WebAssembly method.&lt;/p&gt;

&lt;p&gt;The method creates a &lt;code&gt;WebForms&lt;/code&gt; response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;WebFormsCore&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;New&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inputPlace&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetBackgroundColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"-"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetFontSize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"-"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fontSize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The response is then interpreted by WebFormsJS.&lt;/p&gt;

&lt;p&gt;The resulting execution chain is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HTML Event
    ↓
WebFormsJS
    ↓
Go WASM
    ↓
WebForms
    ↓
WebForms Core Response
    ↓
WebFormsJS
    ↓
DOM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is different from simply calling a WebAssembly function and returning a number.&lt;/p&gt;

&lt;p&gt;The WebAssembly method can become a producer of UI commands.&lt;/p&gt;

&lt;p&gt;That is what allows Go WebAssembly to participate in the WebForms Core UI execution model.&lt;/p&gt;




&lt;h2&gt;
  
  
  WASM Event With Output
&lt;/h2&gt;

&lt;p&gt;The third method demonstrates another possibility:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetWasmEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"WasmEventWithOutput"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;HtmlEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OnClick&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;WasmLanguage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GO&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;WasmPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"getHtml"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;[],&lt;/span&gt;
    &lt;span class="s"&gt;"WasmHtmlOutput"&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Go method returns HTML:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;getHtml&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;this&lt;/span&gt; &lt;span class="n"&gt;js&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="n"&gt;js&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;interface&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="s"&gt;"&amp;lt;marquee&amp;gt;Tag From Wasm!&amp;lt;/marquee&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;WebForms Core can then place the returned value into:&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;p&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"WasmHtmlOutput"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Wasm Html Output&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This demonstrates that WebAssembly methods can participate directly in the WebForms Core output flow.&lt;/p&gt;




&lt;h2&gt;
  
  
  Where Does the Execution Take Place?
&lt;/h2&gt;

&lt;p&gt;This architecture does not require every operation to execute on the server.&lt;/p&gt;

&lt;p&gt;The server can generate the initial WebForms Core commands and define the UI behavior, while selected WebAssembly methods can execute locally in the browser.&lt;/p&gt;

&lt;p&gt;For an interactive event, the flow can be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Browser Event
    ↓
WebFormsJS
    ↓
Go WebAssembly
    ↓
WebForms Response
    ↓
WebFormsJS
    ↓
HTML DOM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This allows the application to keep a server-orchestrated UI model while selectively executing code locally in the browser through WebAssembly.&lt;/p&gt;

&lt;p&gt;The examples in this article intentionally demonstrate this integration with WebForms Core. Other configurations can reduce or eliminate server participation for selected operations.&lt;/p&gt;




&lt;h2&gt;
  
  
  Go Is an Execution Layer
&lt;/h2&gt;

&lt;p&gt;This example demonstrates an important distinction.&lt;/p&gt;

&lt;p&gt;WebAssembly is not being used here to build a complete frontend application.&lt;/p&gt;

&lt;p&gt;Go is being used as an execution layer.&lt;/p&gt;

&lt;p&gt;The UI architecture remains:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HTML
  +
WebForms Core
  +
WebFormsJS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Go WebAssembly is inserted where local WebAssembly execution provides value:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                 WebForms Core
                      │
             ┌────────┴────────┐
             │                 │
       Server WebForms      Go WASM
                               │
                              Go
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This allows the application to use WebAssembly selectively instead of moving the entire application into a WebAssembly frontend.&lt;/p&gt;




&lt;h2&gt;
  
  
  No Custom JavaScript Required for These UI Operations
&lt;/h2&gt;

&lt;p&gt;In this example, the application does not need custom JavaScript business logic to perform these UI operations.&lt;/p&gt;

&lt;p&gt;The Go method performs the computation or generates the WebForms Core response.&lt;/p&gt;

&lt;p&gt;WebFormsJS remains the browser runtime responsible for executing the resulting commands.&lt;/p&gt;

&lt;p&gt;Therefore, the flow is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Go → WebForms Commands → WebFormsJS → DOM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;rather than requiring a separate custom JavaScript layer between the Go code and the UI.&lt;/p&gt;

&lt;p&gt;This separation keeps the WebAssembly layer independent from the application's browser-side DOM implementation.&lt;/p&gt;




&lt;h2&gt;
  
  
  Standard HTML Remains the UI
&lt;/h2&gt;

&lt;p&gt;The Go example does not introduce a new component model.&lt;/p&gt;

&lt;p&gt;The page still contains standard 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;h3&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"h3Tag"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Wasm Tag Changing!&lt;span class="nt"&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and:&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;button&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"WasmEvent"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Wasm Event&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The server assigns behavior to these existing elements.&lt;/p&gt;

&lt;p&gt;This is one of the important characteristics of WebForms Core.&lt;/p&gt;

&lt;p&gt;WebAssembly does not require the UI to be redesigned around WebAssembly components.&lt;/p&gt;

&lt;p&gt;The HTML remains the UI, while WebForms Core and WebFormsJS provide the command and execution layers.&lt;/p&gt;




&lt;h2&gt;
  
  
  Go and WebForms Core
&lt;/h2&gt;

&lt;p&gt;The Go implementation demonstrates that a WebAssembly language can use the same WebForms Core model as other supported languages.&lt;/p&gt;

&lt;p&gt;The important relationship is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Go
 ↓
WebForms Class
 ↓
Action Controls / Response
 ↓
WebFormsJS
 ↓
Browser DOM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The WebForms class acts as the bridge between application logic and WebForms Core command generation.&lt;/p&gt;

&lt;p&gt;This makes the WebAssembly module more than an isolated computational library.&lt;/p&gt;

&lt;p&gt;It can participate in the UI execution model.&lt;/p&gt;




&lt;h2&gt;
  
  
  WebAssembly Does Not Have to Replace the UI Architecture
&lt;/h2&gt;

&lt;p&gt;A common approach to WebAssembly applications is to move a large portion of the frontend into the WebAssembly runtime.&lt;/p&gt;

&lt;p&gt;WebForms Core takes a different approach.&lt;/p&gt;

&lt;p&gt;WebAssembly can be introduced only where it provides value.&lt;/p&gt;

&lt;p&gt;For example, an application can continue using:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;standard HTML&lt;/li&gt;
&lt;li&gt;server-side WebForms&lt;/li&gt;
&lt;li&gt;WebFormsJS&lt;/li&gt;
&lt;li&gt;server-generated commands&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;while selectively executing Go code through WebAssembly.&lt;/p&gt;

&lt;p&gt;This makes WebAssembly an execution capability rather than a mandatory application architecture.&lt;/p&gt;

&lt;p&gt;The result is a hybrid execution model in which the UI architecture remains based on HTML and WebForms Core while WebAssembly can provide additional local execution capabilities.&lt;/p&gt;




&lt;h2&gt;
  
  
  Go WebAssembly and WebFormsJS
&lt;/h2&gt;

&lt;p&gt;Go provides the WebAssembly execution environment, while WebFormsJS remains responsible for browser-side UI execution.&lt;/p&gt;

&lt;p&gt;A simple method can be written as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;this&lt;/span&gt; &lt;span class="n"&gt;js&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="n"&gt;js&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="kt"&gt;int32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="kt"&gt;int32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The method executes inside the Go WebAssembly environment.&lt;/p&gt;

&lt;p&gt;When combined with WebForms Core, the overall flow can be represented as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Server
  ↓
WebForms
  ↓
WebAssembly Method
  ↓
Go
  ↓
WebForms Response
  ↓
WebFormsJS
  ↓
DOM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The browser therefore remains responsible for UI execution while Go provides a WebAssembly execution layer.&lt;/p&gt;




&lt;h2&gt;
  
  
  WebForms Core 2.1 and WebAssembly Languages
&lt;/h2&gt;

&lt;p&gt;WebForms Core 2.1 allows the WebAssembly execution layer to work with different programming languages while keeping the UI command architecture unchanged.&lt;/p&gt;

&lt;p&gt;In this example, Go provides the WebAssembly implementation.&lt;/p&gt;

&lt;p&gt;The same architectural model can be used with other supported WebAssembly languages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                 WebForms Core
                       │
          ┌────────────┼────────────┐
          ↓            ↓            ↓
       Go WASM      C# WASM      Rust WASM
          │            │            │
          └────────────┼────────────┘
                       ↓
                  WebFormsJS
                       ↓
                      DOM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The WebAssembly implementation can change without requiring the HTML UI to be redesigned around a language-specific component model.&lt;/p&gt;

&lt;p&gt;The UI command architecture remains the same.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Result
&lt;/h2&gt;

&lt;p&gt;The final application combines four technologies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CodeBehind
     ↓
WebForms Core 2.1
     ↓
Go WebAssembly
     ↓
WebFormsJS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each layer has a different responsibility.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CodeBehind&lt;/strong&gt; provides the server-side application environment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;WebForms Core&lt;/strong&gt; provides the command-generation and UI orchestration model.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Go WebAssembly&lt;/strong&gt; provides a local execution layer in the browser.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;WebFormsJS&lt;/strong&gt; provides the browser-side execution environment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;HTML&lt;/strong&gt; remains the UI.&lt;/p&gt;

&lt;p&gt;The result is a WebAssembly-enabled application model without requiring a separate WebAssembly frontend architecture.&lt;/p&gt;




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

&lt;p&gt;Go WebAssembly does not have to become the frontend architecture.&lt;/p&gt;

&lt;p&gt;With WebForms Core 2.1, Go can be used as a WebAssembly execution layer inside a server-orchestrated UI architecture.&lt;/p&gt;

&lt;p&gt;The resulting model can be represented as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Server → WebForms → WebAssembly → WebForms Commands → WebFormsJS → DOM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Go can perform computation, respond to browser events, generate WebForms Core responses, and participate in interactive UI operations.&lt;/p&gt;

&lt;p&gt;At the same time, the application can continue using standard HTML and WebForms Core commands.&lt;/p&gt;

&lt;p&gt;The key idea is simple:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;WebAssembly can be an execution layer without becoming the UI architecture.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Related Links
&lt;/h2&gt;

&lt;p&gt;In Elanat:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://elanat.net/webforms-core" rel="noopener noreferrer"&gt;WebForms Core Page&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://elanat.net/webforms-js" rel="noopener noreferrer"&gt;WebFormsJS Page&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In GitHub:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/webforms-core" rel="noopener noreferrer"&gt;WebForms Core Organizations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/webforms-core/Web_forms" rel="noopener noreferrer"&gt;WebFormsJS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/webforms-core/Web_forms_classes" rel="noopener noreferrer"&gt;WebForms Classes&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In PKG:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://pkg.go.dev/github.com/webforms-core/go" rel="noopener noreferrer"&gt;WebForms Core Package&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>go</category>
      <category>webassembly</category>
      <category>frontend</category>
      <category>webformscore</category>
    </item>
    <item>
      <title>Rust WebAssembly with WebForms Core 2.1</title>
      <dc:creator>Elanat Framework</dc:creator>
      <pubDate>Tue, 22 Sep 2026 21:28:01 +0000</pubDate>
      <link>https://dev.to/elanatframework/rust-webassembly-with-webforms-core-21-3jj9</link>
      <guid>https://dev.to/elanatframework/rust-webassembly-with-webforms-core-21-3jj9</guid>
      <description>&lt;h2&gt;
  
  
  What is WebForms Core?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://elanat.net/page_content/web_forms_core" rel="noopener noreferrer"&gt;WebForms Core&lt;/a&gt; is a modern multi-platform web technology from &lt;a href="https://elanat.net" rel="noopener noreferrer"&gt;Elanat&lt;/a&gt; for building interactive HTML applications through server-defined commands and client-side command execution.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;WebForms Core uses a server-oriented architecture in which the server defines UI behavior through commands, while a lightweight browser runtime executes those commands.&lt;/p&gt;

&lt;p&gt;With &lt;strong&gt;WebForms Core 2.1 (WFC)&lt;/strong&gt;, WebAssembly can also be used as an execution layer within this architecture.&lt;/p&gt;

&lt;p&gt;In this article, we will use &lt;strong&gt;Rust WebAssembly&lt;/strong&gt; with WebForms Core and demonstrate two approaches:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Rust with &lt;code&gt;wasm-bindgen&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Raw WebAssembly using &lt;code&gt;extern "C"&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both approaches can execute Rust code through WebForms Core.&lt;/p&gt;

&lt;p&gt;More importantly, Rust code running inside WebAssembly can use the WebForms Core &lt;code&gt;WebForms&lt;/code&gt; class to generate WebForms Core commands.&lt;/p&gt;

&lt;p&gt;This creates a pipeline such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Rust
  ↓
WebAssembly
  ↓
WebForms
  ↓
WebForms Core Commands
  ↓
WebFormsJS
  ↓
Browser DOM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The WASM module executes in the browser, while the server-side WebForms class declares when and how the WASM method should be executed. The WASM method can then use the WebForms API to generate WebForms Core commands, which are executed by WebFormsJS in the browser.&lt;/strong&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  Rust WebAssembly
&lt;/h1&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F65rroccslore15hz15vc.jpg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F65rroccslore15hz15vc.jpg" alt="Rust and WebForms Core" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Rust has first-class support for compiling code to WebAssembly.&lt;/p&gt;

&lt;p&gt;A Rust project can target:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;wasm32-unknown-unknown
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cargo +stable-x86_64-pc-windows-gnu build &lt;span class="nt"&gt;--release&lt;/span&gt; &lt;span class="nt"&gt;--target&lt;/span&gt; wasm32-unknown-unknown
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The resulting WebAssembly module is generated under:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;target/wasm32-unknown-unknown/release/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;webformscore_wasm_test.wasm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This module can then be executed in the browser through WebForms Core's WebAssembly execution layer.&lt;/p&gt;




&lt;h3&gt;
  
  
  Rust in Crates.io
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Rust in Crates.io&lt;/strong&gt; (&lt;a href="https://crates.io/crates/webformscore" rel="noopener noreferrer"&gt;https://crates.io/crates/webformscore&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CLI&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cargo add webformscore
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Project settings&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[dependencies]&lt;/span&gt;
&lt;span class="py"&gt;webformscore&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"#.#.#"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Two Rust WebAssembly Approaches
&lt;/h1&gt;

&lt;p&gt;WebForms Core can work with different Rust WebAssembly execution models.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. wasm-bindgen
&lt;/h2&gt;

&lt;p&gt;The first approach uses:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;wasm_bindgen&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;prelude&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[wasm_bindgen]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Rust project can then be processed by &lt;code&gt;wasm-bindgen&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;wasm-bindgen target/wasm32-unknown-unknown/release/webformscore_wasm_test.wasm &lt;span class="nt"&gt;--target&lt;/span&gt; web &lt;span class="nt"&gt;--out-dir&lt;/span&gt; pkg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This produces JavaScript glue code and a WebAssembly module.&lt;/p&gt;

&lt;p&gt;The resulting files include:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;webformscore_wasm_test.js
webformscore_wasm_test_bg.wasm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;WebForms Core can execute the generated JavaScript module through its JavaScript WASM executor.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;wasm-bindgen&lt;/code&gt; approach is useful when Rust code needs convenient JavaScript interoperability.&lt;/p&gt;




&lt;h1&gt;
  
  
  2. Raw WebAssembly
&lt;/h1&gt;

&lt;p&gt;The second approach does not use &lt;code&gt;wasm-bindgen&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Instead, Rust functions can be exported directly using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[no_mangle]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;extern&lt;/span&gt; &lt;span class="s"&gt;"C"&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[no_mangle]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;extern&lt;/span&gt; &lt;span class="s"&gt;"C"&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The function is exported directly into the WebAssembly module.&lt;/p&gt;

&lt;p&gt;There is no JavaScript glue code generated by &lt;code&gt;wasm-bindgen&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The resulting architecture is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Rust
  ↓
extern "C"
  ↓
Raw .wasm
  ↓
WebForms Core WASM Executor
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This approach is particularly interesting for WebForms Core because the WASM module can expose a direct callable interface without depending on the &lt;code&gt;wasm-bindgen&lt;/code&gt; JavaScript layer.&lt;/p&gt;




&lt;h1&gt;
  
  
  Creating the Rust Project
&lt;/h1&gt;

&lt;p&gt;Create a Rust library project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cargo new webformscore_wasm_test &lt;span class="nt"&gt;--lib&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Enter the project:&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="nb"&gt;cd &lt;/span&gt;webformscore_wasm_test
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The project can use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[package]&lt;/span&gt;
&lt;span class="py"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"webformscore_wasm_test"&lt;/span&gt;
&lt;span class="py"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"2.1.0"&lt;/span&gt;
&lt;span class="py"&gt;edition&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"2021"&lt;/span&gt;

&lt;span class="nn"&gt;[lib]&lt;/span&gt;
&lt;span class="py"&gt;crate-type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"cdylib"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="nn"&gt;[dependencies]&lt;/span&gt;
&lt;span class="py"&gt;webformscore&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"2.1.0"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important dependency is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="py"&gt;webformscore&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"2.1.0"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes the WebForms Core Rust implementation available inside the WebAssembly project.&lt;/p&gt;




&lt;h1&gt;
  
  
  Using WebForms Core from Rust
&lt;/h1&gt;

&lt;p&gt;The Rust code can directly use the &lt;code&gt;WebForms&lt;/code&gt; class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;webformscore&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;WebForms&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;WebForms&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="nf"&gt;.set_text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"h3Tag"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Text From Wasm"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="nf"&gt;.set_background_color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"-"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"lightgreen"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="nf"&gt;.set_font_size&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"-"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"30px"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="nf"&gt;.response&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Rust code does not directly manipulate the browser DOM.&lt;/p&gt;

&lt;p&gt;Instead, it creates a &lt;strong&gt;WebForms Core response&lt;/strong&gt; containing commands.&lt;/p&gt;

&lt;p&gt;This preserves the same command-oriented architecture used by WebForms Core.&lt;/p&gt;

&lt;p&gt;The Rust WASM module therefore does not need to know how WebFormsJS applies the commands to the DOM.&lt;/p&gt;




&lt;h1&gt;
  
  
  Rust with wasm-bindgen
&lt;/h1&gt;

&lt;p&gt;The &lt;code&gt;wasm-bindgen&lt;/code&gt; version is straightforward.&lt;/p&gt;

&lt;p&gt;The complete Rust source can be written as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;wasm_bindgen&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;prelude&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;webformscore&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;WebForms&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;#[wasm_bindgen]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;#[wasm_bindgen]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;set_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;input_place&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;background_color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;font_size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;WebForms&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="nf"&gt;.set_text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;input_place&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="nf"&gt;.set_background_color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"-"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;background_color&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="nf"&gt;.set_font_size&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"-"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;font_size&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="nf"&gt;.response&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;#[wasm_bindgen]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;get_html&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s"&gt;"&amp;lt;marquee&amp;gt;Tag From Wasm!&amp;lt;/marquee&amp;gt;"&lt;/span&gt;&lt;span class="nf"&gt;.to_string&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 important point is that the Rust methods can use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="n"&gt;WebForms&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;directly.&lt;/p&gt;

&lt;p&gt;The WebAssembly method therefore does not need to manipulate the DOM itself.&lt;/p&gt;

&lt;p&gt;It can generate a WebForms Core response instead.&lt;/p&gt;




&lt;h1&gt;
  
  
  Building the wasm-bindgen Module
&lt;/h1&gt;

&lt;p&gt;Build the Rust WebAssembly module:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cargo +stable-x86_64-pc-windows-gnu build &lt;span class="nt"&gt;--release&lt;/span&gt; &lt;span class="nt"&gt;--target&lt;/span&gt; wasm32-unknown-unknown
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;wasm-bindgen target&lt;span class="se"&gt;\w&lt;/span&gt;asm32-unknown-unknown&lt;span class="se"&gt;\r&lt;/span&gt;elease&lt;span class="se"&gt;\w&lt;/span&gt;ebformscore_wasm_test.wasm &lt;span class="nt"&gt;--target&lt;/span&gt; web &lt;span class="nt"&gt;--out-dir&lt;/span&gt; pkg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The generated package contains the JavaScript glue required by the &lt;code&gt;wasm-bindgen&lt;/code&gt; execution model.&lt;/p&gt;

&lt;p&gt;The resulting structure is conceptually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;webformscore_wasm_test.js
webformscore_wasm_test_bg.wasm
webformscore_wasm_test.d.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The JavaScript file provides the JavaScript-facing interface for the Rust WebAssembly module.&lt;/p&gt;




&lt;h1&gt;
  
  
  Raw WebAssembly with Rust
&lt;/h1&gt;

&lt;p&gt;Rust can also export functions directly without &lt;code&gt;wasm-bindgen&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;A simple function is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[no_mangle]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;extern&lt;/span&gt; &lt;span class="s"&gt;"C"&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This function is exported directly by the WebAssembly module.&lt;/p&gt;

&lt;p&gt;A complete Raw WASM example can be written as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;ffi&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;CStr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;webformscore&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;WebForms&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;#[no_mangle]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;extern&lt;/span&gt; &lt;span class="s"&gt;"C"&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;#[no_mangle]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;extern&lt;/span&gt; &lt;span class="s"&gt;"C"&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;alloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="nb"&gt;u8&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;buffer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Vec&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;with_capacity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="nf"&gt;.as_mut_ptr&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;mem&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;forget&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;ptr&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;#[no_mangle]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;extern&lt;/span&gt; &lt;span class="s"&gt;"C"&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;set_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;input_place&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;background_color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;font_size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="nb"&gt;u8&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;input_place&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;unsafe&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nn"&gt;CStr&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_ptr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input_place&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="nb"&gt;i8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="nf"&gt;.to_str&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;unsafe&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nn"&gt;CStr&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_ptr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="nb"&gt;i8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="nf"&gt;.to_str&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;background_color&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;unsafe&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nn"&gt;CStr&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_ptr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;background_color&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="nb"&gt;i8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="nf"&gt;.to_str&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;font_size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;unsafe&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nn"&gt;CStr&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_ptr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;font_size&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="nb"&gt;i8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="nf"&gt;.to_str&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;WebForms&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="nf"&gt;.set_text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input_place&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="nf"&gt;.set_background_color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"-"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;background_color&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="nf"&gt;.set_font_size&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"-"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;font_size&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="nf"&gt;.response&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;output&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="nf"&gt;.into_bytes&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="nf"&gt;.push&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="nn"&gt;Box&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;into_raw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="nf"&gt;.into_boxed_slice&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="nb"&gt;u8&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;#[no_mangle]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;extern&lt;/span&gt; &lt;span class="s"&gt;"C"&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;get_html&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="nb"&gt;u8&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s"&gt;b"&amp;lt;marquee&amp;gt;Tag From Wasm!&amp;lt;/marquee&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\0&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="nf"&gt;.as_ptr&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 version has no:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;wasm_bindgen&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;prelude&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and no:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[wasm_bindgen]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The functions are exported directly from the WebAssembly module.&lt;/p&gt;




&lt;h1&gt;
  
  
  Passing Strings to Raw WebAssembly
&lt;/h1&gt;

&lt;p&gt;Primitive values such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nb"&gt;i32&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;are straightforward:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;extern&lt;/span&gt; &lt;span class="s"&gt;"C"&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Strings require an explicit memory representation.&lt;/p&gt;

&lt;p&gt;In the Raw WASM example, WebForms Core passes strings into WebAssembly memory and the Rust code reads them using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nn"&gt;CStr&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_ptr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;unsafe&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nn"&gt;CStr&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_ptr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="nb"&gt;i8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.to_str&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;.unwrap&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 Rust method can then use the resulting string normally:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="nf"&gt;.set_text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input_place&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The response is returned through a pointer to UTF-8 data.&lt;/p&gt;

&lt;p&gt;This represents a simple ABI suitable for direct WebAssembly execution.&lt;/p&gt;




&lt;h1&gt;
  
  
  Returning WebForms Core Responses
&lt;/h1&gt;

&lt;p&gt;The most interesting part of the Raw WASM example is that &lt;code&gt;set_data&lt;/code&gt; does not return a traditional application value.&lt;/p&gt;

&lt;p&gt;It creates a WebForms Core response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;WebForms&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="nf"&gt;.set_text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input_place&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="nf"&gt;.set_background_color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"-"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;background_color&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="nf"&gt;.set_font_size&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"-"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;font_size&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="nf"&gt;.response&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The response can then be returned to WebForms Core.&lt;/p&gt;

&lt;p&gt;Therefore:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Rust WASM
    ↓
WebForms
    ↓
response()
    ↓
WebForms Core
    ↓
WebFormsJS
    ↓
Browser DOM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Rust WebAssembly method effectively becomes another source of WebForms Core commands.&lt;/p&gt;

&lt;p&gt;This is the central architectural idea of the example.&lt;/p&gt;




&lt;h1&gt;
  
  
  Using Rust WASM from WebForms Core
&lt;/h1&gt;

&lt;p&gt;The server-side WebForms Core controller can declare a WASM method invocation that is executed by the browser.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;CodeBehind&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;partial&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;WasmRustController&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;CodeBehindController&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;PageLoad&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HttpContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;WasmPath&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"/web-assembly/rust/webformscore_wasm_test_bg.wasm"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="n"&gt;WebForms&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;WebForms&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;"&amp;lt;b&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;Fetch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WasmMethod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="n"&gt;WasmLanguage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Rust&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;WasmPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s"&gt;"add"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;3&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="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetWasmEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;"WasmEvent"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;HtmlEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OnClick&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;WasmLanguage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Rust&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;WasmPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"setData"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"h3Tag"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Text From Wasm"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"lightgreen"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"30px"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetWasmEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;"WasmEventWithOutput"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;HtmlEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OnClick&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;WasmLanguage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Rust&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;WasmPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"getHtml"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;[],&lt;/span&gt;
            &lt;span class="s"&gt;"WasmHtmlOutput"&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="nf"&gt;Write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ExportToHtmlComment&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;blockquote&gt;
&lt;p&gt;Both the wasm-bindgen and Raw WebAssembly examples use server-side WebForms Core code to demonstrate the power of its server-oriented architecture. However, server-side orchestration is not required by WebForms Core itself. These scenarios can also be configured to run without server-side WebForms code when server orchestration is not needed.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The same WFC API can therefore declare Rust WASM method calls.&lt;/p&gt;

&lt;p&gt;The server does not need to know the internal implementation of the Rust method.&lt;/p&gt;

&lt;p&gt;It only needs to specify:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;WASM language
WASM path
method name
arguments
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The server defines the execution behavior, while the browser executes the WASM module and processes the resulting WebForms Core response.&lt;/p&gt;




&lt;h1&gt;
  
  
  Three Rust WASM Methods
&lt;/h1&gt;

&lt;p&gt;The example exposes three methods:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;add
set_data
get_html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first method returns a number:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;which produces:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;10003
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The second method receives strings and generates a WebForms Core response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nf"&gt;set_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"h3Tag"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"Text From Wasm"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"lightgreen"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"30px"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The third method returns HTML:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nf"&gt;get_html&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;which produces:&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;marquee&amp;gt;&lt;/span&gt;Tag From Wasm!&lt;span class="nt"&gt;&amp;lt;/marquee&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This demonstrates that WebForms Core can use WASM methods for different kinds of operations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;returning values&lt;/li&gt;
&lt;li&gt;generating WebForms Core commands&lt;/li&gt;
&lt;li&gt;returning HTML&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  HTML
&lt;/h1&gt;

&lt;p&gt;The HTML remains standard HTML:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;@page
@controller WasmRustController
@layout "/layout.aspx"

@{
    ViewData.Add("title", "Rust Wasm");
}

&lt;span class="nt"&gt;&amp;lt;h3&amp;gt;&lt;/span&gt;Rust Wasm&lt;span class="nt"&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;b&amp;gt;&lt;/span&gt;Rust WASM Result: &lt;span class="nt"&gt;&amp;lt;/b&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;br&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"WasmEvent"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    Wasm Event
&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;br&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;h3&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"h3Tag"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    Wasm Tag Changing!
&lt;span class="nt"&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"WasmEventWithOutput"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    Wasm Event With Output
&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"WasmHtmlOutput"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    Wasm Html Output
&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is no custom WebAssembly HTML element.&lt;/p&gt;

&lt;p&gt;There is no special component syntax.&lt;/p&gt;

&lt;p&gt;There is no Rust-specific DOM layer.&lt;/p&gt;

&lt;p&gt;The page remains standard HTML.&lt;/p&gt;




&lt;h1&gt;
  
  
  The WASM Method as a Command Execution Source
&lt;/h1&gt;

&lt;p&gt;Consider this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetWasmEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"WasmEvent"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;HtmlEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OnClick&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;WasmLanguage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Rust&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;WasmPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"setData"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"h3Tag"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Text From Wasm"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"lightgreen"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"30px"&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;WebForms Core declares that when the button is activated, a Rust WASM method should be executed.&lt;/p&gt;

&lt;p&gt;The Rust method can then create:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;WebForms&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="nf"&gt;.set_text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input_place&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="nf"&gt;.set_background_color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"-"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;background_color&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="nf"&gt;.set_font_size&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"-"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;font_size&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and return the WebForms Core response.&lt;/p&gt;

&lt;p&gt;The WASM method therefore becomes an &lt;strong&gt;execution source for WebForms Core commands&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The browser does not need a separate Rust-specific UI architecture.&lt;/p&gt;




&lt;h1&gt;
  
  
  WASM Event With Output
&lt;/h1&gt;

&lt;p&gt;The same mechanism can return HTML:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[no_mangle]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;extern&lt;/span&gt; &lt;span class="s"&gt;"C"&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;get_html&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="nb"&gt;u8&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s"&gt;b"&amp;lt;marquee&amp;gt;Tag From Wasm!&amp;lt;/marquee&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\0&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="nf"&gt;.as_ptr&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 server connects it to an output element:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetWasmEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"WasmEventWithOutput"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;HtmlEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OnClick&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;WasmLanguage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Rust&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;WasmPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"getHtml"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;[],&lt;/span&gt;
    &lt;span class="s"&gt;"WasmHtmlOutput"&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The returned HTML is then placed into:&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;p&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"WasmHtmlOutput"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    Wasm Html Output
&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This demonstrates that a Rust WASM method can also be used as a source of dynamic UI output.&lt;/p&gt;




&lt;h1&gt;
  
  
  One WebForms Core API, Different WASM Models
&lt;/h1&gt;

&lt;p&gt;The WebForms Core API does not have to change when the WASM execution model changes.&lt;/p&gt;

&lt;p&gt;The application can use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Rust + wasm-bindgen
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Rust + Raw WebAssembly
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;while the WebForms Core invocation remains conceptually the same:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;WasmMethod
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The execution layer handles the differences between the WASM models.&lt;/p&gt;

&lt;p&gt;This gives WebForms Core a unified way to work with different WebAssembly environments.&lt;/p&gt;




&lt;h1&gt;
  
  
  wasm-bindgen vs Raw WebAssembly
&lt;/h1&gt;

&lt;p&gt;The two approaches have different characteristics.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;wasm-bindgen&lt;/th&gt;
&lt;th&gt;Raw WebAssembly&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Rust API&lt;/td&gt;
&lt;td&gt;High-level&lt;/td&gt;
&lt;td&gt;Low-level&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;String handling&lt;/td&gt;
&lt;td&gt;Mostly abstracted&lt;/td&gt;
&lt;td&gt;Explicit memory handling&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;JavaScript glue&lt;/td&gt;
&lt;td&gt;Generated&lt;/td&gt;
&lt;td&gt;No &lt;code&gt;wasm-bindgen&lt;/code&gt; glue&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;.js&lt;/code&gt; module&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Direct &lt;code&gt;.wasm&lt;/code&gt; loading&lt;/td&gt;
&lt;td&gt;Possible with a compatible interface&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ABI complexity&lt;/td&gt;
&lt;td&gt;Mostly handled by wasm-bindgen&lt;/td&gt;
&lt;td&gt;Developer-defined&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Memory/ABI control&lt;/td&gt;
&lt;td&gt;Mostly abstracted&lt;/td&gt;
&lt;td&gt;Developer-defined&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WebForms Core integration&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Best suited for&lt;/td&gt;
&lt;td&gt;General Rust WASM applications&lt;/td&gt;
&lt;td&gt;Direct WASM execution&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;wasm-bindgen&lt;/code&gt; approach is convenient when Rust needs a rich JavaScript interoperability layer.&lt;/p&gt;

&lt;p&gt;The Raw WebAssembly approach is attractive when the goal is a directly callable WASM module with a developer-defined ABI.&lt;/p&gt;

&lt;p&gt;Neither approach changes the WebForms Core command model.&lt;/p&gt;




&lt;h1&gt;
  
  
  WebForms Core Rust WASM Architecture
&lt;/h1&gt;

&lt;p&gt;The resulting architecture can be viewed as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                         Server
                           │
                           │ WebForms
                           ↓
                     WasmMethod
                           │
                           ↓
                    Browser Runtime
                           │
                  ┌────────┴────────┐
                  │                 │
                  ↓                 ↓
           wasm-bindgen        Raw WASM
                  │                 │
                  ↓                 ↓
             Rust WASM          Rust WASM
                  │                 │
                  └────────┬────────┘
                           ↓
                       WebForms
                           │
                           ↓
                  WebForms Core Response
                           │
                           ↓
                       WebFormsJS
                           │
                           ↓
                      HTML DOM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This shows the role of WebAssembly more clearly.&lt;/p&gt;

&lt;p&gt;WebAssembly does not replace the WebForms Core execution model.&lt;/p&gt;

&lt;p&gt;Instead, it provides another execution environment inside that model.&lt;/p&gt;




&lt;h1&gt;
  
  
  No Separate JavaScript Business Logic
&lt;/h1&gt;

&lt;p&gt;One of the interesting properties of this example is that application behavior can be implemented in Rust without creating a separate JavaScript business-logic layer.&lt;/p&gt;

&lt;p&gt;The Rust code contains the behavior:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;WebForms&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="nf"&gt;.set_text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input_place&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="nf"&gt;.set_background_color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"-"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;background_color&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="nf"&gt;.set_font_size&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"-"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;font_size&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="nf"&gt;.response&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The HTML contains standard 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;button&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"WasmEvent"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    Wasm Event
&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And WebForms Core connects the two:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetWasmEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"WasmEvent"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;HtmlEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OnClick&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;WasmLanguage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Rust&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;WasmPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"setData"&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 Rust code does not need to search for the button, register a DOM event listener, or manually update the target element.&lt;/p&gt;

&lt;p&gt;WebForms Core defines the interaction, while WebFormsJS executes the resulting commands in the browser.&lt;/p&gt;




&lt;h1&gt;
  
  
  Raw WebAssembly and wasm-bindgen Are Different
&lt;/h1&gt;

&lt;p&gt;It is important to distinguish these two approaches.&lt;/p&gt;

&lt;p&gt;A Raw WebAssembly module can expose functions directly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;module.wasm
     ↓
WebAssembly.instantiate()
     ↓
exported function
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;wasm-bindgen&lt;/code&gt; approach introduces a generated JavaScript interoperability layer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Rust
 ↓
wasm-bindgen
 ↓
generated JavaScript
 ↓
_bg.wasm
 ↓
Rust exported function
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These are different execution models.&lt;/p&gt;

&lt;p&gt;WebForms Core can provide an abstraction over both models while keeping the application-level WASM invocation consistent.&lt;/p&gt;




&lt;h1&gt;
  
  
  WebAssembly as an Execution Layer
&lt;/h1&gt;

&lt;p&gt;This example demonstrates a broader idea.&lt;/p&gt;

&lt;p&gt;WebAssembly does not necessarily have to represent an entire frontend application.&lt;/p&gt;

&lt;p&gt;A WASM module can instead provide a specific execution capability.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;WebForms Core
      ↓
Rust WASM
      ↓
Process data
      ↓
Generate WebForms Core response
      ↓
WebFormsJS
      ↓
Browser DOM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Rust code can therefore perform computation, generate UI commands, or return values without becoming a complete client-side application framework.&lt;/p&gt;

&lt;p&gt;This allows WebAssembly to participate in the existing WebForms Core command architecture.&lt;/p&gt;




&lt;h1&gt;
  
  
  Rust and WebForms Core
&lt;/h1&gt;

&lt;p&gt;Rust is particularly interesting in this architecture because it can be compiled into WebAssembly while still using the WebForms Core API.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;WebForms&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="nf"&gt;.set_text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"h3Tag"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Text From Wasm"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Rust code does not need to know how WebFormsJS internally executes the resulting command.&lt;/p&gt;

&lt;p&gt;It only creates the WebForms Core response.&lt;/p&gt;

&lt;p&gt;This separates:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Application execution
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;from:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Browser UI execution
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The WASM module performs its computation and creates the desired WebForms Core response, while WebFormsJS remains responsible for applying commands to the HTML DOM.&lt;/p&gt;




&lt;h1&gt;
  
  
  Rust WASM Compared with Direct JavaScript DOM Manipulation
&lt;/h1&gt;

&lt;p&gt;A conventional JavaScript approach might directly perform:&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="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;h3Tag&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Text From Wasm&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 Rust WebAssembly approach demonstrated here does not need to manipulate the DOM directly.&lt;/p&gt;

&lt;p&gt;Instead, it can produce WebForms Core behavior through:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="n"&gt;WebForms&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means the Rust code participates in the same command architecture used by the rest of the WebForms Core application.&lt;/p&gt;

&lt;p&gt;The UI execution remains centralized in the WebForms Core command pipeline.&lt;/p&gt;




&lt;h1&gt;
  
  
  WebForms Core 2.1
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;WebForms Core 2.1 extends the WebForms Core execution model with WebAssembly integration.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Rust is particularly interesting for this capability because it supports both:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;wasm-bindgen
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Raw WebAssembly
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The same WebForms Core application can therefore use Rust WASM as an execution layer while keeping its HTML and UI command model intact.&lt;/p&gt;

&lt;p&gt;The important point is not simply that:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Rust can run in the browser.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The more interesting part is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Rust running in WebAssembly can participate in the WebForms Core command architecture.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A WASM module can therefore become a computational or UI-command-producing execution environment without requiring the application to adopt a separate frontend architecture.&lt;/p&gt;




&lt;h1&gt;
  
  
  Final Architecture
&lt;/h1&gt;

&lt;p&gt;The complete architecture can be summarized as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                    Server
                      │
                      ↓
                  WebForms
                      │
                      ↓
                  WasmMethod
                      │
                      ↓
                  Browser
                      │
             ┌────────┴────────┐
             │                 │
             ↓                 ↓
      wasm-bindgen        Raw WebAssembly
             │                 │
             └────────┬────────┘
                      ↓
                    Rust
                      │
                      ↓
                  WebForms
                      │
                      ↓
          WebForms Core Response
                      │
                      ↓
                 WebFormsJS
                      │
                      ↓
                  HTML DOM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes Rust WebAssembly more than a way to run Rust code in the browser.&lt;/p&gt;

&lt;p&gt;It becomes another execution environment capable of participating in the &lt;strong&gt;WebForms Core server-orchestrated command architecture&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The same model can therefore combine:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Rust&lt;/li&gt;
&lt;li&gt;WebAssembly&lt;/li&gt;
&lt;li&gt;Raw WebAssembly&lt;/li&gt;
&lt;li&gt;&lt;code&gt;wasm-bindgen&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;WebForms Core&lt;/li&gt;
&lt;li&gt;WebForms Core commands&lt;/li&gt;
&lt;li&gt;WebFormsJS&lt;/li&gt;
&lt;li&gt;Standard HTML&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;without requiring the application to become a traditional JavaScript SPA.&lt;/p&gt;




&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Rust WebAssembly and WebForms Core provide an interesting combination.&lt;/p&gt;

&lt;p&gt;With &lt;code&gt;wasm-bindgen&lt;/code&gt;, Rust can expose a convenient WebAssembly API with JavaScript interoperability.&lt;/p&gt;

&lt;p&gt;With Raw WebAssembly, Rust can expose functions directly through &lt;code&gt;extern "C"&lt;/code&gt; using a developer-defined ABI.&lt;/p&gt;

&lt;p&gt;Both approaches can participate in the WebForms Core execution model.&lt;/p&gt;

&lt;p&gt;The result is a different way of thinking about WebAssembly:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;WebAssembly does not have to replace the UI architecture. It can become an execution layer inside the UI architecture.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When that execution layer can directly use &lt;code&gt;WebForms&lt;/code&gt;, Rust code can generate WebForms Core commands instead of implementing a separate client-side DOM architecture.&lt;/p&gt;

&lt;p&gt;This extends the WebForms Core execution model from:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Server
  ↓
WebForms
  ↓
Commands
  ↓
WebFormsJS
  ↓
HTML DOM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to also support:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Server
  ↓
WebForms
  ↓
WasmMethod
  ↓
Rust WASM
  ↓
WebForms
  ↓
Commands
  ↓
WebFormsJS
  ↓
HTML DOM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is one of the capabilities introduced by &lt;strong&gt;WebForms Core 2.1&lt;/strong&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Related Links
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://elanat.net/webforms-core" rel="noopener noreferrer"&gt;WebForms Core&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://elanat.net/webforms-js" rel="noopener noreferrer"&gt;WebFormsJS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/webforms-core" rel="noopener noreferrer"&gt;WebForms Core GitHub&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>rust</category>
      <category>webassembly</category>
      <category>tutorial</category>
      <category>webformscore</category>
    </item>
    <item>
      <title>Build Interactive Web Pages with TypeScript and WebForms Core</title>
      <dc:creator>Elanat Framework</dc:creator>
      <pubDate>Tue, 22 Sep 2026 18:23:01 +0000</pubDate>
      <link>https://dev.to/elanatframework/build-interactive-web-pages-with-typescript-and-webforms-core-46dm</link>
      <guid>https://dev.to/elanatframework/build-interactive-web-pages-with-typescript-and-webforms-core-46dm</guid>
      <description>&lt;p&gt;TypeScript can be used with WebForms Core as an &lt;strong&gt;isomorphic WebForms Commander&lt;/strong&gt;. This means the same WebForms class can be executed on both the server and client side.&lt;/p&gt;

&lt;p&gt;Instead of directly manipulating the DOM, the WebForms class creates WebForms Core commands. These commands are then executed by WebFormsJS in the browser.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installation via npm
&lt;/h2&gt;

&lt;p&gt;The TypeScript WebForms class is available through npm.&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;webformscore-ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The package provides the TypeScript WebForms Commander for WebForms Core.&lt;/p&gt;

&lt;h2&gt;
  
  
  Commander and Executor
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;webforms.ts&lt;/strong&gt; is an isomorphic class that can be executed on both the server and client side.&lt;/p&gt;

&lt;p&gt;This is the Commander class and should not be confused with the client-only WebFormsJS Executor library.&lt;/p&gt;

&lt;p&gt;WebForms Core consists of two main parts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Commander:&lt;/strong&gt; WebForms classes available for different programming languages.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Executor:&lt;/strong&gt; WebFormsJS, a front-end library whose physical file is &lt;code&gt;web-forms.js&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Commander creates WebForms Core commands, while the Executor executes those commands in the browser.&lt;/p&gt;

&lt;p&gt;WebFormsJS is normally placed in the &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; section of the HTML page. Other than its initial configuration, you work with the WebForms class functions rather than directly with WebFormsJS.&lt;/p&gt;

&lt;p&gt;This separation allows the same command-based programming model to be used in different environments.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7cjw4mawxdnvyqg7f5v4.jpg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7cjw4mawxdnvyqg7f5v4.jpg" alt="WebForms Core in TypeScript" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Work with WebForms Core in Front-End
&lt;/h2&gt;

&lt;p&gt;The TypeScript WebForms class can also be used directly on the front-end.&lt;/p&gt;

&lt;p&gt;Unlike WebForms classes that are primarily used on the server or WebAssembly, the TypeScript WebForms class is isomorphic and can run in both front-end and server-side environments. Since the TypeScript class is isomorphic, it can execute in a browser environment as well.&lt;/p&gt;

&lt;p&gt;To use it on the front-end, first make the WebForms class available in your project. Then create a simple HTML page.&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="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Using WebForms Core&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"module"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"/script/web-forms.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"Button1"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Set Dynamic Random Color&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
        &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;load&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;event&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="nc"&gt;FrontBack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/script/module/main.ts&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="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Usually, when the initial page is controlled from the server, the server can return HTML together with the output of the &lt;code&gt;exportToHtmlComment()&lt;/code&gt; method. WebFormsJS automatically finds the Action Controls in the HTML comments and executes them.&lt;/p&gt;

&lt;p&gt;In this example, however, the page is static. Therefore, the &lt;code&gt;FrontBack&lt;/code&gt; method is assigned directly to the page load event.&lt;/p&gt;

&lt;p&gt;After the page loads, &lt;code&gt;FrontBack&lt;/code&gt; executes the specified module.&lt;/p&gt;

&lt;p&gt;Modules executed through &lt;code&gt;FrontBack&lt;/code&gt; must provide a &lt;code&gt;PageLoad&lt;/code&gt; function with an &lt;code&gt;evt&lt;/code&gt; argument.&lt;/p&gt;

&lt;p&gt;Additional arguments can also be passed to &lt;code&gt;FrontBack&lt;/code&gt;. When provided, they are added after the &lt;code&gt;evt&lt;/code&gt; argument when &lt;code&gt;PageLoad&lt;/code&gt; is called.&lt;/p&gt;

&lt;h3&gt;
  
  
  TypeScript Module
&lt;/h3&gt;

&lt;p&gt;The following is &lt;code&gt;/script/module/main.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;WebForms&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;HtmlEvent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Fetch&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;./webforms.ts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;PageLoad&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;evt&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;form&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;WebForms&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setCommentEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Button1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;HtmlEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;OnClick&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;random-color&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startIndex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;random-color&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;removeCommentEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Button1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;HtmlEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;OnClick&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;f&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;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addSaveValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;color&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;rgb({{R}}, {{G}}, {{B}})&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replaceSaveValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;color&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;{{R}}&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Fetch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;random&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;256&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="nx"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replaceSaveValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;color&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;{{G}}&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Fetch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;random&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;256&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="nx"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replaceSaveValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;color&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;{{B}}&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Fetch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;random&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;256&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="nx"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setBackgroundColor&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;body&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Fetch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;color&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="nx"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;31536000&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;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;response&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;Here, the WebForms class first assigns an event to &lt;code&gt;Button1&lt;/code&gt;. When the button is clicked, the &lt;code&gt;random-color&lt;/code&gt; command sequence starts.&lt;/p&gt;

&lt;p&gt;The sequence generates three random values for red, green, and blue, creates an RGB color, and changes the page background. The &lt;code&gt;repeat&lt;/code&gt; operation runs the sequence repeatedly with a 500 millisecond delay.&lt;/p&gt;

&lt;p&gt;When the user clicks the button, the background color therefore changes to a new random RGB color every 500 milliseconds.&lt;/p&gt;

&lt;p&gt;The important point is that the TypeScript Commander does not directly perform the DOM operation. It creates WebForms Core commands, and WebFormsJS executes those commands in the browser.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using TypeScript with Node.js and Express
&lt;/h2&gt;

&lt;p&gt;The same TypeScript WebForms class can be used on the server.&lt;/p&gt;

&lt;p&gt;The following example uses Node.js and Express to process an HTML form and return WebForms Core commands.&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="nx"&gt;express&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;express&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;bodyParser&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;body-parser&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;WebForms&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;InputPlace&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./webforms&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;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;express&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;PORT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;static&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;public&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;bodyParser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;urlencoded&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;extended&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;}));&lt;/span&gt;

&lt;span class="nx"&gt;app&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="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&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;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`
        &amp;lt;!DOCTYPE html&amp;gt;
        &amp;lt;html&amp;gt;
        &amp;lt;head&amp;gt;
          &amp;lt;title&amp;gt;Using WebForms Core&amp;lt;/title&amp;gt;
          &amp;lt;script type="module" src="/script/web-forms.js"&amp;gt;&amp;lt;/script&amp;gt;
        &amp;lt;/head&amp;gt;
        &amp;lt;body&amp;gt;
            &amp;lt;form method="post" action="/"&amp;gt;
                &amp;lt;label for="txt_Name"&amp;gt;Your Name&amp;lt;/label&amp;gt;
                &amp;lt;input name="txt_Name" id="txt_Name" type="text" /&amp;gt;
                &amp;lt;br&amp;gt;
                &amp;lt;label for="txt_FontSize"&amp;gt;Set Font Size&amp;lt;/label&amp;gt;
                &amp;lt;input name="txt_FontSize" id="txt_FontSize" type="number" value="16" min="10" max="36" /&amp;gt;
                &amp;lt;br&amp;gt;
                &amp;lt;label for="txt_BackgroundColor"&amp;gt;Set Background Color&amp;lt;/label&amp;gt;
                &amp;lt;input name="txt_BackgroundColor" id="txt_BackgroundColor" type="text" /&amp;gt;
                &amp;lt;br&amp;gt;
                &amp;lt;input name="btn_SetBodyValue" type="submit" value="Click to send data" /&amp;gt;
            &amp;lt;/form&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;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&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;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&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;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;btn_SetBodyValue&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;name&lt;/span&gt; &lt;span class="o"&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;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;txt_Name&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;backgroundColor&lt;/span&gt; &lt;span class="o"&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;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;txt_BackgroundColor&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;fontSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;parseInt&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;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;txt_FontSize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&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;form&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;WebForms&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setFontSize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;InputPlace&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;form&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;fontSize&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setBackgroundColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;InputPlace&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;form&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setDisabled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;InputPlace&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;btn_SetBodyValue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addTag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;InputPlace&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;form&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;h3&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;InputPlace&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;h3&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s2"&gt;`Welcome &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="s2"&gt;!`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;response&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;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;PORT&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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Server is running on http://localhost:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, Express receives the submitted form values. The TypeScript WebForms class then creates commands that modify the existing page.&lt;/p&gt;

&lt;p&gt;The server can change the font size, change the background color, disable the submit button, add an &lt;code&gt;h3&lt;/code&gt; element, and set its text.&lt;/p&gt;

&lt;p&gt;The response is generated with:&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="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;response&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The browser receives the WebForms Core commands and WebFormsJS executes them.&lt;/p&gt;

&lt;h2&gt;
  
  
  One Commander, Multiple Environments
&lt;/h2&gt;

&lt;p&gt;TypeScript makes it possible to use the WebForms Core Commander in both browser and server environments.&lt;/p&gt;

&lt;p&gt;The same programming model can therefore be used for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Front-end TypeScript modules&lt;/li&gt;
&lt;li&gt;Node.js applications&lt;/li&gt;
&lt;li&gt;Express applications&lt;/li&gt;
&lt;li&gt;Server-side HTML responses&lt;/li&gt;
&lt;li&gt;Other JavaScript-compatible environments&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The architecture remains simple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;TypeScript WebForms Class
          ↓
   WebForms Core Commands
          ↓
       WebFormsJS
          ↓
      HTML DOM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The TypeScript class decides what should happen, while WebFormsJS performs the execution in the browser.&lt;/p&gt;

&lt;h2&gt;
  
  
  WebFormsJS
&lt;/h2&gt;

&lt;p&gt;As shown in the examples, WebFormsJS is included in the HTML &lt;code&gt;&amp;lt;head&amp;gt;&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;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"module"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"/script/web-forms.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The WebFormsJS library is the Executor layer of WebForms Core. Application logic can remain focused on the WebForms class rather than directly manipulating the DOM.&lt;/p&gt;

&lt;p&gt;The latest WebFormsJS script is available in the WebForms repository.&lt;/p&gt;

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

&lt;p&gt;With the TypeScript WebForms class, WebForms Core can be used from both sides of a web application.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;Commander&lt;/strong&gt; can run in TypeScript on the server or in the browser, while &lt;strong&gt;WebFormsJS&lt;/strong&gt; provides the client-side execution layer.&lt;/p&gt;

&lt;p&gt;This makes TypeScript a natural environment for building WebForms Core applications with the same command-based programming model across front-end and back-end development.&lt;/p&gt;

&lt;h2&gt;
  
  
  Related links
&lt;/h2&gt;

&lt;p&gt;On Elanat:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://elanat.net/webforms-core" rel="noopener noreferrer"&gt;WebForms Core Page&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://elanat.net/webforms-js" rel="noopener noreferrer"&gt;WebFormsJS Page&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On GitHub:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/webforms-core" rel="noopener noreferrer"&gt;WebForms Core Organizations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/webforms-core/Web_forms" rel="noopener noreferrer"&gt;WebFormsJS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/webforms-core/Web_forms_classes" rel="noopener noreferrer"&gt;WebForms Classes&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On npm:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.npmjs.com/package/webformscore-ts" rel="noopener noreferrer"&gt;WebFormsTS&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>typescript</category>
      <category>frontend</category>
      <category>backend</category>
      <category>webformscore</category>
    </item>
    <item>
      <title>AssemblyScript WebAssembly Meets WebForms Core 2.1</title>
      <dc:creator>Elanat Framework</dc:creator>
      <pubDate>Mon, 21 Sep 2026 21:17:18 +0000</pubDate>
      <link>https://dev.to/elanatframework/assemblyscript-webassembly-meets-webforms-core-21-31o4</link>
      <guid>https://dev.to/elanatframework/assemblyscript-webassembly-meets-webforms-core-21-31o4</guid>
      <description>&lt;h2&gt;
  
  
  What is WebForms Core?
&lt;/h2&gt;

&lt;p&gt;WebForms Core is a server-orchestrated UI technology that allows the server to generate commands for manipulating the browser DOM and controlling UI behavior.&lt;/p&gt;

&lt;p&gt;Its architecture can be summarized as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Server → WebForms → Commands → WebFormsJS → HTML DOM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;WebForms Core does not require a separate frontend project, component framework, JSX, or a virtual DOM. It works with standard HTML and lets the server define UI operations through the &lt;code&gt;WebForms&lt;/code&gt; class.&lt;/p&gt;

&lt;p&gt;With WebAssembly support, this architecture can also invoke WebAssembly methods as part of the UI execution flow.&lt;/p&gt;

&lt;p&gt;This means WebAssembly does not have to replace the UI architecture. It can become an execution layer inside the UI architecture.&lt;/p&gt;




&lt;h2&gt;
  
  
  AssemblyScript WebAssembly
&lt;/h2&gt;

&lt;p&gt;AssemblyScript is a TypeScript-like language designed to compile to WebAssembly.&lt;/p&gt;

&lt;p&gt;This makes it particularly interesting for browser applications that want a WebAssembly execution layer while using a language syntax familiar to JavaScript and TypeScript developers.&lt;/p&gt;

&lt;p&gt;In this example, AssemblyScript is used together with WebForms Core 2.1.&lt;/p&gt;

&lt;p&gt;The AssemblyScript module can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;execute numerical methods&lt;/li&gt;
&lt;li&gt;receive string parameters&lt;/li&gt;
&lt;li&gt;create WebForms commands&lt;/li&gt;
&lt;li&gt;return WebForms responses&lt;/li&gt;
&lt;li&gt;generate HTML&lt;/li&gt;
&lt;li&gt;participate in WebForms Core events&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The important part is that the AssemblyScript code does not need to manipulate the browser DOM directly.&lt;/p&gt;

&lt;p&gt;Instead, it can use the &lt;code&gt;WebForms&lt;/code&gt; class to generate the WebForms Core response.&lt;/p&gt;




&lt;h2&gt;
  
  
  Installation via Package
&lt;/h2&gt;

&lt;h3&gt;
  
  
  AssemblyScript in npm
&lt;/h3&gt;

&lt;p&gt;You can install the WebForms Core AssemblyScript package directly from npm:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.npmjs.com/package/webformscore-wasm" rel="noopener noreferrer"&gt;webformscore-wasm&lt;/a&gt;&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;webformscore-wasm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The package provides the AssemblyScript implementation required to use the WebForms Core API from AssemblyScript WebAssembly modules.&lt;/p&gt;

&lt;h3&gt;
  
  
  WebFormsJS in GitHub
&lt;/h3&gt;

&lt;p&gt;Always get the latest version of WebFormsJS directly from GitHub:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/webforms-core/Web_forms" rel="noopener noreferrer"&gt;WebFormsJS&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;WebFormsJS provides the client-side runtime responsible for executing WebForms Core commands in the browser.&lt;/p&gt;




&lt;h2&gt;
  
  
  Creating the AssemblyScript Project
&lt;/h2&gt;

&lt;p&gt;An AssemblyScript project can be created using the AssemblyScript toolchain.&lt;/p&gt;

&lt;p&gt;A typical project contains an entry point such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;assembly/
    index.ts
    webforms.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;webforms.ts&lt;/code&gt; file contains the AssemblyScript implementation of the WebForms class.&lt;/p&gt;

&lt;p&gt;The application can then compile the AssemblyScript source into a WebAssembly module.&lt;/p&gt;

&lt;p&gt;For example, the resulting file can be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;release.wasm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Depending on the execution model, a JavaScript module can also be generated:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;release.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;WebForms Core can work with the corresponding WebAssembly execution path.&lt;/p&gt;




&lt;h2&gt;
  
  
  Using WebForms Core from AssemblyScript
&lt;/h2&gt;

&lt;p&gt;The interesting part of this example is that the AssemblyScript code uses the WebForms Core API directly.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;index.ts&lt;/code&gt; file contains the exported WebAssembly methods:&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;WebForms&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;./webforms&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;i32&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;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;setData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;inputPlace&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="nx"&gt;text&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="nx"&gt;backgroundColor&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="nx"&gt;fontSize&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="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;form&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;WebForms&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;inputPlace&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setBackgroundColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;-&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setFontSize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;-&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fontSize&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;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;response&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getHtml&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;marquee&amp;gt;Tag From Wasm!&amp;lt;/marquee&amp;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="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;createWebForms&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;WebForms&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;WebForms&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;There are three methods used by the WebForms Core example:&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;add&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;add(10000, 3)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;returns:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;10003
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;setData&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;The method receives four strings:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;inputPlace
text
backgroundColor
fontSize
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It creates a &lt;code&gt;WebForms&lt;/code&gt; object and generates a WebForms Core response.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;getHtml&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;This method returns 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;marquee&amp;gt;&lt;/span&gt;Tag From Wasm!&lt;span class="nt"&gt;&amp;lt;/marquee&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The HTML can then be placed into the browser through a WebForms Core event.&lt;/p&gt;




&lt;h2&gt;
  
  
  The WebForms Class in AssemblyScript
&lt;/h2&gt;

&lt;p&gt;The important architectural detail is that &lt;code&gt;WebForms&lt;/code&gt; is not a browser component.&lt;/p&gt;

&lt;p&gt;The AssemblyScript code uses it as a command generator.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;form&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;WebForms&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;inputPlace&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setBackgroundColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;-&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setFontSize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;-&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fontSize&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;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;response&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The resulting response is interpreted by WebFormsJS in the browser.&lt;/p&gt;

&lt;p&gt;Therefore the flow becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AssemblyScript
      ↓
WebForms
      ↓
WebForms Core Commands
      ↓
WebFormsJS
      ↓
HTML DOM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;AssemblyScript does not need to know how the browser applies these commands.&lt;/p&gt;

&lt;p&gt;That responsibility belongs to WebFormsJS.&lt;/p&gt;




&lt;h2&gt;
  
  
  Using AssemblyScript WebAssembly from WebForms Core
&lt;/h2&gt;

&lt;p&gt;The server-side controller can invoke AssemblyScript methods through the WebForms Core WASM API.&lt;/p&gt;

&lt;p&gt;The actual execution of the method takes place in the browser.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Server-side configuration
           ↓
      WebFormsJS
           ↓
Browser WebAssembly runtime
           ↓
  AssemblyScript method
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The controller is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;CodeBehind&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;partial&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;WasmAssemblyScriptController&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;CodeBehindController&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;PageLoad&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HttpContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;WasmPath&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"/web-assembly/assembly-script/release.wasm"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// or release.js&lt;/span&gt;

        &lt;span class="n"&gt;WebForms&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;WebForms&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;"&amp;lt;b&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;Fetch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WasmMethod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="n"&gt;WasmLanguage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AssemblyScript&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;WasmPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s"&gt;"add"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;3&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="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetWasmEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;"WasmEvent"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;HtmlEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OnClick&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;WasmLanguage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AssemblyScript&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;WasmPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"setData"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"h3Tag"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Text From Wasm"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"lightgreen"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"30px"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetWasmEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;"WasmEventWithOutput"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;HtmlEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OnClick&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;WasmLanguage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AssemblyScript&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;WasmPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"getHtml"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;[],&lt;/span&gt;
            &lt;span class="s"&gt;"WasmHtmlOutput"&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="nf"&gt;Write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ExportToHtmlComment&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 controller does not contain AssemblyScript implementation details.&lt;/p&gt;

&lt;p&gt;It only defines how the WebAssembly methods participate in the WebForms Core UI flow.&lt;/p&gt;




&lt;h2&gt;
  
  
  HTML
&lt;/h2&gt;

&lt;p&gt;The page itself remains ordinary HTML:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;@page
@controller WasmAssemblyScriptController
@layout "/layout.aspx"
@{
  ViewData.Add("title","AssemblyScript Wasm");
}
&lt;span class="nt"&gt;&amp;lt;h3&amp;gt;&lt;/span&gt;AssemblyScript Wasm&lt;span class="nt"&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;b&amp;gt;&lt;/span&gt;AssemblyScript WASM Result: &lt;span class="nt"&gt;&amp;lt;/b&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;br&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"WasmEvent"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Wasm Event&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;br&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;h3&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"h3Tag"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Wasm Tag Changing!&lt;span class="nt"&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"WasmEventWithOutput"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Wasm Event With Output&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"WasmHtmlOutput"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Wasm Html Output&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is no AssemblyScript-specific markup.&lt;/p&gt;

&lt;p&gt;There is no custom WebAssembly element.&lt;/p&gt;

&lt;p&gt;There is no component declaration.&lt;/p&gt;

&lt;p&gt;The HTML remains standard HTML.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Interesting Part
&lt;/h2&gt;

&lt;p&gt;The controller uses the same WebForms Core concepts regardless of where the method is implemented.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"&amp;lt;b&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Fetch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WasmMethod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;WasmLanguage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AssemblyScript&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;WasmPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"add"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;3&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;add&lt;/code&gt; method is implemented in AssemblyScript, but its result can be consumed by WebForms Core.&lt;/p&gt;

&lt;p&gt;The second method is more interesting:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetWasmEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"WasmEvent"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;HtmlEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OnClick&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;WasmLanguage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AssemblyScript&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;WasmPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"setData"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"h3Tag"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Text From Wasm"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"lightgreen"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"30px"&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;When the button is clicked, WebFormsJS can invoke the AssemblyScript WebAssembly method.&lt;/p&gt;

&lt;p&gt;The method creates a &lt;code&gt;WebForms&lt;/code&gt; response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;form&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;WebForms&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;inputPlace&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setBackgroundColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;-&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setFontSize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;-&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fontSize&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;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;response&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The response is then interpreted by WebFormsJS.&lt;/p&gt;

&lt;p&gt;So the execution chain is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HTML Event
    ↓
WebFormsJS
    ↓
AssemblyScript WASM
    ↓
WebForms
    ↓
WebForms Core Response
    ↓
WebFormsJS
    ↓
DOM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is different from simply calling a WebAssembly function and returning a number.&lt;/p&gt;

&lt;p&gt;The WebAssembly method can become a producer of UI commands.&lt;/p&gt;




&lt;h2&gt;
  
  
  WASM Event With Output
&lt;/h2&gt;

&lt;p&gt;The third method demonstrates another possibility:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetWasmEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"WasmEventWithOutput"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;HtmlEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OnClick&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;WasmLanguage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AssemblyScript&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;WasmPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"getHtml"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;[],&lt;/span&gt;
    &lt;span class="s"&gt;"WasmHtmlOutput"&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The AssemblyScript method returns HTML:&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;getHtml&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;marquee&amp;gt;Tag From Wasm!&amp;lt;/marquee&amp;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;WebForms Core can then place the returned value into:&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;p&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"WasmHtmlOutput"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Wasm Html Output&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This demonstrates that WebAssembly methods can participate directly in the WebForms Core output flow.&lt;/p&gt;




&lt;h2&gt;
  
  
  AssemblyScript Is an Execution Layer
&lt;/h2&gt;

&lt;p&gt;This example demonstrates an important distinction.&lt;/p&gt;

&lt;p&gt;WebAssembly is not being used here to build a complete frontend application.&lt;/p&gt;

&lt;p&gt;AssemblyScript is being used as an execution layer.&lt;/p&gt;

&lt;p&gt;The UI architecture remains:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HTML
  +
WebForms Core
  +
WebFormsJS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;AssemblyScript is inserted where a WebAssembly execution capability is useful:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;             WebForms Core
                  │
        ┌─────────┴─────────┐
        │                   │
   Server WebForms     WebAssembly
                            │
                      AssemblyScript
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This allows the application to use WebAssembly selectively instead of moving the entire application into a WebAssembly frontend.&lt;/p&gt;




&lt;h2&gt;
  
  
  No JavaScript Business Logic
&lt;/h2&gt;

&lt;p&gt;One of the interesting aspects of this architecture is that the application does not need custom JavaScript business logic for these operations.&lt;/p&gt;

&lt;p&gt;The AssemblyScript method performs the computation or generates the WebForms Core response.&lt;/p&gt;

&lt;p&gt;WebFormsJS remains the browser runtime responsible for executing the resulting commands.&lt;/p&gt;

&lt;p&gt;Therefore:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AssemblyScript → WebForms Commands → WebFormsJS → DOM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;rather than:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AssemblyScript → Custom JavaScript → DOM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This separation keeps the WebAssembly layer independent from the application's browser-side DOM implementation.&lt;/p&gt;




&lt;h2&gt;
  
  
  Standard HTML Remains the UI
&lt;/h2&gt;

&lt;p&gt;The AssemblyScript example does not introduce a new component model.&lt;/p&gt;

&lt;p&gt;The page still contains:&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;h3&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"h3Tag"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Wasm Tag Changing!&lt;span class="nt"&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and:&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;button&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"WasmEvent"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Wasm Event&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The server assigns behavior to these existing elements.&lt;/p&gt;

&lt;p&gt;This is one of the important characteristics of WebForms Core.&lt;/p&gt;

&lt;p&gt;WebAssembly does not require the UI to be redesigned around WebAssembly components.&lt;/p&gt;




&lt;h2&gt;
  
  
  AssemblyScript and WebForms Core
&lt;/h2&gt;

&lt;p&gt;The AssemblyScript implementation demonstrates that a WebAssembly language can use the same WebForms Core model as other supported languages.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fx3amikxr5lw9b2za28hw.jpg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fx3amikxr5lw9b2za28hw.jpg" alt="AssemblyScript in WebForms Core Technology" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The important relationship is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AssemblyScript
      ↓
WebForms Class
      ↓
Action Controls / Response
      ↓
WebFormsJS
      ↓
Browser DOM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The WebForms class acts as the bridge between application logic and WebForms Core command generation.&lt;/p&gt;

&lt;p&gt;This makes the WebAssembly module more than an isolated computational library.&lt;/p&gt;

&lt;p&gt;It can participate in the UI execution model.&lt;/p&gt;




&lt;h2&gt;
  
  
  WebAssembly Does Not Have to Replace the UI Architecture
&lt;/h2&gt;

&lt;p&gt;A common approach to WebAssembly applications is to move a large portion of the frontend into the WebAssembly runtime.&lt;/p&gt;

&lt;p&gt;WebForms Core takes a different approach.&lt;/p&gt;

&lt;p&gt;WebAssembly can be introduced only where it provides value.&lt;/p&gt;

&lt;p&gt;For example, an application can continue using:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;standard HTML&lt;/li&gt;
&lt;li&gt;server-side WebForms&lt;/li&gt;
&lt;li&gt;WebFormsJS&lt;/li&gt;
&lt;li&gt;server-generated commands&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;while selectively executing AssemblyScript code through WebAssembly.&lt;/p&gt;

&lt;p&gt;This makes WebAssembly an execution capability rather than a mandatory application architecture.&lt;/p&gt;




&lt;h2&gt;
  
  
  AssemblyScript WebAssembly vs JavaScript
&lt;/h2&gt;

&lt;p&gt;AssemblyScript provides a particularly interesting option for developers coming from the JavaScript and TypeScript ecosystem.&lt;/p&gt;

&lt;p&gt;The source syntax is familiar:&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;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;i32&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;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;b&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;but the resulting code executes as WebAssembly.&lt;/p&gt;

&lt;p&gt;When combined with WebForms Core, the result is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Server
  ↓
WebForms
  ↓
WebAssembly Method
  ↓
AssemblyScript
  ↓
WebForms Response
  ↓
WebFormsJS
  ↓
DOM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The browser therefore remains responsible for UI execution while AssemblyScript provides a WebAssembly execution layer.&lt;/p&gt;




&lt;h2&gt;
  
  
  WebForms Core 2.1
&lt;/h2&gt;

&lt;p&gt;WebForms Core 2.1 extends the architecture beyond a single programming language.&lt;/p&gt;

&lt;p&gt;The same general WebForms model can be used with different WebAssembly implementations.&lt;/p&gt;

&lt;p&gt;This makes the WebAssembly layer replaceable.&lt;/p&gt;

&lt;p&gt;An application can choose AssemblyScript when its execution model is appropriate, while other parts of the system can use different WebAssembly languages.&lt;/p&gt;

&lt;p&gt;The UI command architecture does not have to change.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Result
&lt;/h2&gt;

&lt;p&gt;The final application combines four technologies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CodeBehind
     ↓
WebForms Core 2.1
     ↓
AssemblyScript WebAssembly
     ↓
WebFormsJS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;AssemblyScript provides the WebAssembly execution layer.&lt;/p&gt;

&lt;p&gt;WebForms provides the command-generation model.&lt;/p&gt;

&lt;p&gt;WebFormsJS provides browser-side execution.&lt;/p&gt;

&lt;p&gt;HTML remains the UI.&lt;/p&gt;

&lt;p&gt;The result is a WebAssembly application model without requiring a separate frontend architecture.&lt;/p&gt;




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

&lt;p&gt;AssemblyScript and WebForms Core provide an interesting combination.&lt;/p&gt;

&lt;p&gt;AssemblyScript can be used to execute WebAssembly code while the WebForms class provides a direct way to generate WebForms Core responses.&lt;/p&gt;

&lt;p&gt;The important point is not simply that AssemblyScript can run in the browser.&lt;/p&gt;

&lt;p&gt;The more interesting idea is that &lt;strong&gt;WebAssembly can become another execution layer inside a server-orchestrated UI architecture.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Instead of replacing the HTML and UI architecture with a WebAssembly application, AssemblyScript can work inside the existing flow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Server → WebForms → WebAssembly → WebForms Commands → WebFormsJS → DOM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This keeps the UI based on standard HTML while allowing WebAssembly to perform computation, generate UI responses, and participate in interactive browser events.&lt;/p&gt;

&lt;h2&gt;
  
  
  Related links
&lt;/h2&gt;

&lt;p&gt;In Elanat:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://elanat.net/webforms-core" rel="noopener noreferrer"&gt;WebForms Core Page&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://elanat.net/webforms-js" rel="noopener noreferrer"&gt;WebFormsJS Page&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;in GitHub:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/webforms-core" rel="noopener noreferrer"&gt;WebForms Core Organizations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/webforms-core/Web_forms" rel="noopener noreferrer"&gt;WebFormsJS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/webforms-core/Web_forms_classes" rel="noopener noreferrer"&gt;WebForms Classes&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>assemblyscript</category>
      <category>webassembly</category>
      <category>frontend</category>
      <category>webformscore</category>
    </item>
    <item>
      <title>Experience the Server Renaissance in Julia: Build Interactive Web Pages with WebForms Core</title>
      <dc:creator>Elanat Framework</dc:creator>
      <pubDate>Mon, 21 Sep 2026 20:51:24 +0000</pubDate>
      <link>https://dev.to/elanatframework/experience-the-server-renaissance-in-julia-build-interactive-web-pages-with-webforms-core-4of7</link>
      <guid>https://dev.to/elanatframework/experience-the-server-renaissance-in-julia-build-interactive-web-pages-with-webforms-core-4of7</guid>
      <description>&lt;p&gt;Julia is widely known for numerical computing, scientific programming, data analysis, and high-performance applications. But Julia can also be used to build web applications.&lt;/p&gt;

&lt;p&gt;With &lt;a href="https://elanat.net/webforms-core" rel="noopener noreferrer"&gt;&lt;strong&gt;WebForms Core&lt;/strong&gt;&lt;/a&gt;, Julia applications can manipulate the browser UI from the server using server-side WebForms classes and WebForms commands.&lt;/p&gt;

&lt;p&gt;The result is a different approach to interactive web development:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Julia Server → WebForms → Commands → WebFormsJS → HTML DOM&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Instead of writing JavaScript for every UI operation, the server can generate commands that WebFormsJS executes in the browser.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installation and Downloads
&lt;/h2&gt;

&lt;p&gt;The Julia implementation of WebForms Core is provided as &lt;strong&gt;WebForms.jl&lt;/strong&gt;, while the browser-side Executor is provided by &lt;strong&gt;WebFormsJS&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Download WebForms.jl
&lt;/h3&gt;

&lt;p&gt;Download the Julia WebForms Core library directly from GitHub:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/webforms-core/Web_forms_classes/tree/elanat_framework/julia" rel="noopener noreferrer"&gt;Download WebForms.jl&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then include the library in your Julia application:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight julia"&gt;&lt;code&gt;&lt;span class="n"&gt;include&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"WebForms.jl"&lt;/span&gt;&lt;span class="x"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WebFormsCore&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WebFormsCore&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;WebForms&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WebFormsCore&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;InputPlace&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Download WebFormsJS
&lt;/h3&gt;

&lt;p&gt;WebFormsJS is the client-side JavaScript Executor responsible for executing WebForms commands and manipulating the HTML DOM.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.npmjs.com/package/webformsjs" rel="noopener noreferrer"&gt;Get WebFormsJS in npm&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://elanat.net/webforms-js" rel="noopener noreferrer"&gt;WebFormsJS Page in Elanat&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can also obtain the source directly from GitHub:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/webforms-core/Web_forms" rel="noopener noreferrer"&gt;WebFormsJS on GitHub&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; We also attempted to publish the WebForms Core package for Julia through the Julia General registry. However, the registry has strict requirements for package structure, documentation, testing, versioning, and release management, and we did not have the time required to meet all of these requirements for this project. For this reason, we decided not to continue with the registration process. &lt;code&gt;WebForms.jl&lt;/code&gt; will remain available directly from its GitHub repository, where Julia developers can download and use it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In the examples in this article, &lt;code&gt;web-forms.js&lt;/code&gt; is served by the Julia application through &lt;strong&gt;HTTP.jl&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight julia"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"/script/web-forms.js"&lt;/span&gt;
    &lt;span class="n"&gt;js&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;joinpath&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@__DIR__&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"script"&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"web-forms.js"&lt;/span&gt;&lt;span class="x"&gt;),&lt;/span&gt;
        &lt;span class="kt"&gt;String&lt;/span&gt;
    &lt;span class="x"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;
        &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt;
        &lt;span class="x"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"Content-Type"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"text/javascript"&lt;/span&gt;&lt;span class="x"&gt;],&lt;/span&gt;
        &lt;span class="n"&gt;js&lt;/span&gt;
    &lt;span class="x"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The web server used throughout the examples is &lt;strong&gt;HTTP.jl&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight julia"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="n"&gt;HTTP&lt;/span&gt;

&lt;span class="n"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;serve&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;handle_request&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"127.0.0.1"&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt;
    &lt;span class="mi"&gt;8080&lt;/span&gt;
&lt;span class="x"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gives the application a simple architecture:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Julia + HTTP.jl
       │
       ▼
   WebForms.jl
       │
       ▼
 WebForms Commands
       │
       ▼
   WebFormsJS
       │
       ▼
    HTML DOM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  WebForms Core for Julia
&lt;/h2&gt;

&lt;p&gt;The Julia implementation of WebForms Core provides the WebForms API directly inside Julia applications.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fd7tzs8fm2c3fqt37o44s.jpg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fd7tzs8fm2c3fqt37o44s.jpg" alt="WebForms Core in Julia" width="799" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A basic application can use Julia's &lt;code&gt;HTTP&lt;/code&gt; package as its HTTP server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight julia"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="n"&gt;HTTP&lt;/span&gt;

&lt;span class="n"&gt;include&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"WebForms.jl"&lt;/span&gt;&lt;span class="x"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WebFormsCore&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WebFormsCore&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;WebForms&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WebFormsCore&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;InputPlace&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;WebForms&lt;/code&gt; module provides the server-side API for creating and manipulating WebForms commands.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight julia"&gt;&lt;code&gt;&lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;WebForms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Form&lt;/span&gt;&lt;span class="x"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;WebForms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_font_size&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt; &lt;span class="n"&gt;InputPlace&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"form"&lt;/span&gt;&lt;span class="x"&gt;),&lt;/span&gt; &lt;span class="n"&gt;font_size&lt;/span&gt;&lt;span class="x"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;WebForms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_background_color&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt; &lt;span class="n"&gt;InputPlace&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"form"&lt;/span&gt;&lt;span class="x"&gt;),&lt;/span&gt; &lt;span class="n"&gt;background_color&lt;/span&gt;&lt;span class="x"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;WebForms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_disabled&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt; &lt;span class="n"&gt;InputPlace&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"btn_SetBodyValue"&lt;/span&gt;&lt;span class="x"&gt;),&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="x"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;WebForms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_tag&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt; &lt;span class="n"&gt;InputPlace&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"form"&lt;/span&gt;&lt;span class="x"&gt;),&lt;/span&gt; &lt;span class="s"&gt;"h3"&lt;/span&gt;&lt;span class="x"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;WebForms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_text&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt; &lt;span class="n"&gt;InputPlace&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"h3"&lt;/span&gt;&lt;span class="x"&gt;),&lt;/span&gt; &lt;span class="s"&gt;"Welcome &lt;/span&gt;&lt;span class="si"&gt;$(name)&lt;/span&gt;&lt;span class="s"&gt;!"&lt;/span&gt;&lt;span class="x"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These operations do not directly manipulate the browser DOM from Julia.&lt;/p&gt;

&lt;p&gt;Instead, they construct WebForms commands.&lt;/p&gt;

&lt;p&gt;WebFormsJS then receives those commands and executes them in the browser.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Complete Julia Example
&lt;/h2&gt;

&lt;p&gt;Consider a simple page where the user enters a name, chooses a font size, and specifies a background color.&lt;/p&gt;

&lt;p&gt;The HTML itself remains ordinary HTML:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight julia"&gt;&lt;code&gt;&lt;span class="n"&gt;html&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"""
&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
  &amp;lt;title&amp;gt;Using WebForms Core&amp;lt;/title&amp;gt;
  &amp;lt;script type="&lt;/span&gt;&lt;span class="k"&gt;module&lt;/span&gt;&lt;span class="s"&gt;" src="&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;script&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;web&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;forms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;js&lt;/span&gt;&lt;span class="s"&gt;"&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;form method="&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="s"&gt;" action="&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="s"&gt;"&amp;gt;
        &amp;lt;label for="&lt;/span&gt;&lt;span class="n"&gt;txt_Name&lt;/span&gt;&lt;span class="s"&gt;"&amp;gt;Your Name&amp;lt;/label&amp;gt;
        &amp;lt;input name="&lt;/span&gt;&lt;span class="n"&gt;txt_Name&lt;/span&gt;&lt;span class="s"&gt;" id="&lt;/span&gt;&lt;span class="n"&gt;txt_Name&lt;/span&gt;&lt;span class="s"&gt;" type="&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="s"&gt;" /&amp;gt;
        &amp;lt;br&amp;gt;
        &amp;lt;label for="&lt;/span&gt;&lt;span class="n"&gt;txt_FontSize&lt;/span&gt;&lt;span class="s"&gt;"&amp;gt;Set Font Size&amp;lt;/label&amp;gt;
        &amp;lt;input name="&lt;/span&gt;&lt;span class="n"&gt;txt_FontSize&lt;/span&gt;&lt;span class="s"&gt;" id="&lt;/span&gt;&lt;span class="n"&gt;txt_FontSize&lt;/span&gt;&lt;span class="s"&gt;" type="&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="s"&gt;" value="&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="s"&gt;" min="&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="s"&gt;" max="&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="s"&gt;" /&amp;gt;
        &amp;lt;br&amp;gt;
        &amp;lt;label for="&lt;/span&gt;&lt;span class="n"&gt;txt_BackgroundColor&lt;/span&gt;&lt;span class="s"&gt;"&amp;gt;Set Background Color&amp;lt;/label&amp;gt;
        &amp;lt;input name="&lt;/span&gt;&lt;span class="n"&gt;txt_BackgroundColor&lt;/span&gt;&lt;span class="s"&gt;" id="&lt;/span&gt;&lt;span class="n"&gt;txt_BackgroundColor&lt;/span&gt;&lt;span class="s"&gt;" type="&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="s"&gt;" /&amp;gt;
        &amp;lt;br&amp;gt;
        &amp;lt;input name="&lt;/span&gt;&lt;span class="n"&gt;btn_SetBodyValue&lt;/span&gt;&lt;span class="s"&gt;" type="&lt;/span&gt;&lt;span class="n"&gt;submit&lt;/span&gt;&lt;span class="s"&gt;" value="&lt;/span&gt;&lt;span class="n"&gt;Click&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;send&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="s"&gt;" /&amp;gt;
    &amp;lt;/form&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
"""&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When the form is submitted, Julia receives the request and processes the values:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight julia"&gt;&lt;code&gt;&lt;span class="n"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="x"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;queryparams&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="x"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;haskey&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"btn_SetBodyValue"&lt;/span&gt;&lt;span class="x"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"txt_Name"&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="x"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;background_color&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"txt_BackgroundColor"&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="x"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;font_size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;parse&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Int&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt; &lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"txt_FontSize"&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"16"&lt;/span&gt;&lt;span class="x"&gt;))&lt;/span&gt;

    &lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;WebForms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Form&lt;/span&gt;&lt;span class="x"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;WebForms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_font_size&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;InputPlace&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"form"&lt;/span&gt;&lt;span class="x"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;font_size&lt;/span&gt;
    &lt;span class="x"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;WebForms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_background_color&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;InputPlace&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"form"&lt;/span&gt;&lt;span class="x"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;background_color&lt;/span&gt;
    &lt;span class="x"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;WebForms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_disabled&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;InputPlace&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"btn_SetBodyValue"&lt;/span&gt;&lt;span class="x"&gt;),&lt;/span&gt;
        &lt;span class="nb"&gt;true&lt;/span&gt;
    &lt;span class="x"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;WebForms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_tag&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;InputPlace&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"form"&lt;/span&gt;&lt;span class="x"&gt;),&lt;/span&gt;
        &lt;span class="s"&gt;"h3"&lt;/span&gt;
    &lt;span class="x"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;WebForms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_text&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;InputPlace&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"h3"&lt;/span&gt;&lt;span class="x"&gt;),&lt;/span&gt;
        &lt;span class="s"&gt;"Welcome &lt;/span&gt;&lt;span class="si"&gt;$(name)&lt;/span&gt;&lt;span class="s"&gt;!"&lt;/span&gt;
    &lt;span class="x"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;
        &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;WebForms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="x"&gt;)&lt;/span&gt;
    &lt;span class="x"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important part is that the server does not need to return an entirely new HTML document.&lt;/p&gt;

&lt;p&gt;It returns a WebForms response containing instructions for the browser.&lt;/p&gt;

&lt;p&gt;The browser then executes those instructions through WebFormsJS.&lt;/p&gt;

&lt;h2&gt;
  
  
  Server-Orchestrated UI
&lt;/h2&gt;

&lt;p&gt;This is the central idea behind WebForms Core.&lt;/p&gt;

&lt;p&gt;The server determines &lt;strong&gt;what UI operation should happen&lt;/strong&gt;, while WebFormsJS performs the actual browser-side execution.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Julia
  │
  │ WebForms commands
  ▼
WebForms
  │
  │ WebForms response
  ▼
WebFormsJS
  │
  │ DOM operations
  ▼
HTML DOM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates a &lt;strong&gt;Commander–Executor&lt;/strong&gt; architecture.&lt;/p&gt;

&lt;p&gt;The WebForms class acts as the server-side Commander.&lt;/p&gt;

&lt;p&gt;WebFormsJS acts as the client-side Executor.&lt;/p&gt;

&lt;p&gt;Julia therefore does not need to contain JavaScript implementations for every UI operation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Interactive UI Without Writing JavaScript
&lt;/h2&gt;

&lt;p&gt;WebForms Core can also define browser events from Julia.&lt;/p&gt;

&lt;p&gt;Consider this page:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight julia"&gt;&lt;code&gt;&lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="nf"&gt; html_form&lt;/span&gt;&lt;span class="x"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"""
    &amp;lt;!DOCTYPE html&amp;gt;
    &amp;lt;html&amp;gt;
    &amp;lt;head&amp;gt;
        &amp;lt;title&amp;gt;WebForms Core Technology in Julia&amp;lt;/title&amp;gt;
        &amp;lt;script type="&lt;/span&gt;&lt;span class="k"&gt;module&lt;/span&gt;&lt;span class="s"&gt;" src="&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;script&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;web&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;forms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;js&lt;/span&gt;&lt;span class="s"&gt;"&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;/head&amp;gt;
    &amp;lt;body&amp;gt;
        &amp;lt;h1&amp;gt;WebForms Core Technology in Julia&amp;lt;/h1&amp;gt;
        &amp;lt;button id="&lt;/span&gt;&lt;span class="n"&gt;Button1&lt;/span&gt;&lt;span class="s"&gt;"&amp;gt;Increase Textbox&amp;lt;/button&amp;gt;
        &amp;lt;input type="&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="s"&gt;" id="&lt;/span&gt;&lt;span class="n"&gt;Textbox1&lt;/span&gt;&lt;span class="s"&gt;" value="&lt;/span&gt;&lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="s"&gt;"&amp;gt;
    &amp;lt;/body&amp;gt;
    &amp;lt;/html&amp;gt;
    """&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The page contains an ordinary HTML button and input.&lt;/p&gt;

&lt;p&gt;Now Julia can associate an event with that button:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight julia"&gt;&lt;code&gt;&lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;WebForms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Form&lt;/span&gt;&lt;span class="x"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;WebForms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_comment_event&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"Button1"&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;HtmlEvent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OnClick&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"incease"&lt;/span&gt;
&lt;span class="x"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The server can then define what should happen when the event occurs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight julia"&gt;&lt;code&gt;&lt;span class="n"&gt;WebForms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;start_index&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"incease"&lt;/span&gt;&lt;span class="x"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;WebForms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;increase_width&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"Textbox1"&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Fetch&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_value&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Textbox1"&lt;/span&gt;&lt;span class="x"&gt;)&lt;/span&gt;
&lt;span class="x"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The resulting WebForms instructions can be exported into HTML comments:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight julia"&gt;&lt;code&gt;&lt;span class="n"&gt;WebForms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;export_to_html_comment&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="x"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The final response is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight julia"&gt;&lt;code&gt;&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;
    &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt;
    &lt;span class="x"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"Content-Type"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"text/html; charset=utf-8"&lt;/span&gt;&lt;span class="x"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;html_form&lt;/span&gt;&lt;span class="x"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
    &lt;span class="n"&gt;WebForms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;export_to_html_comment&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="x"&gt;)&lt;/span&gt;
&lt;span class="x"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;WebFormsJS detects the WebForms instructions and executes them in the browser.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fetching Browser Values
&lt;/h2&gt;

&lt;p&gt;An important feature of this model is that commands can use values from the browser.&lt;/p&gt;

&lt;p&gt;In the example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight julia"&gt;&lt;code&gt;&lt;span class="n"&gt;Fetch&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_value&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Textbox1"&lt;/span&gt;&lt;span class="x"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;represents the current value of the element.&lt;/p&gt;

&lt;p&gt;That value can be used by another WebForms operation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight julia"&gt;&lt;code&gt;&lt;span class="n"&gt;WebForms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;increase_width&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"Textbox1"&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Fetch&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_value&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Textbox1"&lt;/span&gt;&lt;span class="x"&gt;)&lt;/span&gt;
&lt;span class="x"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This allows a sequence of server-defined UI operations to depend on browser state without requiring the Julia application to maintain a permanent mirror of the DOM.&lt;/p&gt;

&lt;h2&gt;
  
  
  HTML Remains HTML
&lt;/h2&gt;

&lt;p&gt;One of the design goals of WebForms Core is to keep the HTML itself simple.&lt;/p&gt;

&lt;p&gt;The page can remain:&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;button&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"Button1"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Incease Textbox&lt;span class="nt"&gt;&amp;lt;/button&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;"number"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"Textbox1"&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"40"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is no requirement to replace HTML with a component syntax.&lt;/p&gt;

&lt;p&gt;The WebForms instructions can instead be transmitted separately or embedded as HTML comments.&lt;/p&gt;

&lt;p&gt;This makes WebForms Core HTML-native.&lt;/p&gt;

&lt;h2&gt;
  
  
  Julia as the Server-Side UI Commander
&lt;/h2&gt;

&lt;p&gt;The Julia application remains responsible for the server-side logic.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight julia"&gt;&lt;code&gt;&lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="nf"&gt; handle_request&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="x"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"/"&lt;/span&gt;
            &lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;WebForms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Form&lt;/span&gt;&lt;span class="x"&gt;()&lt;/span&gt;

            &lt;span class="n"&gt;WebForms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_comment_event&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;
                &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt;
                &lt;span class="s"&gt;"Button1"&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;HtmlEvent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OnClick&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt;
                &lt;span class="s"&gt;"incease"&lt;/span&gt;
            &lt;span class="x"&gt;)&lt;/span&gt;

            &lt;span class="n"&gt;WebForms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;start_index&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"incease"&lt;/span&gt;&lt;span class="x"&gt;)&lt;/span&gt;

            &lt;span class="n"&gt;WebForms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;increase_width&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;
                &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt;
                &lt;span class="s"&gt;"Textbox1"&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;Fetch&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_value&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Textbox1"&lt;/span&gt;&lt;span class="x"&gt;)&lt;/span&gt;
            &lt;span class="x"&gt;)&lt;/span&gt;

            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;
                &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt;
                &lt;span class="x"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"Content-Type"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"text/html; charset=utf-8"&lt;/span&gt;&lt;span class="x"&gt;],&lt;/span&gt;
                &lt;span class="n"&gt;html_form&lt;/span&gt;&lt;span class="x"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
                &lt;span class="n"&gt;WebForms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;export_to_html_comment&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="x"&gt;)&lt;/span&gt;
            &lt;span class="x"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;
            &lt;span class="mi"&gt;404&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt;
            &lt;span class="x"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"Content-Type"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"text/plain"&lt;/span&gt;&lt;span class="x"&gt;],&lt;/span&gt;
            &lt;span class="s"&gt;"Not Found"&lt;/span&gt;
        &lt;span class="x"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;
        &lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;========== ERROR =========="&lt;/span&gt;&lt;span class="x"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;showerror&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;stdout&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt; &lt;span class="n"&gt;catch_backtrace&lt;/span&gt;&lt;span class="x"&gt;())&lt;/span&gt;
        &lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;============================"&lt;/span&gt;&lt;span class="x"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"REQUEST: "&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="x"&gt;)&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;
            &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"Internal Server Error"&lt;/span&gt;
        &lt;span class="x"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the application can be started directly with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight julia"&gt;&lt;code&gt;&lt;span class="n"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;serve&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;handle_request&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"127.0.0.1"&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt;
    &lt;span class="mi"&gt;8080&lt;/span&gt;
&lt;span class="x"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is no separate frontend application required for this example.&lt;/p&gt;

&lt;h2&gt;
  
  
  WebForms Core and WebFormsJS
&lt;/h2&gt;

&lt;p&gt;The Julia library is the server-side part of the technology.&lt;/p&gt;

&lt;p&gt;The browser-side execution is performed by &lt;code&gt;web-forms.js&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;A Julia application can simply serve the JavaScript file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight julia"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"/script/web-forms.js"&lt;/span&gt;
    &lt;span class="n"&gt;js&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;joinpath&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@__DIR__&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"script"&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"web-forms.js"&lt;/span&gt;&lt;span class="x"&gt;),&lt;/span&gt;
        &lt;span class="kt"&gt;String&lt;/span&gt;
    &lt;span class="x"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;
        &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt;
        &lt;span class="x"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"Content-Type"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"text/javascript"&lt;/span&gt;&lt;span class="x"&gt;],&lt;/span&gt;
        &lt;span class="n"&gt;js&lt;/span&gt;
    &lt;span class="x"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This separation is intentional.&lt;/p&gt;

&lt;p&gt;The server-side WebForms implementation can be written in Julia, while the same WebFormsJS Executor can execute commands generated by WebForms implementations in different programming languages.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Cross-Language Architecture
&lt;/h2&gt;

&lt;p&gt;This makes WebForms Core different from a framework that couples a particular frontend runtime to a particular backend language.&lt;/p&gt;

&lt;p&gt;The architecture is based on a protocol and an Executor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Julia
C#
PHP
Python
R
Ruby
Go
JavaScript
Rust
Java
Elixir
Perl
Dart
C
C++
...
 │
 ▼
WebForms
 │
 ▼
WebForms Commands
 │
 ▼
WebFormsJS
 │
 ▼
HTML DOM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The server-side implementation can therefore be native to the programming language.&lt;/p&gt;

&lt;p&gt;The browser does not need to know which programming language generated the commands.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Julia?
&lt;/h2&gt;

&lt;p&gt;Julia already provides a powerful ecosystem for scientific and technical computing.&lt;/p&gt;

&lt;p&gt;With WebForms Core, the same language can also participate in server-side interactive web applications while retaining its existing HTTP ecosystem.&lt;/p&gt;

&lt;p&gt;A Julia application can therefore combine:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Julia application logic&lt;/li&gt;
&lt;li&gt;&lt;code&gt;HTTP.jl&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;WebForms Core&lt;/li&gt;
&lt;li&gt;WebFormsJS&lt;/li&gt;
&lt;li&gt;standard HTML&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;without requiring a separate JavaScript application to implement every interactive operation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stateless Server-Orchestrated UI
&lt;/h2&gt;

&lt;p&gt;WebForms Core is designed around server-side commands rather than maintaining a server-side copy of the browser DOM.&lt;/p&gt;

&lt;p&gt;The server receives a request, executes its logic, and generates commands.&lt;/p&gt;

&lt;p&gt;The browser executes those commands.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HTTP Request
     │
     ▼
Julia Server
     │
     ▼
WebForms Commands
     │
     ▼
HTTP Response
     │
     ▼
WebFormsJS
     │
     ▼
Browser DOM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The server does not need to maintain a persistent component tree representing the browser.&lt;/p&gt;

&lt;p&gt;This makes the approach suitable for applications that prefer stateless HTTP request processing.&lt;/p&gt;

&lt;h2&gt;
  
  
  WebForms Core in Julia
&lt;/h2&gt;

&lt;p&gt;The Julia implementation demonstrates that WebForms Core is not tied to a single programming language.&lt;/p&gt;

&lt;p&gt;A Julia developer can write:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight julia"&gt;&lt;code&gt;&lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;WebForms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Form&lt;/span&gt;&lt;span class="x"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;WebForms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_font_size&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;InputPlace&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"form"&lt;/span&gt;&lt;span class="x"&gt;),&lt;/span&gt;
    &lt;span class="mi"&gt;20&lt;/span&gt;
&lt;span class="x"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;WebForms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_background_color&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;InputPlace&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"form"&lt;/span&gt;&lt;span class="x"&gt;),&lt;/span&gt;
    &lt;span class="s"&gt;"lightblue"&lt;/span&gt;
&lt;span class="x"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;WebForms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_text&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;InputPlace&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"h3"&lt;/span&gt;&lt;span class="x"&gt;),&lt;/span&gt;
    &lt;span class="s"&gt;"Welcome Julia!"&lt;/span&gt;
&lt;span class="x"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and let WebFormsJS translate those server-generated commands into browser-side DOM operations.&lt;/p&gt;

&lt;p&gt;That is the fundamental idea of &lt;strong&gt;Server-Orchestrated UI&lt;/strong&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The server decides what should happen. The client executes it.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;With WebForms Core, Julia can participate in that architecture while keeping the application logic on the server and the browser interface based on ordinary HTML and WebFormsJS.&lt;/p&gt;

&lt;h2&gt;
  
  
  Related links
&lt;/h2&gt;

&lt;p&gt;In Elanat:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://elanat.net/webforms-core" rel="noopener noreferrer"&gt;WebForms Core Page&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://elanat.net/webforms-js" rel="noopener noreferrer"&gt;WebFormsJS Page&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;in GitHub:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/webforms-core" rel="noopener noreferrer"&gt;WebForms Core Organizations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/webforms-core/Web_forms" rel="noopener noreferrer"&gt;WebFormsJS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/webforms-core/Web_forms_classes" rel="noopener noreferrer"&gt;WebForms Classes&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>julia</category>
      <category>opensource</category>
      <category>webdev</category>
      <category>webformscore</category>
    </item>
    <item>
      <title>I Built a Web Page with C! Here’s How WebForms Core Makes It Possible</title>
      <dc:creator>Elanat Framework</dc:creator>
      <pubDate>Mon, 21 Sep 2026 17:26:54 +0000</pubDate>
      <link>https://dev.to/elanatframework/i-built-a-web-page-with-c-heres-how-webforms-core-makes-it-possible-1b5n</link>
      <guid>https://dev.to/elanatframework/i-built-a-web-page-with-c-heres-how-webforms-core-makes-it-possible-1b5n</guid>
      <description>&lt;p&gt;C is one of the most influential programming languages in software development. It is widely used for operating systems, embedded systems, networking, infrastructure, and performance-critical software.&lt;/p&gt;

&lt;p&gt;But can C also be used to build an interactive web application where the server controls the HTML interface?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Yes. And the server can control the HTML interface without requiring a separate frontend application.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://elanat.net/webforms-core" rel="noopener noreferrer"&gt;WebForms Core (WFC)&lt;/a&gt; is a server-side UI manipulation technology developed by Elanat. It allows a server application to generate commands that manipulate the HTML DOM in the browser.&lt;/p&gt;

&lt;p&gt;The basic architecture is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;C Server
    ↓
WebForms header
    ↓
Commands
    ↓
WebFormsJS
    ↓
HTML DOM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This article shows how to build a web application in C using &lt;strong&gt;Mongoose&lt;/strong&gt; as the HTTP server and &lt;strong&gt;WebForms Core&lt;/strong&gt; for server-side UI manipulation.&lt;/p&gt;




&lt;h1&gt;
  
  
  WebForms Core in C
&lt;/h1&gt;

&lt;p&gt;The C implementation is provided as a single header file, &lt;code&gt;WebForms.h&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This makes integration straightforward. The application does not need a specific C package manager for WebForms Core.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnl245ep6m295rtcpykrb.jpg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnl245ep6m295rtcpykrb.jpg" alt="Web Programming With C" width="799" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For the HTTP server, this example uses &lt;strong&gt;Mongoose&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;"mongoose.h"&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;"WebForms.h"&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Mongoose handles HTTP requests and responses, while WebForms Core generates commands for manipulating the browser interface.&lt;/p&gt;

&lt;p&gt;The resulting stack is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;C Application
    │
    ├── Mongoose
    │      └── HTTP Server
    │
    └── WebForms Core
           └── UI Commands
                  ↓
              WebFormsJS
                  ↓
              HTML DOM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Download the &lt;code&gt;mongoose.h&lt;/code&gt; and &lt;code&gt;mongoose.c&lt;/code&gt; files directly from the link below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/cesanta/mongoose" rel="noopener noreferrer"&gt;https://github.com/cesanta/mongoose&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The C WebForms header is available in the WebForms Core GitHub repository:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/webforms-core/Web_forms_classes/tree/elanat_framework/c" rel="noopener noreferrer"&gt;https://github.com/webforms-core/Web_forms_classes/tree/elanat_framework/c&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can get &lt;code&gt;WebForms.h&lt;/code&gt; directly from the &lt;code&gt;c&lt;/code&gt; directory and place it in your C project.&lt;/p&gt;

&lt;p&gt;This makes the WebForms Core C implementation easy to integrate into projects using different build systems or development environments.&lt;/p&gt;




&lt;h1&gt;
  
  
  Building the Web Page in C
&lt;/h1&gt;

&lt;p&gt;The HTML page can simply be stored as a C string:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;view_html&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
&lt;span class="s"&gt;"&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;
&lt;span class="s"&gt;"&amp;lt;html&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;
&lt;span class="s"&gt;"&amp;lt;head&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;
&lt;span class="s"&gt;"  &amp;lt;title&amp;gt;Using WebForms Core&amp;lt;/title&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;
&lt;span class="s"&gt;"  &amp;lt;script type=&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt;module&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt; src=&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt;/script/web-forms.js&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;
&lt;span class="s"&gt;"&amp;lt;/head&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;
&lt;span class="s"&gt;"&amp;lt;body&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;
&lt;span class="s"&gt;"    &amp;lt;form method=&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt;post&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt; action=&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt;&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;
&lt;span class="s"&gt;"        &amp;lt;label for=&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt;txt_Name&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt;&amp;gt;Your Name&amp;lt;/label&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;
&lt;span class="s"&gt;"        &amp;lt;input name=&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt;txt_Name&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt; id=&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt;txt_Name&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt; type=&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt; /&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;
&lt;span class="s"&gt;"        &amp;lt;br&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;
&lt;span class="s"&gt;"        &amp;lt;label for=&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt;txt_FontSize&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt;&amp;gt;Set Font Size&amp;lt;/label&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;
&lt;span class="s"&gt;"        &amp;lt;input name=&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt;txt_FontSize&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt; id=&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt;txt_FontSize&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt; type=&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt;number&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt; /&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;
&lt;span class="s"&gt;"        &amp;lt;br&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;
&lt;span class="s"&gt;"        &amp;lt;label for=&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt;txt_BackgroundColor&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt;&amp;gt;Set Background Color&amp;lt;/label&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;
&lt;span class="s"&gt;"        &amp;lt;input name=&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt;txt_BackgroundColor&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt; id=&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt;txt_BackgroundColor&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt; type=&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt; /&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;
&lt;span class="s"&gt;"        &amp;lt;br&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;
&lt;span class="s"&gt;"        &amp;lt;input name=&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt;btn_SetBodyValue&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt; type=&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt;submit&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt; value=&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt;Click to send data&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt; /&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;
&lt;span class="s"&gt;"    &amp;lt;/form&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;
&lt;span class="s"&gt;"&amp;lt;/body&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;
&lt;span class="s"&gt;"&amp;lt;/html&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;There is no JSX, no frontend component framework, and no separate frontend application.&lt;/p&gt;

&lt;p&gt;The page is standard HTML.&lt;/p&gt;




&lt;h1&gt;
  
  
  Controlling the HTML from C
&lt;/h1&gt;

&lt;p&gt;When the form is submitted, Mongoose provides the POST data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;fontSize_str&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;background_color&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;128&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;128&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="n"&gt;mg_http_get_var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;hm&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"txt_FontSize"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;fontSize_str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fontSize_str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;mg_http_get_var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;hm&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"txt_BackgroundColor"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;background_color&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;background_color&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;mg_http_get_var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;hm&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"txt_Name"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&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;A WebForms instance can then be created:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="n"&gt;WebForms&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;webforms_create&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The server creates InputPlace selectors:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ipForm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;webforms_ip_tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"form"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ipH3&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;webforms_ip_tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"h3"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ipBtn&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;webforms_ip_tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"btn_SetBodyValue"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And generates UI commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="n"&gt;webforms_set_font_size&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ipForm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fontSize&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;webforms_set_background_color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;ipForm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;background_color&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;webforms_set_disabled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;ipBtn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nb"&gt;true&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;webforms_add_tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;ipForm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"h3"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;""&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;webforms_set_text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;ipH3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;welcome&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The C server is therefore not simply returning data. It is generating &lt;strong&gt;instructions for the browser&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Screenshot of page load&lt;/strong&gt;&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fum3qjqf0q5etj0be0b6h.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fum3qjqf0q5etj0be0b6h.png" alt="WebForms Core HTML Load" width="425" height="192"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Screenshot after send data&lt;/strong&gt;&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3ddg74e97dtgpysyg1jw.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3ddg74e97dtgpysyg1jw.png" alt="WebForms Core Change HTML" width="425" height="192"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  Low-Overhead Server Commands
&lt;/h1&gt;

&lt;p&gt;One of the interesting ideas behind WFC is that the server sends &lt;strong&gt;commands&lt;/strong&gt;, rather than continuously sending a representation of the entire UI.&lt;/p&gt;

&lt;p&gt;The commands are compact and can be embedded inside HTML comments:&lt;/p&gt;

&lt;p&gt;Commands with 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;b&amp;gt;&lt;/span&gt; ... &lt;span class="nt"&gt;&amp;lt;/b&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;/div&amp;gt;&lt;/span&gt;
...
&lt;span class="c"&gt;&amp;lt;!--[web-forms]
st&amp;lt;h1&amp;gt;=WebForms Core in C!
bc&amp;lt;body&amp;gt;=lightblue--&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This has two useful properties.&lt;/p&gt;

&lt;p&gt;First, the commands do not interfere with the visible HTML structure.&lt;/p&gt;

&lt;p&gt;Second, the command representation has relatively low overhead because only the required UI operations need to be transmitted.&lt;/p&gt;

&lt;p&gt;Commands without html&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="nn"&gt;[web-forms]&lt;/span&gt;
&lt;span class="err"&gt;fs&amp;lt;form&amp;gt;=26px&lt;/span&gt;
&lt;span class="err"&gt;bc&amp;lt;form&amp;gt;=cadetblue&lt;/span&gt;
&lt;span class="err"&gt;sd&amp;lt;btn_SetBodyValue&amp;gt;=1&lt;/span&gt;
&lt;span class="err"&gt;nt&amp;lt;form&amp;gt;=h3&lt;/span&gt;
&lt;span class="err"&gt;st&amp;lt;h3&amp;gt;=Welcome&lt;/span&gt; &lt;span class="err"&gt;Adriano!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;WebFormsJS detects the commands and executes them against the DOM.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Server
   ↓
Compact Commands
   ↓
WebFormsJS
   ↓
DOM Operations
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  A Different Approach to Stateless Server-Driven UI
&lt;/h1&gt;

&lt;p&gt;Before WebForms Core, different systems and approaches attempted to combine server-side UI control with a &lt;strong&gt;stateless server&lt;/strong&gt; and command-based communication.&lt;/p&gt;

&lt;p&gt;This model has an obvious challenge:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How can multiple asynchronous interactions remain synchronized without requiring the server to maintain the complete client state?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;WFC takes a different approach.&lt;/p&gt;

&lt;p&gt;Several mechanisms work together to control the execution flow.&lt;/p&gt;

&lt;h3&gt;
  
  
  Queue Manager
&lt;/h3&gt;

&lt;p&gt;Requests can be placed into a queue and processed serially.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Request 1
   ↓
Request 2
   ↓
Request 3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This helps preserve the order of UI operations.&lt;/p&gt;

&lt;h3&gt;
  
  
  Loader
&lt;/h3&gt;

&lt;p&gt;When an operation depends on a server response, a Loader can temporarily lock the relevant interface before the result arrives.&lt;/p&gt;

&lt;p&gt;This prevents the user from triggering conflicting interactions while the required server operation is still pending.&lt;/p&gt;

&lt;h3&gt;
  
  
  Serial Request Processing
&lt;/h3&gt;

&lt;p&gt;Queued requests are processed in order, helping dependent UI operations execute in a predictable sequence.&lt;/p&gt;

&lt;h3&gt;
  
  
  DebounceDelay
&lt;/h3&gt;

&lt;p&gt;For events that can fire repeatedly, &lt;code&gt;DebounceDelay&lt;/code&gt; can prevent unnecessary requests from being generated too rapidly.&lt;/p&gt;

&lt;p&gt;Together, these mechanisms address an important problem in interactive Server-Driven UI systems: &lt;strong&gt;synchronization between user actions, server responses, and client-side command execution.&lt;/strong&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  Stateless by Design
&lt;/h1&gt;

&lt;p&gt;WFC is, by itself, a &lt;strong&gt;stateless server-side UI architecture&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The server does not need to maintain a complete representation of the browser DOM.&lt;/p&gt;

&lt;p&gt;A typical flow can therefore remain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HTTP Request
     ↓
C Server
     ↓
WebForms Commands
     ↓
HTTP Response
     ↓
Browser
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, Stateless does not mean that server-side state is forbidden.&lt;/p&gt;

&lt;p&gt;An application can still maintain state on the server when a particular page or scenario requires it.&lt;/p&gt;

&lt;p&gt;The choice depends on the application's requirements.&lt;/p&gt;




&lt;h1&gt;
  
  
  Memory Management in C
&lt;/h1&gt;

&lt;p&gt;Because this implementation is written in C, memory management is explicit.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="n"&gt;WebForms&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;webforms_create&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;creates a WebForms instance, while:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="n"&gt;webforms_clean&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;webforms_free&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;cleans and releases it.&lt;/p&gt;

&lt;p&gt;InputPlace values returned by:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="n"&gt;webforms_ip_tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"form"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;are heap-allocated strings and therefore must also be released:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="n"&gt;free&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ipForm&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;free&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ipH3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;free&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ipBtn&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The response returned by:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;webforms_response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;is also heap-allocated and must be released after sending it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="n"&gt;free&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This keeps the API compatible with the explicit memory-management model expected in C.&lt;/p&gt;




&lt;h1&gt;
  
  
  Running the C Web Server
&lt;/h1&gt;

&lt;p&gt;Mongoose can listen for HTTP connections with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="n"&gt;mg_http_listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;mgr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"http://127.0.0.1:8080"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nb"&gt;NULL&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The event loop is then kept alive with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(;;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;mg_mgr_poll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;mgr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1000&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 application can be opened at:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://127.0.0.1:8080/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;WebFormsJS can also be served directly by Mongoose.&lt;/p&gt;




&lt;h1&gt;
  
  
  C as a Web Programming Language
&lt;/h1&gt;

&lt;p&gt;The complete stack is surprisingly small:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;C
+
Mongoose
+
WebForms Core
+
WebFormsJS
+
HTML
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is no requirement for React, JSX, a frontend build system, or a separate frontend application.&lt;/p&gt;

&lt;p&gt;The C application handles the server logic.&lt;/p&gt;

&lt;p&gt;WebForms Core generates UI commands.&lt;/p&gt;

&lt;p&gt;WebFormsJS executes those commands.&lt;/p&gt;

&lt;p&gt;The browser remains the final place where the HTML DOM is manipulated.&lt;/p&gt;




&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Building an interactive web application in C does not require turning C into a frontend language.&lt;/p&gt;

&lt;p&gt;Instead, C can remain the server-side language while WebForms Core provides a command-based mechanism for controlling the browser UI.&lt;/p&gt;

&lt;p&gt;The architecture is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;C Server
    ↓
WebForms
    ↓
Commands
    ↓
WebFormsJS
    ↓
HTML DOM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;WFC combines this architecture with compact commands, HTML-comment command embedding, queue management, serial request processing, Loader controls, and event debouncing.&lt;/p&gt;

&lt;p&gt;The result is a &lt;strong&gt;server-oriented, stateless-by-design approach to interactive web UI&lt;/strong&gt;, while still allowing applications to keep server-side state when a specific scenario requires it.&lt;/p&gt;

&lt;p&gt;And yes, this entire example starts with a language that was originally designed decades ago for systems programming:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;C.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Related links
&lt;/h2&gt;

&lt;p&gt;In Elanat:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://elanat.net/webforms-core" rel="noopener noreferrer"&gt;WebForms Core Page&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://elanat.net/webforms-js" rel="noopener noreferrer"&gt;WebFormsJS Page&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;in GitHub:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/webforms-core" rel="noopener noreferrer"&gt;WebForms Core Organizations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/webforms-core/Web_forms" rel="noopener noreferrer"&gt;WebFormsJS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/webforms-core/Web_forms_classes" rel="noopener noreferrer"&gt;WebForms Classes&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>c</category>
      <category>mongoose</category>
      <category>webdev</category>
      <category>webformscore</category>
    </item>
    <item>
      <title>Web Programming in C++ with WFC</title>
      <dc:creator>Elanat Framework</dc:creator>
      <pubDate>Sun, 20 Sep 2026 18:37:20 +0000</pubDate>
      <link>https://dev.to/elanatframework/web-programming-in-c-with-wfc-5bm1</link>
      <guid>https://dev.to/elanatframework/web-programming-in-c-with-wfc-5bm1</guid>
      <description>&lt;p&gt;C++ is one of the most powerful and widely used programming languages in the world. It is well known for high-performance software, system programming, networking, game engines, embedded systems, and infrastructure.&lt;/p&gt;

&lt;p&gt;But can C++ also be used to build modern web applications with server-side control over the HTML user interface?&lt;/p&gt;

&lt;p&gt;Yes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;WebForms Core (WFC)&lt;/strong&gt; is a server-side UI manipulation technology created by Elanat. It allows a server application to generate commands that manipulate the HTML interface in the browser.&lt;/p&gt;

&lt;p&gt;Instead of creating a completely separate frontend application, the server can define UI operations and behaviors, while &lt;strong&gt;WebFormsJS&lt;/strong&gt; executes those commands in the browser.&lt;/p&gt;

&lt;p&gt;The basic architecture is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;C++ Server
    ↓
WebForms Class
    ↓
Action Controls
    ↓
WebFormsJS
    ↓
HTML DOM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This article demonstrates how to use WebForms Core with C++ to build web applications, including a form-based application and an interactive video player.&lt;/p&gt;




&lt;h1&gt;
  
  
  WebForms Core in C++
&lt;/h1&gt;

&lt;p&gt;For C and C++, there are several package management ecosystems and dependency management approaches. Because of the diversity of these systems, the WebForms Core C++ implementation is provided directly as a header file rather than requiring a specific C++ package manager.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Faotny3knn5j8qc52s0zv.jpg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Faotny3knn5j8qc52s0zv.jpg" alt="WFC in C++" width="799" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The C++ WebForms class is available in the WebForms Core GitHub repository:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/webforms-core/Web_forms_classes/tree/elanat_framework/cpp" rel="noopener noreferrer"&gt;https://github.com/webforms-core/Web_forms_classes/tree/elanat_framework/cpp&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The file required by the application is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;WebForms.h
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can get &lt;code&gt;WebForms.h&lt;/code&gt; directly from the &lt;code&gt;cpp&lt;/code&gt; directory and place it in your C++ project.&lt;/p&gt;

&lt;p&gt;This makes the WebForms Core C++ implementation easy to integrate into projects using different build systems or development environments.&lt;/p&gt;

&lt;p&gt;There is no requirement to use a particular C++ package manager for WebForms Core itself.&lt;/p&gt;




&lt;h1&gt;
  
  
  Using cpp-httplib
&lt;/h1&gt;

&lt;p&gt;For the HTTP server in the examples, we use &lt;strong&gt;cpp-httplib&lt;/strong&gt;, a C++ HTTP server/client library.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;httplib.h&lt;/code&gt; file used in these examples is obtained directly from the official GitHub repository:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/yhirose/cpp-httplib" rel="noopener noreferrer"&gt;https://github.com/yhirose/cpp-httplib&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Just like &lt;code&gt;WebForms.h&lt;/code&gt;, the header can be placed directly into the C++ project.&lt;/p&gt;

&lt;p&gt;A simplified project structure can therefore look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;C++ Web Project/
├── main.cpp
├── WebForms.h
├── httplib.h
├── api/
│   ├── video.json
│   └── template.html
└── script/
    └── web-forms.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The two headers have different responsibilities:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;"httplib.h"&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;"WebForms.h"&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;cpp-httplib&lt;/strong&gt; is used to create the HTTP server and handle HTTP requests and responses.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;WebForms Core&lt;/strong&gt; is used to create server-side UI commands.&lt;/p&gt;

&lt;p&gt;The architecture is therefore:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;C++ Application
       │
       ├── cpp-httplib
       │       │
       │       └── HTTP Server
       │
       └── WebForms Core
               │
               └── UI Commands
                       │
                       ▼
                   WebFormsJS
                       │
                       ▼
                    HTML DOM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This combination is not a dependency relationship between the two libraries. They simply work together in the application: &lt;code&gt;cpp-httplib&lt;/code&gt; handles HTTP, while WebForms Core handles server-side UI manipulation.&lt;/p&gt;




&lt;h1&gt;
  
  
  Building a Web Server with C++
&lt;/h1&gt;

&lt;p&gt;Let's start with a simple web application.&lt;/p&gt;

&lt;p&gt;We include the standard C++ libraries together with &lt;code&gt;httplib.h&lt;/code&gt; and &lt;code&gt;WebForms.h&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;string&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;"httplib.h"&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;"WebForms.h"&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="n"&gt;WebFormsCore&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can then define an HTML view:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;backEndRender&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;viewName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;viewName&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"view"&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="s"&gt;R"(&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
  &amp;lt;title&amp;gt;Using WebForms Core&amp;lt;/title&amp;gt;
  &amp;lt;script type="module" src="/script/web-forms.js"&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;form method="post" action="/"&amp;gt;

        &amp;lt;label for="txt_Name"&amp;gt;Your Name&amp;lt;/label&amp;gt;
        &amp;lt;input name="txt_Name" id="txt_Name" type="text" /&amp;gt;
        &amp;lt;br&amp;gt;

        &amp;lt;label for="txt_FontSize"&amp;gt;Set Font Size&amp;lt;/label&amp;gt;
        &amp;lt;input name="txt_FontSize"
               id="txt_FontSize"
               type="number"
               value="16"
               min="10"
               max="36" /&amp;gt;
        &amp;lt;br&amp;gt;

        &amp;lt;label for="txt_BackgroundColor"&amp;gt;
            Set Background Color
        &amp;lt;/label&amp;gt;

        &amp;lt;input name="txt_BackgroundColor"
               id="txt_BackgroundColor"
               type="text" /&amp;gt;
        &amp;lt;br&amp;gt;

        &amp;lt;input name="btn_SetBodyValue"
               type="submit"
               value="Click to send data" /&amp;gt;

    &amp;lt;/form&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;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"&amp;lt;h1&amp;gt;View not found&amp;lt;/h1&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The HTML is standard HTML. There is no JSX, no frontend component framework, and no special frontend build system required.&lt;/p&gt;




&lt;h1&gt;
  
  
  Manipulating the UI from C++
&lt;/h1&gt;

&lt;p&gt;Now the C++ server can handle the POST request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;svr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&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;const&lt;/span&gt; &lt;span class="n"&gt;httplib&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="n"&gt;httplib&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;has_param&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"btn_SetBodyValue"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;fontSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
            &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;stoi&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_param_value&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"txt_FontSize"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

        &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;backgroundColor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
            &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_param_value&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"txt_BackgroundColor"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
            &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_param_value&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"txt_Name"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;WebForms&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetFontSize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;InputPlace&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"form"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="n"&gt;fontSize&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetBackgroundColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;InputPlace&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"form"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="n"&gt;backgroundColor&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetDisabled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;InputPlace&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"btn_SetBodyValue"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="nb"&gt;true&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddTag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;InputPlace&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"form"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="s"&gt;"h3"&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;InputPlace&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"h3"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="s"&gt;"Welcome "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"!"&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_content&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
            &lt;span class="s"&gt;"text/plain"&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_content&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;backEndRender&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"view"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="s"&gt;"text/html"&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 important point is that the C++ application is not simply returning data.&lt;/p&gt;

&lt;p&gt;It is creating UI commands.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetFontSize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;InputPlace&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"form"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;fontSize&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;creates a command that changes the font size of the target element.&lt;/p&gt;

&lt;p&gt;Likewise:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetBackgroundColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;InputPlace&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"form"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;backgroundColor&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;changes the background color.&lt;/p&gt;

&lt;p&gt;And:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetDisabled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;InputPlace&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"btn_SetBodyValue"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nb"&gt;true&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;disables the submit button.&lt;/p&gt;

&lt;p&gt;The server can also create new HTML elements:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddTag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;InputPlace&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"form"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="s"&gt;"h3"&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;InputPlace&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"h3"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="s"&gt;"Welcome "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&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 resulting commands are sent to the browser, where WebFormsJS executes them against the DOM.&lt;/p&gt;




&lt;h1&gt;
  
  
  Starting the C++ Server
&lt;/h1&gt;

&lt;p&gt;The GET request returns the initial HTML page:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;svr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&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;const&lt;/span&gt; &lt;span class="n"&gt;httplib&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;httplib&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_content&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;backEndRender&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"view"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="s"&gt;"text/html"&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 WebFormsJS file can be served using &lt;code&gt;cpp-httplib&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;svr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_mount_point&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/script"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"./script"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, the server listens on port &lt;code&gt;8080&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;svr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"127.0.0.1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8080&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The application can then be accessed at:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://127.0.0.1:8080/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Building a Video Player with C++
&lt;/h1&gt;

&lt;p&gt;WebForms Core is not limited to forms and simple DOM modifications.&lt;/p&gt;

&lt;p&gt;It can also be used to build more interactive interfaces.&lt;/p&gt;

&lt;p&gt;The second example is a video player that loads a list of videos from a JSON file and creates the video cards dynamically.&lt;/p&gt;

&lt;p&gt;The JSON file contains:&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Big Buck Bunny"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"path"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://test-videos.co.uk/vids/bigbuckbunny/mp4/h264/720/Big_Buck_Bunny_720_10s_1MB.mp4"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Sintel"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"path"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://test-videos.co.uk/vids/sintel/mp4/h264/720/Sintel_720_10s_2MB.mp4"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Flower"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"path"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Elephants Dream"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"path"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://archive.org/download/ElephantsDream/ed_1024_512kb.mp4"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The C++ application exposes the JSON file through an HTTP endpoint:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;svr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/api/video.json"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;[](&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;httplib&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="n"&gt;httplib&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;readFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"./api/video.json"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_content&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;"Cannot read api/video.json"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"text/plain"&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;}&lt;/span&gt;

    &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_content&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"application/json"&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 application also exposes the HTML template:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;svr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/api/template.html"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;[](&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;httplib&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="n"&gt;httplib&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;readFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"./api/template.html"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_content&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;"Cannot read api/template.html"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"text/plain"&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;}&lt;/span&gt;

    &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_content&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"text/html"&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;h1&gt;
  
  
  The WebForms Video Interface
&lt;/h1&gt;

&lt;p&gt;We start by creating a WebForms instance:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;WebForms&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The video data is loaded and stored using WebForms Core:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NotExist&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;Fetch&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Cache&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"video-data"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddCacheValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"video-data"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Fetch&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;LoadUrl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/api/video.json"&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;We can then iterate over the JSON data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ForEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"[0]"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Fetch&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Cache&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"video-data"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="s"&gt;"foreach-data"&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inside the loop, the HTML template is loaded and populated:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StartBracket&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="s"&gt;"{video-container}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;Fetch&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;LoadHtml&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;"/api/template.html"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"Video"&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BindJSONToTemplate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="s"&gt;"{video-card}-1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;Fetch&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;FormatStore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"foreach-data"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="s"&gt;"[0]"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"{{value}}"&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetCommentEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="s"&gt;"{video-card}-1|&amp;lt;&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;HtmlEvent&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;OnClick&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"play-video"&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;EndBracket&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The template is:&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="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;template&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"Video"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"video-card"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;b&lt;/span&gt; &lt;span class="na"&gt;data-path=&lt;/span&gt;&lt;span class="s"&gt;"{{path}}"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            {{title}}
        &lt;span class="nt"&gt;&amp;lt;/b&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;/template&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The JSON data is therefore transformed into a collection of video cards.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Screenshot of Video Player&lt;/strong&gt;&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7ivauou40g15iu9sm1a6.jpg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7ivauou40g15iu9sm1a6.jpg" alt="WebForms Core in C++" width="800" height="650"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  Playing the Selected Video
&lt;/h1&gt;

&lt;p&gt;When the user clicks a video card, the &lt;code&gt;play-video&lt;/code&gt; action is executed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StartIndex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"play-video"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"video"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;HtmlEvent&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;OnLoadStart&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"this.play()"&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"video"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"src"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Fetch&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;GetAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"$"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"data-path"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"video-name"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Fetch&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;GetText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&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 selected video's &lt;code&gt;data-path&lt;/code&gt; is used as the source of the HTML &lt;code&gt;&amp;lt;video&amp;gt;&lt;/code&gt; element:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"video"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"src"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Fetch&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;GetAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"$"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"data-path"&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 selected video's title is also displayed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"video-name"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Fetch&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;GetText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"$"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is an important characteristic of WebForms Core.&lt;/p&gt;

&lt;p&gt;The server can define not only the data that should be displayed, but also the UI operations that should take place when the user interacts with the page.&lt;/p&gt;




&lt;h1&gt;
  
  
  The HTML Interface
&lt;/h1&gt;

&lt;p&gt;The frontend remains standard 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;main&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Web Project in C++&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;
        Building a Video Player with WebForms Core
    &lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"video-container"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;video&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"video"&lt;/span&gt;
           &lt;span class="na"&gt;controls&lt;/span&gt;
           &lt;span class="na"&gt;playsinline&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/video&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"now-playing"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"playing-indicator"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;●&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"video-icon"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;🎬&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"video-name"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            No video selected
        &lt;span class="nt"&gt;&amp;lt;/span&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The WebForms commands are exported into HTML comments:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;html&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ExportToHtmlComment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;WebFormsJS detects these commands in the browser and executes them.&lt;/p&gt;

&lt;p&gt;This means the server can send an HTML page together with the operations required to manipulate that page.&lt;/p&gt;




&lt;h1&gt;
  
  
  The Architecture
&lt;/h1&gt;

&lt;p&gt;The complete architecture of the C++ example can be represented as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                    C++ Application
                           │
             ┌─────────────┴─────────────┐
             │                           │
        cpp-httplib                WebForms Core
             │                           │
             │                    WebForms Class
             │                           │
             │                    Action Controls
             │                           │
             └──────────────┬────────────┘
                            │
                            ▼
                       HTTP Response
                            │
                            ▼
                         Browser
                            │
                            ▼
                       WebFormsJS
                            │
                            ▼
                        HTML DOM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;cpp-httplib&lt;/code&gt; provides the HTTP server layer.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;WebForms Core&lt;/code&gt; provides the server-side UI manipulation layer.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;WebFormsJS&lt;/code&gt; acts as the browser-side executor.&lt;/p&gt;

&lt;p&gt;The final target is the HTML DOM.&lt;/p&gt;




&lt;h1&gt;
  
  
  C++ as a Web Programming Language
&lt;/h1&gt;

&lt;p&gt;C++ is not limited to desktop applications, game engines, or system software.&lt;/p&gt;

&lt;p&gt;With an HTTP library such as &lt;code&gt;cpp-httplib&lt;/code&gt;, C++ can be used to create web servers. With WebForms Core, the same C++ application can also orchestrate operations on the browser's HTML interface.&lt;/p&gt;

&lt;p&gt;The resulting stack is simple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;C++
+
cpp-httplib
+
WebForms Core
+
WebFormsJS
+
HTML
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is no requirement to introduce a separate JavaScript frontend framework.&lt;/p&gt;

&lt;p&gt;The application can keep its server-side logic in C++, while the browser receives HTML and WebForms commands.&lt;/p&gt;




&lt;h1&gt;
  
  
  Direct Header-Based Integration
&lt;/h1&gt;

&lt;p&gt;One of the notable aspects of this C++ implementation is its direct integration model.&lt;/p&gt;

&lt;p&gt;For WebForms Core:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;WebForms.h
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;is obtained directly from the WebForms Core C++ source directory.&lt;/p&gt;

&lt;p&gt;For the HTTP server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;httplib.h
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;is obtained directly from the &lt;code&gt;cpp-httplib&lt;/code&gt; GitHub repository.&lt;/p&gt;

&lt;p&gt;This gives the example a straightforward project structure without requiring a specific C++ package manager:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;main.cpp
WebForms.h
httplib.h
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Additional files such as HTML templates, JSON data, and &lt;code&gt;web-forms.js&lt;/code&gt; can then be added according to the requirements of the application.&lt;/p&gt;

&lt;p&gt;This approach can be useful for C++ projects where developers prefer direct header integration or where the project already has its own build and dependency management system.&lt;/p&gt;




&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Web programming in C++ is possible, and WebForms Core provides a way to bring server-side UI manipulation into C++ web applications.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In these examples, &lt;code&gt;cpp-httplib&lt;/code&gt; provides the HTTP server while WebForms Core provides the UI command layer.&lt;/p&gt;

&lt;p&gt;The server can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Serve standard HTML.&lt;/li&gt;
&lt;li&gt;Receive HTTP requests.&lt;/li&gt;
&lt;li&gt;Process form data in C++.&lt;/li&gt;
&lt;li&gt;Generate UI commands.&lt;/li&gt;
&lt;li&gt;Manipulate HTML elements.&lt;/li&gt;
&lt;li&gt;Load JSON data.&lt;/li&gt;
&lt;li&gt;Bind JSON data to HTML templates.&lt;/li&gt;
&lt;li&gt;Respond to user interactions.&lt;/li&gt;
&lt;li&gt;Control an HTML video player.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The resulting architecture keeps the application server-oriented:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;C++ Server
    ↓
WebForms
    ↓
Commands
    ↓
WebFormsJS
    ↓
HTML DOM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;WebForms Core is developed and maintained by &lt;strong&gt;Elanat&lt;/strong&gt;, and the C++ implementation is available directly through the WebForms Core GitHub repository.&lt;/p&gt;

&lt;p&gt;The combination of C++, &lt;code&gt;cpp-httplib&lt;/code&gt;, WebForms Core, WebFormsJS, and standard HTML provides another way to build interactive web applications without requiring a separate frontend framework.&lt;/p&gt;

&lt;h2&gt;
  
  
  Related links
&lt;/h2&gt;

&lt;p&gt;In Elanat:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://elanat.net/webforms-core" rel="noopener noreferrer"&gt;WebForms Core Page&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://elanat.net/webforms-js" rel="noopener noreferrer"&gt;WebFormsJS Page&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;in GitHub:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/webforms-core" rel="noopener noreferrer"&gt;WebForms Core Organizations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/webforms-core/Web_forms" rel="noopener noreferrer"&gt;WebFormsJS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/webforms-core/Web_forms_classes" rel="noopener noreferrer"&gt;WebForms Classes&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>cpp</category>
      <category>httplib</category>
      <category>tutorial</category>
      <category>webformscore</category>
    </item>
    <item>
      <title>New Server-Driven UI in Elixir: Stateless, RESTful, and HTML-Native with WFC</title>
      <dc:creator>Elanat Framework</dc:creator>
      <pubDate>Sat, 19 Sep 2026 17:20:35 +0000</pubDate>
      <link>https://dev.to/elanatframework/new-server-driven-ui-in-elixir-stateless-restful-and-html-native-with-wfc-52k7</link>
      <guid>https://dev.to/elanatframework/new-server-driven-ui-in-elixir-stateless-restful-and-html-native-with-wfc-52k7</guid>
      <description>&lt;p&gt;What if a web application could provide rich, interactive user interfaces while keeping the server &lt;strong&gt;stateless&lt;/strong&gt;, using standard &lt;strong&gt;HTTP&lt;/strong&gt;, working naturally with &lt;strong&gt;RESTful architectures&lt;/strong&gt;, and remaining based on &lt;strong&gt;HTML&lt;/strong&gt;?&lt;/p&gt;

&lt;p&gt;What if the server could define UI behavior without maintaining a server-side representation of the browser DOM?&lt;/p&gt;

&lt;p&gt;This is the approach introduced by &lt;strong&gt;&lt;a href="https://github.com/webforms-core" rel="noopener noreferrer"&gt;WebForms Core (WFC)&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;WebForms Core is a server-side UI manipulation technology developed by &lt;strong&gt;&lt;a href="https://elanat.net" rel="noopener noreferrer"&gt;Elanat&lt;/a&gt;&lt;/strong&gt;. It allows server-side code to generate commands that describe operations on the HTML DOM. These commands are then executed by &lt;strong&gt;WebFormsJS&lt;/strong&gt;, the browser runtime of WFC.&lt;/p&gt;

&lt;p&gt;The basic architecture is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Server
   ↓
WebForms
   ↓
Commands
   ↓
WebFormsJS
   ↓
HTML DOM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With Elixir and Phoenix, this becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Phoenix Controller
        ↓
    WebForms
        ↓
    Commands
        ↓
   WebFormsJS
        ↓
    HTML DOM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff6zz96d3zedqivce3gnl.jpg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff6zz96d3zedqivce3gnl.jpg" alt="WebForms Core in Elixir" width="800" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The important point is that the server does not need to keep a copy of the browser's UI state.&lt;/p&gt;

&lt;p&gt;The browser owns the DOM.&lt;/p&gt;

&lt;p&gt;The server generates commands.&lt;/p&gt;

&lt;p&gt;WebFormsJS executes them.&lt;/p&gt;




&lt;h2&gt;
  
  
  A Stateless Approach to Server-Driven UI
&lt;/h2&gt;

&lt;p&gt;Many interactive web architectures introduce some form of persistent UI state on the server.&lt;/p&gt;

&lt;p&gt;WFC takes a different approach.&lt;/p&gt;

&lt;p&gt;The server can process a request, generate the required UI commands, return the response, and finish processing the request.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Request
   ↓
Server
   ↓
Generate Commands
   ↓
Response
   ↓
Server Request State Ends
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The server does not need to maintain a continuously synchronized representation of the client's DOM.&lt;/p&gt;

&lt;p&gt;This makes the architecture naturally compatible with stateless HTTP applications and horizontal scaling.&lt;/p&gt;

&lt;p&gt;For example, multiple server instances can process independent requests:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                 ┌── Server A
Browser ── HTTP ─┼── Server B
                 └── Server C
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The application does not need a particular server instance to continuously own the browser's UI state.&lt;/p&gt;




&lt;h2&gt;
  
  
  HTML Is Still the Interface
&lt;/h2&gt;

&lt;p&gt;WFC does not require a proprietary UI markup language.&lt;/p&gt;

&lt;p&gt;The interface is HTML.&lt;/p&gt;

&lt;p&gt;A normal Phoenix template can contain:&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;form&lt;/span&gt; &lt;span class="na"&gt;method=&lt;/span&gt;&lt;span class="s"&gt;"post"&lt;/span&gt; &lt;span class="na"&gt;action=&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"txt_Name"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Your Name&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"txt_Name"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"txt_Name"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&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;name=&lt;/span&gt;&lt;span class="s"&gt;"btn_SetBodyValue"&lt;/span&gt;
           &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;
           &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"Click to send data"&lt;/span&gt;&lt;span class="nt"&gt;&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;p&gt;There is no requirement to convert the page into a separate component language.&lt;/p&gt;

&lt;p&gt;The HTML remains the HTML that the browser understands.&lt;/p&gt;

&lt;p&gt;WebFormsJS operates on that existing DOM.&lt;/p&gt;

&lt;p&gt;This creates a simple relationship:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HTML
  +
WebFormsJS
  +
Server Commands
  =
Interactive UI
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  RESTful and HTTP-Friendly
&lt;/h2&gt;

&lt;p&gt;A Server-Driven UI architecture does not necessarily require a persistent connection between the server and the browser.&lt;/p&gt;

&lt;p&gt;WFC commands can be returned through ordinary HTTP responses.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;POST /submit
        ↓
Phoenix Controller
        ↓
    WebForms
        ↓
WebForms Core Response
        ↓
  HTTP Response
        ↓
   WebFormsJS
        ↓
   DOM Update
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This fits naturally into the request/response model of the web.&lt;/p&gt;

&lt;p&gt;At the same time, WFC is not restricted to HTTP request/response communication.&lt;/p&gt;

&lt;p&gt;Depending on the application's requirements, server-generated commands can also be transported through technologies such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;HTTP&lt;/li&gt;
&lt;li&gt;WebSocket&lt;/li&gt;
&lt;li&gt;Server-Sent Events (SSE)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The command architecture remains the same.&lt;/p&gt;

&lt;p&gt;Only the transport mechanism changes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                  ┌── HTTP
WebForms Commands ├── WebSocket
                  └── SSE
                       ↓
                  WebFormsJS
                       ↓
                   HTML DOM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This separation between &lt;strong&gt;command generation&lt;/strong&gt; and &lt;strong&gt;transport&lt;/strong&gt; allows the UI architecture to remain independent from a single communication mechanism.&lt;/p&gt;




&lt;h2&gt;
  
  
  Server-Orchestrated UI
&lt;/h2&gt;

&lt;p&gt;WFC can be described as a &lt;strong&gt;Server-Orchestrated UI&lt;/strong&gt; architecture.&lt;/p&gt;

&lt;p&gt;The server determines which UI operations should occur.&lt;/p&gt;

&lt;p&gt;For example, server-side Elixir code can express:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="no"&gt;WebForms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;WebForms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_font_size&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;InputPlace&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"form"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;WebForms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_background_color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;InputPlace&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"form"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s2"&gt;"#eeeeee"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;WebForms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_disabled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;InputPlace&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"btn_SetBodyValue"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The server is defining behavior.&lt;/p&gt;

&lt;p&gt;The browser is executing behavior.&lt;/p&gt;

&lt;p&gt;WebFormsJS receives the generated commands and applies them to the DOM.&lt;/p&gt;

&lt;p&gt;The server does not need to send a complete replacement page.&lt;/p&gt;

&lt;p&gt;It can send only the operations required for the current interaction.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Commander–Executor Architecture
&lt;/h2&gt;

&lt;p&gt;This creates a clear division between the server and the browser.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;             SERVER
                │
                ▼
          WebForms Class
            Commander
                │
                ▼
       WebForms Commands
                │
                ▼
             BROWSER
                │
                ▼
           WebFormsJS
            Executor
                │
                ▼
            HTML DOM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;WebForms&lt;/code&gt; class is the &lt;strong&gt;Commander&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It creates the instructions.&lt;/p&gt;

&lt;p&gt;WebFormsJS is the &lt;strong&gt;Executor&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It interprets and executes the instructions.&lt;/p&gt;

&lt;p&gt;This is different from sending application-level JavaScript from the server.&lt;/p&gt;

&lt;p&gt;The server generates WebForms Core commands, while WebFormsJS provides the runtime that understands those commands.&lt;/p&gt;




&lt;h2&gt;
  
  
  Building a Phoenix Application
&lt;/h2&gt;

&lt;p&gt;Let's see how this architecture works in a real Elixir application.&lt;/p&gt;

&lt;p&gt;The example uses Phoenix and the &lt;code&gt;wfc&lt;/code&gt; package.&lt;/p&gt;

&lt;p&gt;Add WFC to the project's dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;defp&lt;/span&gt; &lt;span class="n"&gt;deps&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:wfc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"~&amp;gt; 2.1"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then fetch the dependency:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mix deps.get
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The package provides the &lt;code&gt;WebFormsCore&lt;/code&gt; namespace:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;alias&lt;/span&gt; &lt;span class="no"&gt;WebFormsCore&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="no"&gt;WebForms&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;InputPlace&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  The Phoenix View
&lt;/h2&gt;

&lt;p&gt;Create an &lt;code&gt;index.html.heex&lt;/code&gt; view:&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;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"module"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"/script/web-forms.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;form&lt;/span&gt; &lt;span class="na"&gt;method=&lt;/span&gt;&lt;span class="s"&gt;"post"&lt;/span&gt; &lt;span class="na"&gt;action=&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"txt_Name"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Your Name&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"txt_Name"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"txt_Name"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;br&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"txt_FontSize"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Set Font Size&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"txt_FontSize"&lt;/span&gt;
           &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"txt_FontSize"&lt;/span&gt;
           &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"number"&lt;/span&gt;
           &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"16"&lt;/span&gt;
           &lt;span class="na"&gt;min=&lt;/span&gt;&lt;span class="s"&gt;"10"&lt;/span&gt;
           &lt;span class="na"&gt;max=&lt;/span&gt;&lt;span class="s"&gt;"36"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;br&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"txt_BackgroundColor"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Set Background Color&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"txt_BackgroundColor"&lt;/span&gt;
           &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"txt_BackgroundColor"&lt;/span&gt;
           &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;br&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"btn_SetBodyValue"&lt;/span&gt;
           &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;
           &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"Click to send data"&lt;/span&gt;&lt;span class="nt"&gt;&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;p&gt;The first &lt;code&gt;GET /&lt;/code&gt; request renders the complete HTML page.&lt;/p&gt;

&lt;p&gt;The browser now owns the interface.&lt;/p&gt;

&lt;p&gt;When the user submits the form, Phoenix receives the form data.&lt;/p&gt;

&lt;p&gt;The controller can then generate commands instead of rendering another complete page.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Phoenix Controller
&lt;/h2&gt;

&lt;p&gt;Create &lt;code&gt;my_controller.ex&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;MyAppWeb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;MyController&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="no"&gt;MyAppWeb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:controller&lt;/span&gt;

  &lt;span class="n"&gt;alias&lt;/span&gt; &lt;span class="no"&gt;WebFormsCore&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="no"&gt;WebForms&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;InputPlace&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;submit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;%{&lt;/span&gt;
        &lt;span class="s2"&gt;"txt_Name"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"txt_BackgroundColor"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;background_color&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"txt_FontSize"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;font_size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"btn_SetBodyValue"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_button&lt;/span&gt;
      &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
      &lt;span class="no"&gt;WebForms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;WebForms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_font_size&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;InputPlace&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"form"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="no"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_integer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;font_size&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
      &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;WebForms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_background_color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;InputPlace&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"form"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;background_color&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;WebForms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_disabled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;InputPlace&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"btn_SetBodyValue"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;WebForms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;InputPlace&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"form"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s2"&gt;"h3"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;WebForms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;InputPlace&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"h3"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s2"&gt;"Welcome &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;WebForms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The controller creates a &lt;code&gt;WebForms&lt;/code&gt; object and builds the UI operations.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="no"&gt;WebForms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_font_size&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="no"&gt;InputPlace&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"form"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="no"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_integer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;font_size&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;changes the font size of the &lt;code&gt;&amp;lt;form&amp;gt;&lt;/code&gt; element.&lt;/p&gt;

&lt;p&gt;This:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="no"&gt;WebForms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_background_color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="no"&gt;InputPlace&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"form"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="n"&gt;background_color&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;changes its background color.&lt;/p&gt;

&lt;p&gt;And:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="no"&gt;WebForms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_disabled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="no"&gt;InputPlace&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"btn_SetBodyValue"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="no"&gt;true&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;disables the submit button.&lt;/p&gt;

&lt;p&gt;The controller can also create new HTML elements:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="no"&gt;WebForms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="no"&gt;InputPlace&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"form"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="s2"&gt;"h3"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and set their contents:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="no"&gt;WebForms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="no"&gt;InputPlace&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"h3"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="s2"&gt;"Welcome &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;!"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;WebForms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;returns the generated WebForms Core response.&lt;/p&gt;

&lt;p&gt;The response contains the commands that WebFormsJS will execute.&lt;/p&gt;




&lt;h2&gt;
  
  
  Phoenix Router
&lt;/h2&gt;

&lt;p&gt;Add the routes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;MyAppWeb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Router&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="no"&gt;MyAppWeb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:router&lt;/span&gt;

  &lt;span class="n"&gt;scope&lt;/span&gt; &lt;span class="s2"&gt;"/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;MyAppWeb&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="s2"&gt;"/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;MyController&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:index&lt;/span&gt;
    &lt;span class="n"&gt;post&lt;/span&gt; &lt;span class="s2"&gt;"/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;MyController&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:submit&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The request flow is now:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GET /
  ↓
Phoenix
  ↓
HTML View
  ↓
Browser
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After submitting the form:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;POST /
  ↓
Phoenix Controller
  ↓
WebForms
  ↓
WebForms Core Commands
  ↓
HTTP Response
  ↓
WebFormsJS
  ↓
HTML DOM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No server-side DOM needs to be maintained.&lt;/p&gt;




&lt;h2&gt;
  
  
  WebFormsJS
&lt;/h2&gt;

&lt;p&gt;WebFormsJS is the browser runtime responsible for executing WebForms Core commands.&lt;/p&gt;

&lt;p&gt;Load it with:&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;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"module"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"/script/web-forms.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Its role is not to replace HTML.&lt;/p&gt;

&lt;p&gt;Its role is to operate on HTML.&lt;/p&gt;

&lt;p&gt;The relationship is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Server
  ↓
Command
  ↓
WebFormsJS
  ↓
Existing HTML DOM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes WebFormsJS an execution layer rather than a replacement for the browser's native document model.&lt;/p&gt;

&lt;p&gt;Get WebFormsJS in GitHub: &lt;a href="https://github.com/webforms-core/Web_forms" rel="noopener noreferrer"&gt;https://github.com/webforms-core/Web_forms&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Get WebFormsJS in Elanat: &lt;a href="https://elanat.net/webforms-js" rel="noopener noreferrer"&gt;https://elanat.net/webforms-js&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Designed for Scale
&lt;/h2&gt;

&lt;p&gt;Statelessness is particularly important for large web applications.&lt;/p&gt;

&lt;p&gt;When UI state does not need to remain attached to a particular server process, requests can be distributed across multiple application instances.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                         ┌── Phoenix Server 1
                         │
Browser ── Load Balancer ├── Phoenix Server 2
                         │
                         └── Phoenix Server 3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each request can be processed independently.&lt;/p&gt;

&lt;p&gt;The server receives the request, executes application logic, generates the required UI commands, returns the response, and completes the request.&lt;/p&gt;

&lt;p&gt;This architecture can work naturally with common scaling mechanisms such as load balancing and multiple application instances.&lt;/p&gt;

&lt;p&gt;The browser remains responsible for the DOM.&lt;/p&gt;

&lt;p&gt;The server remains responsible for application logic and command generation.&lt;/p&gt;




&lt;h2&gt;
  
  
  Stateless Does Not Mean Less Interactive
&lt;/h2&gt;

&lt;p&gt;A stateless server does not mean a static interface.&lt;/p&gt;

&lt;p&gt;WFC commands can perform a wide range of DOM operations.&lt;/p&gt;

&lt;p&gt;The server can instruct the browser to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Change text&lt;/li&gt;
&lt;li&gt;Change attributes&lt;/li&gt;
&lt;li&gt;Change styles&lt;/li&gt;
&lt;li&gt;Add elements&lt;/li&gt;
&lt;li&gt;Remove elements&lt;/li&gt;
&lt;li&gt;Enable or disable controls&lt;/li&gt;
&lt;li&gt;Replace content&lt;/li&gt;
&lt;li&gt;Move through UI flows&lt;/li&gt;
&lt;li&gt;Respond to user interactions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The interaction can therefore remain dynamic while the server remains stateless.&lt;/p&gt;

&lt;p&gt;This is an important distinction:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Stateless Server
        ≠
Static UI
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A server can be stateless while still orchestrating rich browser interactions.&lt;/p&gt;




&lt;h2&gt;
  
  
  One UI Architecture, Multiple Transports
&lt;/h2&gt;

&lt;p&gt;Another important property of WFC is the separation between &lt;strong&gt;what should happen&lt;/strong&gt; and &lt;strong&gt;how the command is transported&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The UI command itself can remain conceptually the same:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Set Text
Set Style
Add Element
Disable Button
Replace Content
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The transport can vary:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HTTP
WebSocket
SSE
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes it possible to select a communication model based on application requirements without changing the fundamental UI command architecture.&lt;/p&gt;

&lt;p&gt;For a conventional form submission, HTTP may be sufficient.&lt;/p&gt;

&lt;p&gt;For continuous server-to-browser events, SSE may be appropriate.&lt;/p&gt;

&lt;p&gt;For bidirectional real-time communication, WebSocket may be appropriate.&lt;/p&gt;

&lt;p&gt;The WebFormsJS runtime remains the execution environment.&lt;/p&gt;




&lt;h2&gt;
  
  
  HTML-Native Server-Driven UI
&lt;/h2&gt;

&lt;p&gt;The web platform already provides a powerful document model: HTML and the DOM.&lt;/p&gt;

&lt;p&gt;WFC builds its UI architecture around that model.&lt;/p&gt;

&lt;p&gt;There is no requirement for a separate virtual DOM.&lt;/p&gt;

&lt;p&gt;There is no requirement for a separate frontend project.&lt;/p&gt;

&lt;p&gt;There is no requirement for a client-side component build pipeline.&lt;/p&gt;

&lt;p&gt;The fundamental UI remains:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HTML → DOM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;WebForms Core adds a server-generated command layer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Server
   ↓
Commands
   ↓
WebFormsJS
   ↓
HTML DOM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This keeps the browser interface close to the native web platform while allowing the server to orchestrate interactive behavior.&lt;/p&gt;




&lt;h2&gt;
  
  
  A Different Way to Build Interactive Web Applications
&lt;/h2&gt;

&lt;p&gt;WebForms Core combines several architectural ideas:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Stateless Server
       +
RESTful / HTTP Architecture
       +
HTML-Native UI
       +
Server-Generated Commands
       +
Browser Runtime
       +
Multiple Transports
       ↓
Server-Orchestrated UI
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For Elixir applications, Phoenix provides the server-side web framework, while WFC provides the server-side UI command layer and WebFormsJS provides the browser-side execution runtime.&lt;/p&gt;

&lt;p&gt;The result is a model where:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The server owns the application logic.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The browser owns the DOM.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;WebForms defines the UI commands.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;WebFormsJS executes the commands.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And the server does not need to maintain a continuously synchronized copy of the browser interface.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Architecture
&lt;/h2&gt;

&lt;p&gt;The complete architecture can be summarized in one diagram:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                         SERVER
                            │
                     Phoenix / Elixir
                            │
                            ▼
                      WebForms Class
                        Commander
                            │
                            ▼
                  WebForms Core Commands
                            │
                 ┌──────────┼──────────┐
                 │          │          │
                HTTP       SSE     WebSocket
                 │          │          │
                 └──────────┼──────────┘
                            │
                            ▼
                        WebFormsJS
                         Executor
                            │
                            ▼
                        HTML DOM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the core idea behind the new Server-Driven UI approach of WebForms Core:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The server orchestrates.&lt;br&gt;&lt;br&gt;
The browser executes.&lt;br&gt;&lt;br&gt;
HTML remains the interface.&lt;br&gt;&lt;br&gt;
The server remains stateless.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;WebForms Core is a technology owned and developed by &lt;strong&gt;Elanat&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Official website: &lt;a href="https://elanat.net" rel="noopener noreferrer"&gt;https://elanat.net&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;WebForms Core: &lt;a href="https://elanat.net/webforms-core" rel="noopener noreferrer"&gt;https://elanat.net/webforms-core&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;WebForms Core GitHub: &lt;a href="https://github.com/webforms-core" rel="noopener noreferrer"&gt;https://github.com/webforms-core&lt;/a&gt;&lt;/p&gt;

</description>
      <category>elixir</category>
      <category>phoenix</category>
      <category>webdev</category>
      <category>webformscore</category>
    </item>
    <item>
      <title>New Server-Driven UI in Dart - WebForms Core</title>
      <dc:creator>Elanat Framework</dc:creator>
      <pubDate>Fri, 18 Sep 2026 19:41:58 +0000</pubDate>
      <link>https://dev.to/elanatframework/new-server-driven-ui-in-dart-webforms-core-121f</link>
      <guid>https://dev.to/elanatframework/new-server-driven-ui-in-dart-webforms-core-121f</guid>
      <description>&lt;p&gt;What if you could build interactive web interfaces in &lt;strong&gt;Dart&lt;/strong&gt;, without writing a separate JavaScript UI layer?&lt;/p&gt;

&lt;p&gt;What if the server could define not only the initial HTML, but also the UI behavior that should happen when the user interacts with that HTML?&lt;/p&gt;

&lt;p&gt;A new approach is now available for Dart.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;WebForms Core (WFC)&lt;/strong&gt; is now available for Dart.&lt;/p&gt;

&lt;p&gt;WebForms Core is a server-side UI manipulation technology created by &lt;a href="https://elanat.net" rel="noopener noreferrer"&gt;Elanat&lt;/a&gt;. It allows server-side code to generate commands for manipulating the browser DOM through the &lt;strong&gt;WebFormsJS&lt;/strong&gt; runtime.&lt;/p&gt;

&lt;p&gt;And now, Dart can act as a &lt;strong&gt;WebForms Commander&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Different Approach to Web UI
&lt;/h2&gt;

&lt;p&gt;A typical Dart web application can use Dart to build its server-side application and return HTML to the browser. Client-side JavaScript can then take responsibility for interactive behavior.&lt;/p&gt;

&lt;p&gt;WebForms Core takes a different approach.&lt;/p&gt;

&lt;p&gt;The server can define UI operations such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;creating HTML elements&lt;/li&gt;
&lt;li&gt;changing styles&lt;/li&gt;
&lt;li&gt;changing attributes&lt;/li&gt;
&lt;li&gt;changing text&lt;/li&gt;
&lt;li&gt;responding to events&lt;/li&gt;
&lt;li&gt;reading values from the DOM&lt;/li&gt;
&lt;li&gt;executing conditional logic&lt;/li&gt;
&lt;li&gt;controlling UI flow&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The browser does not need to understand Dart.&lt;/p&gt;

&lt;p&gt;Instead, the server generates &lt;strong&gt;WebForms Core commands&lt;/strong&gt;, and WebFormsJS interprets and executes those commands in the browser.&lt;/p&gt;

&lt;p&gt;The architecture is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Dart
  ↓
WebForms
  ↓
Action Controls
  ↓
WebFormsJS
  ↓
HTML DOM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is not a JavaScript framework.&lt;/p&gt;

&lt;p&gt;It is a &lt;strong&gt;Commander–Executor architecture&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Dart is the Commander.&lt;/p&gt;

&lt;p&gt;WebFormsJS is the Executor.&lt;/p&gt;

&lt;h2&gt;
  
  
  A First Dart Example
&lt;/h2&gt;

&lt;p&gt;Let's start with something very simple.&lt;/p&gt;

&lt;p&gt;Imagine a page containing a &lt;code&gt;&amp;lt;select&amp;gt;&lt;/code&gt; element. The user selects a color, and the background and text color of the page change immediately.&lt;/p&gt;

&lt;p&gt;Here is the Dart code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'dart:io'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:shelf/shelf.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:shelf/shelf_io.dart'&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;io&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:shelf_router/shelf_router.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:webforms/webforms.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="n"&gt;router&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Router&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="n"&gt;router&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'/script/web-forms.js'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt; &lt;span class="n"&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;final&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;File&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'web/script/web-forms.js'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;existsSync&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="n"&gt;Response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;notFound&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'web-forms.js not found'&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="n"&gt;Response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;readAsStringSync&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
      &lt;span class="nl"&gt;headers:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;'Content-Type'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'application/javascript; charset=utf-8'&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="n"&gt;router&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'/'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt; &lt;span class="n"&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;final&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;WebForms&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addOptionTag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&amp;lt;select&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"White"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"white"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addOptionTag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"-"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Light Green"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"lightgreen"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addOptionTag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"-"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Light Blue"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"lightblue"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addOptionTag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"-"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Red"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"red"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addOptionTag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"-"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Blue"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"blue"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addOptionTag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"-"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Green"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"green"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addOptionTag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"-"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Yellow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"yellow"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addOptionTag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"-"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Orange"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"orange"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addOptionTag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"-"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Purple"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"purple"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addOptionTag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"-"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Pink"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"pink"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addOptionTag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"-"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Brown"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"brown"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addOptionTag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"-"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Black"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"black"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addOptionTag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"-"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Gray"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"gray"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setCommentEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"-"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;HtmlEvent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;index:&lt;/span&gt; &lt;span class="s"&gt;"set-color"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;startIndex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"set-color"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setBackgroundColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&amp;lt;body&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Fetch&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&amp;lt;select&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isEqualTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"black"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Fetch&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&amp;lt;select&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setTextColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&amp;lt;body&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"white"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;else_&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setTextColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&amp;lt;body&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"black"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="n"&gt;_htmlForm&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;exportToHtmlComment&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
      &lt;span class="nl"&gt;headers:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;'Content-Type'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'text/html; charset=utf-8'&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;var&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;io&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;serve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;router&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;InternetAddress&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;loopbackIPv4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="mi"&gt;8080&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Server running on http://&lt;/span&gt;&lt;span class="si"&gt;${server.address.host}&lt;/span&gt;&lt;span class="s"&gt;:&lt;/span&gt;&lt;span class="si"&gt;${server.port}&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;_htmlForm&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="s"&gt;'''
&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
  &amp;lt;title&amp;gt;Using WebForms Core&amp;lt;/title&amp;gt;
  &amp;lt;script type="module" src="/script/web-forms.js"&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;h1&amp;gt;WebForms Core in Dart&amp;lt;/h1&amp;gt;
    Change to change color
    &amp;lt;select&amp;gt;&amp;lt;/select&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;p&gt;&lt;strong&gt;Screenshot after running the Dart application&lt;/strong&gt;&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fncd56810cja1now7xy2k.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fncd56810cja1now7xy2k.png" alt="WebForms Core Technology in Dart" width="357" height="156"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There is no JavaScript event handler in the Dart application.&lt;/p&gt;

&lt;p&gt;There is no JavaScript DOM manipulation code.&lt;/p&gt;

&lt;p&gt;There is no client-side framework.&lt;/p&gt;

&lt;p&gt;The behavior is described through the &lt;code&gt;WebForms&lt;/code&gt; class.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Does the Server Actually Send?
&lt;/h2&gt;

&lt;p&gt;The initial response contains the normal HTML page, followed by a WebForms Core command block:&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="c"&gt;&amp;lt;!--[web-forms]
ao&amp;lt;select&amp;gt;=whiteWhite
ao-=lightgreenLight Green
ao-=lightblueLight Blue
ao-=redRed
ao-=blueBlue
ao-=greenGreen
ao-=yellowYellow
ao-=orangeOrange
ao-=purplePurple
ao-=pinkPink
ao-=brownBrown
ao-=blackBlack
ao-=grayGray
Eb-=onchangeset-color
#=set-color
bc&amp;lt;body&amp;gt;=@$v&amp;lt;select&amp;gt;
{et=black@$v&amp;lt;select&amp;gt;
tc&amp;lt;body&amp;gt;=white
}e
tc&amp;lt;body&amp;gt;=black
--&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is not JSON.&lt;/p&gt;

&lt;p&gt;It is not an HTML attribute.&lt;/p&gt;

&lt;p&gt;It is not a JavaScript program.&lt;/p&gt;

&lt;p&gt;It is a &lt;strong&gt;WebForms Core Action Control command stream&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;WebFormsJS detects the &lt;code&gt;[web-forms]&lt;/code&gt; comment and processes it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Then Something Interesting Happens
&lt;/h2&gt;

&lt;p&gt;The browser receives the page.&lt;/p&gt;

&lt;p&gt;WebFormsJS processes the commands.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;&amp;lt;select&amp;gt;&lt;/code&gt; element is populated.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;change&lt;/code&gt; event is connected.&lt;/p&gt;

&lt;p&gt;The conditional behavior is prepared.&lt;/p&gt;

&lt;p&gt;And the server-generated behavior becomes normal browser behavior.&lt;/p&gt;

&lt;p&gt;The resulting DOM contains:&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;select&lt;/span&gt; &lt;span class="na"&gt;onchange=&lt;/span&gt;&lt;span class="s"&gt;"CommentBack(event, 'set-color', '')"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;option&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"white"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;White&lt;span class="nt"&gt;&amp;lt;/option&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;option&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"lightgreen"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Light Green&lt;span class="nt"&gt;&amp;lt;/option&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;option&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"lightblue"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Light Blue&lt;span class="nt"&gt;&amp;lt;/option&amp;gt;&lt;/span&gt;
    ...
    &lt;span class="nt"&gt;&amp;lt;option&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"black"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Black&lt;span class="nt"&gt;&amp;lt;/option&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;option&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"gray"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Gray&lt;span class="nt"&gt;&amp;lt;/option&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/select&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important part is the execution model.&lt;/p&gt;

&lt;p&gt;After the initial response, the interaction does not require another server request.&lt;/p&gt;

&lt;p&gt;The browser executes the generated behavior locally.&lt;/p&gt;

&lt;p&gt;In this example, the sequence is essentially:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Server
  ↓
WebForms Commands
  ↓
Initial HTML Response
  ↓
WebFormsJS
  ↓
DOM + Event
  ↓
Browser Execution
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is one of the important ideas behind WebForms Core.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Server Defines the Behavior
&lt;/h2&gt;

&lt;p&gt;Look at this part again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;startIndex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"set-color"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setBackgroundColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&amp;lt;body&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Fetch&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&amp;lt;select&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isEqualTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"black"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Fetch&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&amp;lt;select&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setTextColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&amp;lt;body&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"white"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;else_&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setTextColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&amp;lt;body&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"black"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Dart server code describes the behavior.&lt;/p&gt;

&lt;p&gt;It says:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;When the &lt;code&gt;set-color&lt;/code&gt; event occurs, get the value of the &lt;code&gt;&amp;lt;select&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Set the body background color to that value.&lt;/li&gt;
&lt;li&gt;Check whether the selected value is &lt;code&gt;black&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;If it is black, make the text white.&lt;/li&gt;
&lt;li&gt;Otherwise, make the text black.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The logic is authored on the server.&lt;/p&gt;

&lt;p&gt;The execution happens in the browser.&lt;/p&gt;

&lt;p&gt;That distinction is fundamental.&lt;/p&gt;

&lt;h2&gt;
  
  
  Server-Orchestrated UI
&lt;/h2&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjvkt6iv8om5v6jeh55rl.jpg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjvkt6iv8om5v6jeh55rl.jpg" alt="Dart Programming with WebForms Core Technology" width="800" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;WebForms Core can be described as &lt;strong&gt;Server-Orchestrated UI&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The server does not continuously mirror the browser DOM.&lt;/p&gt;

&lt;p&gt;It does not need a virtual DOM.&lt;/p&gt;

&lt;p&gt;It does not require a separate frontend project.&lt;/p&gt;

&lt;p&gt;Instead, the server sends executable UI commands, while WebFormsJS provides the browser-side runtime that executes them.&lt;/p&gt;

&lt;p&gt;This creates a clear separation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Server
Commander
    ↓
Commands
    ↓
Browser
Executor
    ↓
HTML DOM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The WebForms class is responsible for constructing the commands.&lt;/p&gt;

&lt;p&gt;WebFormsJS is responsible for parsing and executing them.&lt;/p&gt;

&lt;h2&gt;
  
  
  But What About Server Requests?
&lt;/h2&gt;

&lt;p&gt;WebForms Core does not require every interaction to be sent back to the server.&lt;/p&gt;

&lt;p&gt;That is an important distinction.&lt;/p&gt;

&lt;p&gt;There are two possible patterns.&lt;/p&gt;

&lt;h3&gt;
  
  
  Client execution
&lt;/h3&gt;

&lt;p&gt;The server can send behavior that WebFormsJS executes directly in the browser.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User changes select
        ↓
WebFormsJS
        ↓
Read DOM value
        ↓
Change DOM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No additional server request is necessary.&lt;/p&gt;

&lt;h3&gt;
  
  
  Server execution
&lt;/h3&gt;

&lt;p&gt;Other interactions can send data back to the server.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User submits form
        ↓
      Server
        ↓
   Dart WebForms
        ↓
 WebForms Commands
        ↓
     Browser
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The server can then generate a new response containing only the UI operations required for that interaction.&lt;/p&gt;

&lt;p&gt;This makes WebForms Core a hybrid system.&lt;/p&gt;

&lt;p&gt;Some behavior can execute entirely in the browser.&lt;/p&gt;

&lt;p&gt;Other behavior can involve the server.&lt;/p&gt;

&lt;h2&gt;
  
  
  A More Traditional Dart Example
&lt;/h2&gt;

&lt;p&gt;Now consider a form.&lt;/p&gt;

&lt;p&gt;The user enters a name, chooses a font size, enters a background color, and submits the form.&lt;/p&gt;

&lt;p&gt;The Dart application can process the request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;readAsString&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="n"&gt;formData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Uri&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;splitQueryString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;body&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="n"&gt;formData&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'btn_SetBodyValue'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;formData&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'txt_Name'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="s"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="n"&gt;backgroundColor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;formData&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'txt_BackgroundColor'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="s"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="n"&gt;fontSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;tryParse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;formData&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'txt_FontSize'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="s"&gt;'16'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;WebForms&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setFontSize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;InputPlace&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'form'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="si"&gt;${fontSize}&lt;/span&gt;&lt;span class="s"&gt;px'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setBackgroundColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;InputPlace&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'form'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setDisabled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;InputPlace&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'btn_SetBodyValue'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addTag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;InputPlace&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'form'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s"&gt;'h3'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;InputPlace&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'h3'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s"&gt;'Welcome &lt;/span&gt;&lt;span class="si"&gt;$name&lt;/span&gt;&lt;span class="s"&gt;!'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;response&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="nl"&gt;headers:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s"&gt;'Content-Type'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'text/plain; charset=utf-8'&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;Notice what the server returns.&lt;/p&gt;

&lt;p&gt;It does not have to return the entire HTML document.&lt;/p&gt;

&lt;p&gt;It can return the commands required to update the existing page.&lt;/p&gt;

&lt;p&gt;The server might effectively say:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Change the form font size.
Change the form background.
Disable the submit button.
Add an h3 element.
Set its text.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;WebFormsJS executes those commands against the existing DOM.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dart Without a Separate UI JavaScript Layer
&lt;/h2&gt;

&lt;p&gt;This is where the Dart implementation becomes interesting.&lt;/p&gt;

&lt;p&gt;The developer can write:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;WebForms&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setBackgroundColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;InputPlace&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'form'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setDisabled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;InputPlace&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'btn_SetBodyValue'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addTag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;InputPlace&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'form'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s"&gt;'h3'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;InputPlace&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'h3'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s"&gt;'Welcome &lt;/span&gt;&lt;span class="si"&gt;$name&lt;/span&gt;&lt;span class="s"&gt;!'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of writing a separate JavaScript implementation for each of these operations, the Dart application constructs the WebForms Core command stream.&lt;/p&gt;

&lt;p&gt;The browser runtime handles the execution.&lt;/p&gt;

&lt;h2&gt;
  
  
  WebForms Core Is More Than HTML Generation
&lt;/h2&gt;

&lt;p&gt;It would be easy to look at this and think:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"This is just server-side HTML generation."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It is not.&lt;/p&gt;

&lt;p&gt;HTML generation is only one part of the system.&lt;/p&gt;

&lt;p&gt;The WebForms class can construct operations involving:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;DOM manipulation&lt;/li&gt;
&lt;li&gt;attributes&lt;/li&gt;
&lt;li&gt;styles&lt;/li&gt;
&lt;li&gt;events&lt;/li&gt;
&lt;li&gt;conditions&lt;/li&gt;
&lt;li&gt;DOM value retrieval&lt;/li&gt;
&lt;li&gt;UI state&lt;/li&gt;
&lt;li&gt;element creation&lt;/li&gt;
&lt;li&gt;element replacement&lt;/li&gt;
&lt;li&gt;workflow&lt;/li&gt;
&lt;li&gt;client-side execution&lt;/li&gt;
&lt;li&gt;server interaction&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The important unit is not simply HTML.&lt;/p&gt;

&lt;p&gt;It is the &lt;strong&gt;command&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Commander–Executor Model
&lt;/h2&gt;

&lt;p&gt;WebForms Core uses two major sides.&lt;/p&gt;

&lt;h3&gt;
  
  
  Commander
&lt;/h3&gt;

&lt;p&gt;The WebForms class runs on the server.&lt;/p&gt;

&lt;p&gt;In this case:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Dart
  ↓
WebForms
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Commander constructs the UI commands.&lt;/p&gt;

&lt;h3&gt;
  
  
  Executor
&lt;/h3&gt;

&lt;p&gt;WebFormsJS runs in the browser.&lt;/p&gt;

&lt;p&gt;It contains the runtime required to interpret and execute those commands.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;WebFormsJS
  ↓
HTML DOM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Together:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Dart WebForms Commander
          ↓
    Action Controls
          ↓
      WebFormsJS
          ↓
       HTML DOM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This architecture allows different server-side languages to use the same browser execution model.&lt;/p&gt;

&lt;p&gt;Dart is now another Commander.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Dart?
&lt;/h2&gt;

&lt;p&gt;Dart is already used across server-side and application development, and the Shelf ecosystem provides a lightweight foundation for HTTP applications.&lt;/p&gt;

&lt;p&gt;WebForms Core introduces another possibility for Dart web development:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Dart server
     +
WebForms Commander
     +
WebFormsJS
     =
Server-Orchestrated Web UI
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of introducing a large frontend framework for every interactive page, developers can keep more of the UI behavior in their server-side Dart code.&lt;/p&gt;

&lt;p&gt;That does not mean every application should work this way.&lt;/p&gt;

&lt;p&gt;It means there is another architectural option.&lt;/p&gt;

&lt;h2&gt;
  
  
  This Is Only the Beginning
&lt;/h2&gt;

&lt;p&gt;The examples above are deliberately small.&lt;/p&gt;

&lt;p&gt;The interesting question is what happens when the same model is applied to more complex interactions.&lt;/p&gt;

&lt;p&gt;What if the server can construct:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;multi-step UI workflows&lt;/li&gt;
&lt;li&gt;conditional DOM operations&lt;/li&gt;
&lt;li&gt;dynamic forms&lt;/li&gt;
&lt;li&gt;event-driven interactions&lt;/li&gt;
&lt;li&gt;partial UI updates&lt;/li&gt;
&lt;li&gt;client-side state operations&lt;/li&gt;
&lt;li&gt;complex DOM workflows&lt;/li&gt;
&lt;li&gt;browser-side execution without additional requests&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then the WebForms class becomes more than a response builder.&lt;/p&gt;

&lt;p&gt;It becomes a &lt;strong&gt;UI Commander&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;And WebFormsJS becomes more than a JavaScript helper.&lt;/p&gt;

&lt;p&gt;It becomes the &lt;strong&gt;Browser Executor&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  WebForms Core for Dart
&lt;/h2&gt;

&lt;p&gt;WebForms Core for Dart is now available as the &lt;code&gt;webforms&lt;/code&gt; Dart package.&lt;/p&gt;

&lt;p&gt;The package provides the WebForms Commander:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:webforms/webforms.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Install it with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dart pub add webforms
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The architecture remains the same:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Dart
  ↓
WebForms Commander
  ↓
WebForms Core Commands
  ↓
WebFormsJS Runtime
  ↓
HTML DOM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The goal is simple:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Write the UI behavior in Dart. Let the browser execute it.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This brings WebForms Core's server-orchestrated UI architecture to Dart, allowing Dart applications to generate WebForms Core commands and control browser-side UI behavior through the WebFormsJS Runtime.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;WebForms Core is now available for Dart.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Related links
&lt;/h2&gt;

&lt;p&gt;In Elanat:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://elanat.net/webforms-core" rel="noopener noreferrer"&gt;WebForms Core Page&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://elanat.net/webforms-js" rel="noopener noreferrer"&gt;WebFormsJS Page&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In GitHub:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/webforms-core" rel="noopener noreferrer"&gt;WebForms Core Organizations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/webforms-core/Web_forms" rel="noopener noreferrer"&gt;WebFormsJS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/webforms-core/Web_forms_classes" rel="noopener noreferrer"&gt;WebForms Classes&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In pub.dev:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://pub.dev/packages/webforms" rel="noopener noreferrer"&gt;WebForms Core Package&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>dart</category>
      <category>shelf</category>
      <category>serverdriven</category>
      <category>webformscore</category>
    </item>
    <item>
      <title>WFC in Perl: A Server-Driven UI Approach for Perl</title>
      <dc:creator>Elanat Framework</dc:creator>
      <pubDate>Tue, 15 Sep 2026 19:35:17 +0000</pubDate>
      <link>https://dev.to/elanatframework/wfc-in-perl-a-server-driven-ui-approach-for-perl-13k9</link>
      <guid>https://dev.to/elanatframework/wfc-in-perl-a-server-driven-ui-approach-for-perl-13k9</guid>
      <description>&lt;p&gt;Perl has long been used for server-side web development, but modern web applications often rely heavily on JavaScript frameworks to manipulate the browser interface. WebForms Core (WFC) provides another approach: the server can generate UI commands that are executed by a browser runtime. This article demonstrates how WebForms Core can be used with Perl and the Mojolicious framework to build an interactive web interface while keeping the UI logic on the server.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is WebForms Core?
&lt;/h2&gt;

&lt;p&gt;WebForms Core is a server-side UI manipulation technology created by &lt;strong&gt;&lt;a href="https://elanat.net" rel="noopener noreferrer"&gt;Elanat&lt;/a&gt;&lt;/strong&gt; that allows a server application to generate commands for manipulating the HTML DOM and controlling UI behavior in the browser. Instead of requiring a separate frontend application or a JavaScript framework for every interaction, the server uses the WebForms class to construct WebForms Core commands, and the WebFormsJS browser runtime receives and executes those commands. The architecture separates the server-side Commander from the browser-side Executor: the server generates UI commands, while WebFormsJS parses and executes them against the DOM. WebForms Core is not limited to forms or CRUD operations and can be used for general UI manipulation, automation, and interactive web applications.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;WebForms Core commands are generated by methods of the WebForms class, so developers do not need to construct the command syntax manually. Elanat refers to these commands as "&lt;strong&gt;Action Controls&lt;/strong&gt;".&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  WebForms Core in Perl
&lt;/h2&gt;

&lt;p&gt;The Perl implementation of WebForms Core provides the &lt;code&gt;WebForms&lt;/code&gt; class for generating WebForms Core commands from a Perl application.&lt;/p&gt;

&lt;p&gt;The architecture can be summarized as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Perl Application
      |
      v
WebForms Class
      |
      | WebForms Core Commands
      |
      | HTTP Response
      |
      v
  WebFormsJS
      |
      v
  HTML DOM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important point is that the Perl application does not need to directly manipulate the browser DOM. Instead, the server creates commands describing the required UI operations.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F356kpmvppz7ibkut8wzg.jpg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F356kpmvppz7ibkut8wzg.jpg" alt="WebForms Core" width="799" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For example, the server can instruct the browser to change a font size, change a background color, disable a button, add an element, and set its text.&lt;/p&gt;

&lt;h2&gt;
  
  
  The WebForms Class
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;WebForms&lt;/code&gt; class is the server-side Commander of WebForms Core.&lt;/p&gt;

&lt;p&gt;In Perl, an application creates a &lt;code&gt;WebForms&lt;/code&gt; object and uses its methods to construct UI commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight perl"&gt;&lt;code&gt;&lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="nv"&gt;$form&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;WebForms&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;set_font_size&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;InputPlace::&lt;/span&gt;&lt;span class="nv"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;('&lt;/span&gt;&lt;span class="s1"&gt;form&lt;/span&gt;&lt;span class="p"&gt;'),&lt;/span&gt; &lt;span class="p"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${fontSize}&lt;/span&gt;&lt;span class="s2"&gt;px&lt;/span&gt;&lt;span class="p"&gt;");&lt;/span&gt;
&lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;set_background_color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;InputPlace::&lt;/span&gt;&lt;span class="nv"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;('&lt;/span&gt;&lt;span class="s1"&gt;form&lt;/span&gt;&lt;span class="p"&gt;'),&lt;/span&gt; &lt;span class="nv"&gt;$backgroundColor&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;set_disabled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;InputPlace::&lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;('&lt;/span&gt;&lt;span class="s1"&gt;btn_SetBodyValue&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="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;add_tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;InputPlace::&lt;/span&gt;&lt;span class="nv"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;('&lt;/span&gt;&lt;span class="s1"&gt;form&lt;/span&gt;&lt;span class="p"&gt;'),&lt;/span&gt; &lt;span class="p"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;h3&lt;/span&gt;&lt;span class="p"&gt;');&lt;/span&gt;
&lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;set_text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;InputPlace::&lt;/span&gt;&lt;span class="nv"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;('&lt;/span&gt;&lt;span class="s1"&gt;h3&lt;/span&gt;&lt;span class="p"&gt;'),&lt;/span&gt; &lt;span class="p"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Welcome &lt;/span&gt;&lt;span class="si"&gt;$name&lt;/span&gt;&lt;span class="s2"&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;InputPlace&lt;/code&gt; helpers specify which HTML elements should be targeted. For example, &lt;code&gt;InputPlace::tag('form')&lt;/code&gt; selects the &lt;code&gt;form&lt;/code&gt; element, while &lt;code&gt;InputPlace::name('btn_SetBodyValue')&lt;/code&gt; selects an element by its &lt;code&gt;name&lt;/code&gt; attribute.&lt;/p&gt;

&lt;p&gt;The commands are then returned as part of the HTTP response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight perl"&gt;&lt;code&gt;&lt;span class="nv"&gt;$c&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;response&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes the WebForms class a server-side UI command generator. The Perl application determines what should happen to the interface, while the browser runtime performs the actual DOM operations.&lt;/p&gt;

&lt;h2&gt;
  
  
  WebFormsJS
&lt;/h2&gt;

&lt;p&gt;WebFormsJS is the browser-side runtime of WebForms Core.&lt;/p&gt;

&lt;p&gt;It is included in the HTML page as a JavaScript module or script and is responsible for receiving, parsing, and executing WebForms Core commands in the browser.&lt;/p&gt;

&lt;p&gt;For example:&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;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"module"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"/script/web-forms.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;WebFormsJS acts as the Executor between the server-generated commands and the browser DOM.&lt;/p&gt;

&lt;p&gt;The complete execution model is therefore:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Server
  |
  | WebForms commands
  |
  v
HTTP Response
  |
  v
WebFormsJS
  |
  | DOM operations
  |
  v
Browser
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means that the Perl application does not need to generate custom JavaScript for every UI operation. The server can use the WebForms class to express the required UI changes, while WebFormsJS handles their execution.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installing WFC from CPAN
&lt;/h2&gt;

&lt;p&gt;The Perl implementation of WebForms Core is distributed as the &lt;code&gt;WFC&lt;/code&gt; package.&lt;/p&gt;

&lt;p&gt;After installing Perl and &lt;code&gt;cpanm&lt;/code&gt;, the package can be installed with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cpanm WFC
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The package provides the WebForms Core Perl classes required by the application.&lt;/p&gt;

&lt;p&gt;For example, the application can load the WebForms implementation with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight perl"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nv"&gt;WebForms&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The CPAN distribution is useful when WebForms Core is installed as a dependency of a Perl web application rather than copied directly into the project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using WebForms Core with Mojolicious
&lt;/h2&gt;

&lt;p&gt;Mojolicious is a Perl web framework that can be used to build the server application. WebForms Core can be integrated into a Mojolicious application by creating a &lt;code&gt;WebForms&lt;/code&gt; object inside a route and returning its generated response.&lt;/p&gt;

&lt;p&gt;The following example demonstrates a complete interaction.&lt;/p&gt;

&lt;p&gt;The user enters a name, font size, and background color. When the form is submitted, Perl reads these values, creates WebForms Core commands, and returns them to the browser.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight perl"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;Mojolicious::&lt;/span&gt;&lt;span class="nv"&gt;Lite&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nv"&gt;WebForms&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nv"&gt;post&lt;/span&gt; &lt;span class="p"&gt;'&lt;/span&gt;&lt;span class="s1"&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="k"&gt;sub &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="nv"&gt;$c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;shift&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="nv"&gt;$name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$c&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;param&lt;/span&gt;&lt;span class="p"&gt;('&lt;/span&gt;&lt;span class="s1"&gt;txt_Name&lt;/span&gt;&lt;span class="p"&gt;');&lt;/span&gt;
    &lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="nv"&gt;$backgroundColor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$c&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;param&lt;/span&gt;&lt;span class="p"&gt;('&lt;/span&gt;&lt;span class="s1"&gt;txt_BackgroundColor&lt;/span&gt;&lt;span class="p"&gt;');&lt;/span&gt;
    &lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="nv"&gt;$fontSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$c&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;param&lt;/span&gt;&lt;span class="p"&gt;('&lt;/span&gt;&lt;span class="s1"&gt;txt_FontSize&lt;/span&gt;&lt;span class="p"&gt;');&lt;/span&gt;

    &lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="nv"&gt;$form&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;WebForms&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;set_font_size&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;InputPlace::&lt;/span&gt;&lt;span class="nv"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;('&lt;/span&gt;&lt;span class="s1"&gt;form&lt;/span&gt;&lt;span class="p"&gt;'),&lt;/span&gt; &lt;span class="p"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${fontSize}&lt;/span&gt;&lt;span class="s2"&gt;px&lt;/span&gt;&lt;span class="p"&gt;");&lt;/span&gt;
    &lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;set_background_color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;InputPlace::&lt;/span&gt;&lt;span class="nv"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;('&lt;/span&gt;&lt;span class="s1"&gt;form&lt;/span&gt;&lt;span class="p"&gt;'),&lt;/span&gt; &lt;span class="nv"&gt;$backgroundColor&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;set_disabled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;InputPlace::&lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;('&lt;/span&gt;&lt;span class="s1"&gt;btn_SetBodyValue&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="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;add_tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;InputPlace::&lt;/span&gt;&lt;span class="nv"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;('&lt;/span&gt;&lt;span class="s1"&gt;form&lt;/span&gt;&lt;span class="p"&gt;'),&lt;/span&gt; &lt;span class="p"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;h3&lt;/span&gt;&lt;span class="p"&gt;');&lt;/span&gt;
    &lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;set_text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;InputPlace::&lt;/span&gt;&lt;span class="nv"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;('&lt;/span&gt;&lt;span class="s1"&gt;h3&lt;/span&gt;&lt;span class="p"&gt;'),&lt;/span&gt; &lt;span class="p"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Welcome &lt;/span&gt;&lt;span class="si"&gt;$name&lt;/span&gt;&lt;span class="s2"&gt;!&lt;/span&gt;&lt;span class="p"&gt;");&lt;/span&gt;

    &lt;span class="nv"&gt;$c&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;response&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nv"&gt;get&lt;/span&gt; &lt;span class="p"&gt;'&lt;/span&gt;&lt;span class="s1"&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="k"&gt;sub &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="nv"&gt;$c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;shift&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nv"&gt;$c&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;HTML&lt;/span&gt;&lt;span class="p"&gt;');&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;!&lt;/span&gt;&lt;span class="nv"&gt;DOCTYPE&lt;/span&gt; &lt;span class="nv"&gt;html&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;html&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;head&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;title&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;Using&lt;/span&gt; &lt;span class="nv"&gt;WebForms&lt;/span&gt; &lt;span class="nv"&gt;Core&lt;/span&gt; &lt;span class="nv"&gt;in&lt;/span&gt; &lt;span class="nv"&gt;Perl&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nv"&gt;title&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;script&lt;/span&gt; &lt;span class="nv"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;module&lt;/span&gt;&lt;span class="p"&gt;"&lt;/span&gt; &lt;span class="nv"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/script/web-forms.js&lt;/span&gt;&lt;span class="p"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nv"&gt;script&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nv"&gt;head&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;form&lt;/span&gt; &lt;span class="nv"&gt;method&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;post&lt;/span&gt;&lt;span class="p"&gt;"&lt;/span&gt; &lt;span class="nv"&gt;action&lt;/span&gt;&lt;span class="o"&gt;=&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="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;label&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;txt_Name&lt;/span&gt;&lt;span class="p"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;Your&lt;/span&gt; &lt;span class="nv"&gt;Name&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nv"&gt;label&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;input&lt;/span&gt; &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;txt_Name&lt;/span&gt;&lt;span class="p"&gt;"&lt;/span&gt; &lt;span class="nv"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;txt_Name&lt;/span&gt;&lt;span class="p"&gt;"&lt;/span&gt; &lt;span class="nv"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text&lt;/span&gt;&lt;span class="p"&gt;"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;br&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;label&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;txt_FontSize&lt;/span&gt;&lt;span class="p"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;Set&lt;/span&gt; &lt;span class="nv"&gt;Font&lt;/span&gt; &lt;span class="nv"&gt;Size&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nv"&gt;label&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;input&lt;/span&gt; &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;txt_FontSize&lt;/span&gt;&lt;span class="p"&gt;"&lt;/span&gt; &lt;span class="nv"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;txt_FontSize&lt;/span&gt;&lt;span class="p"&gt;"&lt;/span&gt; &lt;span class="nv"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;number&lt;/span&gt;&lt;span class="p"&gt;"&lt;/span&gt; &lt;span class="nv"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;16&lt;/span&gt;&lt;span class="p"&gt;"&lt;/span&gt; &lt;span class="nv"&gt;min&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;10&lt;/span&gt;&lt;span class="p"&gt;"&lt;/span&gt; &lt;span class="nv"&gt;max&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;36&lt;/span&gt;&lt;span class="p"&gt;"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;br&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;label&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;txt_BackgroundColor&lt;/span&gt;&lt;span class="p"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;Set&lt;/span&gt; &lt;span class="nv"&gt;Background&lt;/span&gt; &lt;span class="nv"&gt;Color&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nv"&gt;label&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;input&lt;/span&gt; &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;txt_BackgroundColor&lt;/span&gt;&lt;span class="p"&gt;"&lt;/span&gt; &lt;span class="nv"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;txt_BackgroundColor&lt;/span&gt;&lt;span class="p"&gt;"&lt;/span&gt; &lt;span class="nv"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text&lt;/span&gt;&lt;span class="p"&gt;"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;br&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;input&lt;/span&gt; &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;btn_SetBodyValue&lt;/span&gt;&lt;span class="p"&gt;"&lt;/span&gt; &lt;span class="nv"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;submit&lt;/span&gt;&lt;span class="p"&gt;"&lt;/span&gt; &lt;span class="nv"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Click to send data&lt;/span&gt;&lt;span class="p"&gt;"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nv"&gt;form&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nv"&gt;html&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nv"&gt;HTML&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nv"&gt;app&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;start&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How the Example Works
&lt;/h2&gt;

&lt;p&gt;The initial &lt;code&gt;GET /&lt;/code&gt; request returns the HTML page. The page contains a normal HTML form and loads &lt;code&gt;web-forms.js&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;No WebForms Core-specific attributes are required in the form:&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;form&lt;/span&gt; &lt;span class="na"&gt;method=&lt;/span&gt;&lt;span class="s"&gt;"post"&lt;/span&gt; &lt;span class="na"&gt;action=&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When the user submits the form, the &lt;code&gt;POST /&lt;/code&gt; route receives the submitted values:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight perl"&gt;&lt;code&gt;&lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="nv"&gt;$name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$c&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;param&lt;/span&gt;&lt;span class="p"&gt;('&lt;/span&gt;&lt;span class="s1"&gt;txt_Name&lt;/span&gt;&lt;span class="p"&gt;');&lt;/span&gt;
&lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="nv"&gt;$backgroundColor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$c&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;param&lt;/span&gt;&lt;span class="p"&gt;('&lt;/span&gt;&lt;span class="s1"&gt;txt_BackgroundColor&lt;/span&gt;&lt;span class="p"&gt;');&lt;/span&gt;
&lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="nv"&gt;$fontSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$c&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;param&lt;/span&gt;&lt;span class="p"&gt;('&lt;/span&gt;&lt;span class="s1"&gt;txt_FontSize&lt;/span&gt;&lt;span class="p"&gt;');&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The server then creates a WebForms object:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight perl"&gt;&lt;code&gt;&lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="nv"&gt;$form&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;WebForms&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The UI operations are defined on the server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight perl"&gt;&lt;code&gt;&lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;set_font_size&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;InputPlace::&lt;/span&gt;&lt;span class="nv"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;('&lt;/span&gt;&lt;span class="s1"&gt;form&lt;/span&gt;&lt;span class="p"&gt;'),&lt;/span&gt; &lt;span class="p"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${fontSize}&lt;/span&gt;&lt;span class="s2"&gt;px&lt;/span&gt;&lt;span class="p"&gt;");&lt;/span&gt;
&lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;set_background_color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;InputPlace::&lt;/span&gt;&lt;span class="nv"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;('&lt;/span&gt;&lt;span class="s1"&gt;form&lt;/span&gt;&lt;span class="p"&gt;'),&lt;/span&gt; &lt;span class="nv"&gt;$backgroundColor&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;set_disabled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;InputPlace::&lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;('&lt;/span&gt;&lt;span class="s1"&gt;btn_SetBodyValue&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The server also creates an &lt;code&gt;h3&lt;/code&gt; element and sets its text:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight perl"&gt;&lt;code&gt;&lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;add_tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;InputPlace::&lt;/span&gt;&lt;span class="nv"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;('&lt;/span&gt;&lt;span class="s1"&gt;form&lt;/span&gt;&lt;span class="p"&gt;'),&lt;/span&gt; &lt;span class="p"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;h3&lt;/span&gt;&lt;span class="p"&gt;');&lt;/span&gt;
&lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;set_text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;InputPlace::&lt;/span&gt;&lt;span class="nv"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;('&lt;/span&gt;&lt;span class="s1"&gt;h3&lt;/span&gt;&lt;span class="p"&gt;'),&lt;/span&gt; &lt;span class="p"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Welcome &lt;/span&gt;&lt;span class="si"&gt;$name&lt;/span&gt;&lt;span class="s2"&gt;!&lt;/span&gt;&lt;span class="p"&gt;");&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, the generated WebForms Core response is returned:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight perl"&gt;&lt;code&gt;&lt;span class="nv"&gt;$c&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;response&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;WebFormsJS receives this response in the browser and executes the generated commands. The result is that the form's font size and background color change, the submit button becomes disabled, and a new heading containing the user's name is added to the page.&lt;/p&gt;

&lt;h2&gt;
  
  
  Server-Driven UI
&lt;/h2&gt;

&lt;p&gt;This example demonstrates the basic Server-Driven UI model provided by WebForms Core.&lt;/p&gt;

&lt;p&gt;The browser does not need a separate frontend application to implement the UI logic described by WebForms Core commands. The server determines the UI operations:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User Input
    |
    v
Mojolicious
    |
    v
WebForms
    |
    | UI Commands
    |
    v
HTTP Response
    |
    v
WebFormsJS
    |
    v
   DOM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is different from the traditional approach where the server primarily returns HTML while JavaScript code in the frontend contains the logic for manipulating that HTML.&lt;/p&gt;

&lt;p&gt;With WebForms Core, the server can orchestrate UI operations through commands while WebFormsJS provides the browser-side runtime that executes those commands.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building a Memory Game with WebForms Core
&lt;/h2&gt;

&lt;p&gt;WebForms Core is not limited to traditional forms or CRUD interfaces. The following example demonstrates a small memory card game implemented with Perl, Mojolicious, and WebForms Core.&lt;/p&gt;

&lt;p&gt;The game contains eight pairs of emoji cards, for a total of 16 tiles. The cards are shuffled on the server when a new game starts. The browser then uses WebForms Core commands to reveal cards, compare pairs, count moves and matches, and reset the game.&lt;/p&gt;

&lt;p&gt;This example is particularly useful for demonstrating that WebForms Core can handle interactive browser behavior without requiring a separate frontend application.&lt;/p&gt;

&lt;h3&gt;
  
  
  Memory Tiles Example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight perl"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;Mojolicious::&lt;/span&gt;&lt;span class="nv"&gt;Lite&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;List::&lt;/span&gt;&lt;span class="nv"&gt;Util&lt;/span&gt; &lt;span class="sx"&gt;qw(shuffle)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nv"&gt;WebForms&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nv"&gt;get&lt;/span&gt; &lt;span class="p"&gt;'&lt;/span&gt;&lt;span class="s1"&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="k"&gt;sub &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="nv"&gt;$c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;shift&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="nv"&gt;@cards&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;shuffle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="sx"&gt;qw(
            🍎 🍎
            🍋 🍋
            🍊 🍊
            🍉 🍉
            🍇 🍇
            🥝 🥝
            🍓 🍓
            🍒 🍒
        )&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="nv"&gt;$html&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;'';&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="nv"&gt;$i&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;..&lt;/span&gt; &lt;span class="nv"&gt;$#cards&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$html&lt;/span&gt; &lt;span class="o"&gt;.=&lt;/span&gt; &lt;span class="sx"&gt;qq{&amp;lt;button id="tag-$i" class="tile" data-card="$cards[$i]"&amp;gt;?&amp;lt;/button&amp;gt;\n}&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="nv"&gt;$form&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;WebForms&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;set_comment_event&lt;/span&gt;&lt;span class="p"&gt;("&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;button&amp;gt;*&lt;/span&gt;&lt;span class="p"&gt;",&lt;/span&gt; &lt;span class="nn"&gt;HtmlEvent::&lt;/span&gt;&lt;span class="nv"&gt;OnClick&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;play&lt;/span&gt;&lt;span class="p"&gt;");&lt;/span&gt;
    &lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;set_comment_event&lt;/span&gt;&lt;span class="p"&gt;("&lt;/span&gt;&lt;span class="s2"&gt;reset&lt;/span&gt;&lt;span class="p"&gt;",&lt;/span&gt; &lt;span class="nn"&gt;HtmlEvent::&lt;/span&gt;&lt;span class="nv"&gt;OnClick&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;reload&lt;/span&gt;&lt;span class="p"&gt;");&lt;/span&gt;
    &lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;remove_all_save&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;start_index&lt;/span&gt;&lt;span class="p"&gt;("&lt;/span&gt;&lt;span class="s2"&gt;play&lt;/span&gt;&lt;span class="p"&gt;");&lt;/span&gt;

    &lt;span class="c1"&gt;# First tile&lt;/span&gt;
    &lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;not_exist&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Fetch::&lt;/span&gt;&lt;span class="nv"&gt;save&lt;/span&gt;&lt;span class="p"&gt;("&lt;/span&gt;&lt;span class="s2"&gt;first-card&lt;/span&gt;&lt;span class="p"&gt;"));&lt;/span&gt;

    &lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;start_bracket&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;save_id&lt;/span&gt;&lt;span class="p"&gt;('&lt;/span&gt;&lt;span class="s1"&gt;$&lt;/span&gt;&lt;span class="p"&gt;',&lt;/span&gt; &lt;span class="p"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;first-id&lt;/span&gt;&lt;span class="p"&gt;");&lt;/span&gt;
    &lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;save_attribute&lt;/span&gt;&lt;span class="p"&gt;('&lt;/span&gt;&lt;span class="s1"&gt;$&lt;/span&gt;&lt;span class="p"&gt;',&lt;/span&gt; &lt;span class="p"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;data-card&lt;/span&gt;&lt;span class="p"&gt;",&lt;/span&gt; &lt;span class="p"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;first-card&lt;/span&gt;&lt;span class="p"&gt;");&lt;/span&gt;
    &lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;insert_class&lt;/span&gt;&lt;span class="p"&gt;('&lt;/span&gt;&lt;span class="s1"&gt;$&lt;/span&gt;&lt;span class="p"&gt;',&lt;/span&gt; &lt;span class="p"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;selected&lt;/span&gt;&lt;span class="p"&gt;");&lt;/span&gt;
    &lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;set_disabled&lt;/span&gt;&lt;span class="p"&gt;('&lt;/span&gt;&lt;span class="s1"&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="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;set_text&lt;/span&gt;&lt;span class="p"&gt;('&lt;/span&gt;&lt;span class="s1"&gt;$&lt;/span&gt;&lt;span class="p"&gt;',&lt;/span&gt; &lt;span class="nn"&gt;Fetch::&lt;/span&gt;&lt;span class="nv"&gt;get_attribute&lt;/span&gt;&lt;span class="p"&gt;('&lt;/span&gt;&lt;span class="s1"&gt;$&lt;/span&gt;&lt;span class="p"&gt;',&lt;/span&gt; &lt;span class="p"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;data-card&lt;/span&gt;&lt;span class="p"&gt;"));&lt;/span&gt;
    &lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;wf_break&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;end_bracket&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;increase&lt;/span&gt;&lt;span class="p"&gt;("&lt;/span&gt;&lt;span class="s2"&gt;moves&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="c1"&gt;# Second tile&lt;/span&gt;
    &lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;set_class&lt;/span&gt;&lt;span class="p"&gt;('&lt;/span&gt;&lt;span class="s1"&gt;$&lt;/span&gt;&lt;span class="p"&gt;',&lt;/span&gt; &lt;span class="p"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;selected&lt;/span&gt;&lt;span class="p"&gt;");&lt;/span&gt;
    &lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;set_disabled&lt;/span&gt;&lt;span class="p"&gt;('&lt;/span&gt;&lt;span class="s1"&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="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;set_text&lt;/span&gt;&lt;span class="p"&gt;('&lt;/span&gt;&lt;span class="s1"&gt;$&lt;/span&gt;&lt;span class="p"&gt;',&lt;/span&gt; &lt;span class="nn"&gt;Fetch::&lt;/span&gt;&lt;span class="nv"&gt;get_attribute&lt;/span&gt;&lt;span class="p"&gt;('&lt;/span&gt;&lt;span class="s1"&gt;$&lt;/span&gt;&lt;span class="p"&gt;',&lt;/span&gt; &lt;span class="p"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;data-card&lt;/span&gt;&lt;span class="p"&gt;"));&lt;/span&gt;

    &lt;span class="c1"&gt;# Match&lt;/span&gt;
    &lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;is_equal_to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nn"&gt;Fetch::&lt;/span&gt;&lt;span class="nv"&gt;save&lt;/span&gt;&lt;span class="p"&gt;("&lt;/span&gt;&lt;span class="s2"&gt;first-card&lt;/span&gt;&lt;span class="p"&gt;"),&lt;/span&gt;
        &lt;span class="nn"&gt;Fetch::&lt;/span&gt;&lt;span class="nv"&gt;get_attribute&lt;/span&gt;&lt;span class="p"&gt;('&lt;/span&gt;&lt;span class="s1"&gt;$&lt;/span&gt;&lt;span class="p"&gt;',&lt;/span&gt; &lt;span class="p"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;data-card&lt;/span&gt;&lt;span class="p"&gt;")&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;start_bracket&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;increase&lt;/span&gt;&lt;span class="p"&gt;("&lt;/span&gt;&lt;span class="s2"&gt;matches&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="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;remove_save&lt;/span&gt;&lt;span class="p"&gt;("&lt;/span&gt;&lt;span class="s2"&gt;first-card&lt;/span&gt;&lt;span class="p"&gt;");&lt;/span&gt;
    &lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;set_text&lt;/span&gt;&lt;span class="p"&gt;("&lt;/span&gt;&lt;span class="s2"&gt;result&lt;/span&gt;&lt;span class="p"&gt;",&lt;/span&gt; &lt;span class="p"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Good&lt;/span&gt;&lt;span class="p"&gt;");&lt;/span&gt;

    &lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;is_equal_to&lt;/span&gt;&lt;span class="p"&gt;("&lt;/span&gt;&lt;span class="s2"&gt;8&lt;/span&gt;&lt;span class="p"&gt;",&lt;/span&gt; &lt;span class="nn"&gt;Fetch::&lt;/span&gt;&lt;span class="nv"&gt;get_text&lt;/span&gt;&lt;span class="p"&gt;("&lt;/span&gt;&lt;span class="s2"&gt;matches&lt;/span&gt;&lt;span class="p"&gt;"));&lt;/span&gt;
    &lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;message&lt;/span&gt;&lt;span class="p"&gt;("&lt;/span&gt;&lt;span class="s2"&gt;🎉 You Win!&lt;/span&gt;&lt;span class="p"&gt;");&lt;/span&gt;

    &lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;wf_break&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;end_bracket&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;# No match&lt;/span&gt;
    &lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;800&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;# Return first card&lt;/span&gt;
    &lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;set_text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Fetch::&lt;/span&gt;&lt;span class="nv"&gt;save&lt;/span&gt;&lt;span class="p"&gt;("&lt;/span&gt;&lt;span class="s2"&gt;first-id&lt;/span&gt;&lt;span class="p"&gt;"),&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="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;set_class&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Fetch::&lt;/span&gt;&lt;span class="nv"&gt;save&lt;/span&gt;&lt;span class="p"&gt;("&lt;/span&gt;&lt;span class="s2"&gt;first-id&lt;/span&gt;&lt;span class="p"&gt;"),&lt;/span&gt; &lt;span class="p"&gt;"");&lt;/span&gt;
    &lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;set_disabled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Fetch::&lt;/span&gt;&lt;span class="nv"&gt;save&lt;/span&gt;&lt;span class="p"&gt;("&lt;/span&gt;&lt;span class="s2"&gt;first-id&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="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;remove_save&lt;/span&gt;&lt;span class="p"&gt;("&lt;/span&gt;&lt;span class="s2"&gt;first-card&lt;/span&gt;&lt;span class="p"&gt;");&lt;/span&gt;

    &lt;span class="c1"&gt;# Return second card&lt;/span&gt;
    &lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;set_text&lt;/span&gt;&lt;span class="p"&gt;('&lt;/span&gt;&lt;span class="s1"&gt;$&lt;/span&gt;&lt;span class="p"&gt;',&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="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;set_class&lt;/span&gt;&lt;span class="p"&gt;('&lt;/span&gt;&lt;span class="s1"&gt;$&lt;/span&gt;&lt;span class="p"&gt;',&lt;/span&gt; &lt;span class="p"&gt;"");&lt;/span&gt;
    &lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;set_disabled&lt;/span&gt;&lt;span class="p"&gt;('&lt;/span&gt;&lt;span class="s1"&gt;$&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="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;set_text&lt;/span&gt;&lt;span class="p"&gt;("&lt;/span&gt;&lt;span class="s2"&gt;result&lt;/span&gt;&lt;span class="p"&gt;",&lt;/span&gt; &lt;span class="p"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Try Again&lt;/span&gt;&lt;span class="p"&gt;");&lt;/span&gt;
    &lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;set_text&lt;/span&gt;&lt;span class="p"&gt;("&lt;/span&gt;&lt;span class="s2"&gt;moves&lt;/span&gt;&lt;span class="p"&gt;",&lt;/span&gt; &lt;span class="nn"&gt;Fetch::&lt;/span&gt;&lt;span class="nv"&gt;get_text&lt;/span&gt;&lt;span class="p"&gt;("&lt;/span&gt;&lt;span class="s2"&gt;moves&lt;/span&gt;&lt;span class="p"&gt;"));&lt;/span&gt;

    &lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;start_index&lt;/span&gt;&lt;span class="p"&gt;("&lt;/span&gt;&lt;span class="s2"&gt;reload&lt;/span&gt;&lt;span class="p"&gt;");&lt;/span&gt;
    &lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;reload_page&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="nv"&gt;$c&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;export_to_html_comment&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;HTML&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;!&lt;/span&gt;&lt;span class="nv"&gt;DOCTYPE&lt;/span&gt; &lt;span class="nv"&gt;html&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;html&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;head&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;title&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;Memory&lt;/span&gt; &lt;span class="nv"&gt;Tiles&lt;/span&gt; &lt;span class="nv"&gt;in&lt;/span&gt; &lt;span class="nv"&gt;Perl&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nv"&gt;title&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;script&lt;/span&gt; &lt;span class="nv"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;module&lt;/span&gt;&lt;span class="p"&gt;"&lt;/span&gt; &lt;span class="nv"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/script/web-forms.js&lt;/span&gt;&lt;span class="p"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nv"&gt;script&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;style&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nv"&gt;body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nv"&gt;font&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;family:&lt;/span&gt; &lt;span class="nv"&gt;sans&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;serif&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nv"&gt;text&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;align:&lt;/span&gt; &lt;span class="nv"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;#board {&lt;/span&gt;
            &lt;span class="nv"&gt;display:&lt;/span&gt; &lt;span class="nv"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nv"&gt;grid&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;template&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;columns:&lt;/span&gt; &lt;span class="nv"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="nv"&gt;px&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="nv"&gt;gap:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="nv"&gt;px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nv"&gt;justify&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;content:&lt;/span&gt; &lt;span class="nv"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nv"&gt;margin:&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="nv"&gt;px&lt;/span&gt; &lt;span class="nv"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;tile&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nv"&gt;width:&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="nv"&gt;px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nv"&gt;height:&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="nv"&gt;px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nv"&gt;font&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;size:&lt;/span&gt; &lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="nv"&gt;px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nv"&gt;cursor:&lt;/span&gt; &lt;span class="nv"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;#reset {&lt;/span&gt;
            &lt;span class="nv"&gt;cursor:&lt;/span&gt; &lt;span class="nv"&gt;pointer&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;lt;/&lt;/span&gt;&lt;span class="nv"&gt;style&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nv"&gt;head&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;Memory&lt;/span&gt; &lt;span class="nv"&gt;Tiles&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nv"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;div&lt;/span&gt; &lt;span class="nv"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;board&lt;/span&gt;&lt;span class="p"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nv"&gt;$html&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nv"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;Moves:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;span&lt;/span&gt; &lt;span class="nv"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;moves&lt;/span&gt;&lt;span class="p"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/span&amp;gt;&amp;lt;/p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;p&lt;/span&gt; &lt;span class="nv"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;result&lt;/span&gt;&lt;span class="p"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nv"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;Matches:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;span&lt;/span&gt; &lt;span class="nv"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;matches&lt;/span&gt;&lt;span class="p"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/span&amp;gt;&amp;lt;/p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;b&lt;/span&gt; &lt;span class="nv"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;reset&lt;/span&gt;&lt;span class="p"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;New&lt;/span&gt; &lt;span class="nv"&gt;Game&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nv"&gt;b&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nv"&gt;html&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nv"&gt;HTML&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nv"&gt;app&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;start&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  How the Memory Game Works
&lt;/h3&gt;

&lt;p&gt;The server initially creates the game board by generating pairs of emoji cards:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight perl"&gt;&lt;code&gt;&lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="nv"&gt;@cards&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;shuffle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sx"&gt;qw(
        🍎 🍎
        🍋 🍋
        🍊 🍊
        🍉 🍉
        🍇 🍇
        🥝 🥝
        🍓 🍓
        🍒 🍒
    )&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;shuffle&lt;/code&gt; function randomizes the cards for each new game. Perl then generates the HTML buttons for the board.&lt;/p&gt;

&lt;p&gt;The important part of the example is that the game behavior is defined through the &lt;code&gt;WebForms&lt;/code&gt; class.&lt;/p&gt;

&lt;h3&gt;
  
  
  Registering Events
&lt;/h3&gt;

&lt;p&gt;The following commands associate browser events with WebForms Core command indexes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight perl"&gt;&lt;code&gt;&lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;set_comment_event&lt;/span&gt;&lt;span class="p"&gt;("&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;button&amp;gt;*&lt;/span&gt;&lt;span class="p"&gt;",&lt;/span&gt; &lt;span class="nn"&gt;HtmlEvent::&lt;/span&gt;&lt;span class="nv"&gt;OnClick&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;play&lt;/span&gt;&lt;span class="p"&gt;");&lt;/span&gt;
&lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;set_comment_event&lt;/span&gt;&lt;span class="p"&gt;("&lt;/span&gt;&lt;span class="s2"&gt;reset&lt;/span&gt;&lt;span class="p"&gt;",&lt;/span&gt; &lt;span class="nn"&gt;HtmlEvent::&lt;/span&gt;&lt;span class="nv"&gt;OnClick&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;reload&lt;/span&gt;&lt;span class="p"&gt;");&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every tile button is associated with the &lt;code&gt;play&lt;/code&gt; command sequence, while the &lt;code&gt;reset&lt;/code&gt; element is associated with the &lt;code&gt;reload&lt;/code&gt; sequence.&lt;/p&gt;

&lt;p&gt;The generated commands are placed into the HTML response using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight perl"&gt;&lt;code&gt;&lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;export_to_html_comment&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This allows WebFormsJS to discover the server-generated commands from the HTML response.&lt;/p&gt;

&lt;h3&gt;
  
  
  Selecting the First Card
&lt;/h3&gt;

&lt;p&gt;The game uses WebForms Core Save values to remember information about the first selected card:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight perl"&gt;&lt;code&gt;&lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;not_exist&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Fetch::&lt;/span&gt;&lt;span class="nv"&gt;save&lt;/span&gt;&lt;span class="p"&gt;("&lt;/span&gt;&lt;span class="s2"&gt;first-card&lt;/span&gt;&lt;span class="p"&gt;"));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When no first card exists, the clicked tile becomes the first selected card.&lt;/p&gt;

&lt;p&gt;The example stores both the card identifier and its &lt;code&gt;data-card&lt;/code&gt; value:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight perl"&gt;&lt;code&gt;&lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;save_id&lt;/span&gt;&lt;span class="p"&gt;('&lt;/span&gt;&lt;span class="s1"&gt;$&lt;/span&gt;&lt;span class="p"&gt;',&lt;/span&gt; &lt;span class="p"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;first-id&lt;/span&gt;&lt;span class="p"&gt;");&lt;/span&gt;
&lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;save_attribute&lt;/span&gt;&lt;span class="p"&gt;('&lt;/span&gt;&lt;span class="s1"&gt;$&lt;/span&gt;&lt;span class="p"&gt;',&lt;/span&gt; &lt;span class="p"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;data-card&lt;/span&gt;&lt;span class="p"&gt;",&lt;/span&gt; &lt;span class="p"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;first-card&lt;/span&gt;&lt;span class="p"&gt;");&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The tile is then visually selected and disabled:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight perl"&gt;&lt;code&gt;&lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;insert_class&lt;/span&gt;&lt;span class="p"&gt;('&lt;/span&gt;&lt;span class="s1"&gt;$&lt;/span&gt;&lt;span class="p"&gt;',&lt;/span&gt; &lt;span class="p"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;selected&lt;/span&gt;&lt;span class="p"&gt;");&lt;/span&gt;
&lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;set_disabled&lt;/span&gt;&lt;span class="p"&gt;('&lt;/span&gt;&lt;span class="s1"&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="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;set_text&lt;/span&gt;&lt;span class="p"&gt;('&lt;/span&gt;&lt;span class="s1"&gt;$&lt;/span&gt;&lt;span class="p"&gt;',&lt;/span&gt; &lt;span class="nn"&gt;Fetch::&lt;/span&gt;&lt;span class="nv"&gt;get_attribute&lt;/span&gt;&lt;span class="p"&gt;('&lt;/span&gt;&lt;span class="s1"&gt;$&lt;/span&gt;&lt;span class="p"&gt;',&lt;/span&gt; &lt;span class="p"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;data-card&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;$&lt;/code&gt; InputPlace refers to the current target element.&lt;/p&gt;

&lt;h3&gt;
  
  
  Comparing the Cards
&lt;/h3&gt;

&lt;p&gt;When the second tile is selected, the game compares its &lt;code&gt;data-card&lt;/code&gt; value with the saved value from the first tile:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight perl"&gt;&lt;code&gt;&lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;is_equal_to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nn"&gt;Fetch::&lt;/span&gt;&lt;span class="nv"&gt;save&lt;/span&gt;&lt;span class="p"&gt;("&lt;/span&gt;&lt;span class="s2"&gt;first-card&lt;/span&gt;&lt;span class="p"&gt;"),&lt;/span&gt;
    &lt;span class="nn"&gt;Fetch::&lt;/span&gt;&lt;span class="nv"&gt;get_attribute&lt;/span&gt;&lt;span class="p"&gt;('&lt;/span&gt;&lt;span class="s1"&gt;$&lt;/span&gt;&lt;span class="p"&gt;',&lt;/span&gt; &lt;span class="p"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;data-card&lt;/span&gt;&lt;span class="p"&gt;")&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the values are equal, the match counter is increased:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight perl"&gt;&lt;code&gt;&lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;increase&lt;/span&gt;&lt;span class="p"&gt;("&lt;/span&gt;&lt;span class="s2"&gt;matches&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="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;remove_save&lt;/span&gt;&lt;span class="p"&gt;("&lt;/span&gt;&lt;span class="s2"&gt;first-card&lt;/span&gt;&lt;span class="p"&gt;");&lt;/span&gt;
&lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;set_text&lt;/span&gt;&lt;span class="p"&gt;("&lt;/span&gt;&lt;span class="s2"&gt;result&lt;/span&gt;&lt;span class="p"&gt;",&lt;/span&gt; &lt;span class="p"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Good&lt;/span&gt;&lt;span class="p"&gt;");&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When all eight pairs have been matched, the game displays a winning message:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight perl"&gt;&lt;code&gt;&lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;is_equal_to&lt;/span&gt;&lt;span class="p"&gt;("&lt;/span&gt;&lt;span class="s2"&gt;8&lt;/span&gt;&lt;span class="p"&gt;",&lt;/span&gt; &lt;span class="nn"&gt;Fetch::&lt;/span&gt;&lt;span class="nv"&gt;get_text&lt;/span&gt;&lt;span class="p"&gt;("&lt;/span&gt;&lt;span class="s2"&gt;matches&lt;/span&gt;&lt;span class="p"&gt;"));&lt;/span&gt;
&lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;message&lt;/span&gt;&lt;span class="p"&gt;("&lt;/span&gt;&lt;span class="s2"&gt;🎉 You Win!&lt;/span&gt;&lt;span class="p"&gt;");&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Handling a Failed Match
&lt;/h3&gt;

&lt;p&gt;If the two cards do not match, the commands wait for 800 milliseconds:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight perl"&gt;&lt;code&gt;&lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;800&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first card is then restored using the saved element identifier:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight perl"&gt;&lt;code&gt;&lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;set_text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Fetch::&lt;/span&gt;&lt;span class="nv"&gt;save&lt;/span&gt;&lt;span class="p"&gt;("&lt;/span&gt;&lt;span class="s2"&gt;first-id&lt;/span&gt;&lt;span class="p"&gt;"),&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="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;set_class&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Fetch::&lt;/span&gt;&lt;span class="nv"&gt;save&lt;/span&gt;&lt;span class="p"&gt;("&lt;/span&gt;&lt;span class="s2"&gt;first-id&lt;/span&gt;&lt;span class="p"&gt;"),&lt;/span&gt; &lt;span class="p"&gt;"");&lt;/span&gt;
&lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;set_disabled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Fetch::&lt;/span&gt;&lt;span class="nv"&gt;save&lt;/span&gt;&lt;span class="p"&gt;("&lt;/span&gt;&lt;span class="s2"&gt;first-id&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The second card is restored using the current target:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight perl"&gt;&lt;code&gt;&lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;set_text&lt;/span&gt;&lt;span class="p"&gt;('&lt;/span&gt;&lt;span class="s1"&gt;$&lt;/span&gt;&lt;span class="p"&gt;',&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="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;set_class&lt;/span&gt;&lt;span class="p"&gt;('&lt;/span&gt;&lt;span class="s1"&gt;$&lt;/span&gt;&lt;span class="p"&gt;',&lt;/span&gt; &lt;span class="p"&gt;"");&lt;/span&gt;
&lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;set_disabled&lt;/span&gt;&lt;span class="p"&gt;('&lt;/span&gt;&lt;span class="s1"&gt;$&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The result is then updated:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight perl"&gt;&lt;code&gt;&lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;set_text&lt;/span&gt;&lt;span class="p"&gt;("&lt;/span&gt;&lt;span class="s2"&gt;result&lt;/span&gt;&lt;span class="p"&gt;",&lt;/span&gt; &lt;span class="p"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Try Again&lt;/span&gt;&lt;span class="p"&gt;");&lt;/span&gt;
&lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;set_text&lt;/span&gt;&lt;span class="p"&gt;("&lt;/span&gt;&lt;span class="s2"&gt;moves&lt;/span&gt;&lt;span class="p"&gt;",&lt;/span&gt; &lt;span class="nn"&gt;Fetch::&lt;/span&gt;&lt;span class="nv"&gt;get_text&lt;/span&gt;&lt;span class="p"&gt;("&lt;/span&gt;&lt;span class="s2"&gt;moves&lt;/span&gt;&lt;span class="p"&gt;"));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Starting a New Game
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;reload&lt;/code&gt; command index is associated with the reset element:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight perl"&gt;&lt;code&gt;&lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;start_index&lt;/span&gt;&lt;span class="p"&gt;("&lt;/span&gt;&lt;span class="s2"&gt;reload&lt;/span&gt;&lt;span class="p"&gt;");&lt;/span&gt;
&lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;reload_page&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When the player selects &lt;strong&gt;New Game&lt;/strong&gt;, WebFormsJS executes the generated reload command and the server creates a new randomized board.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Screenshot of Memory Tiles Game&lt;/strong&gt;&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxlajf3p469d5x4tqiwts.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxlajf3p469d5x4tqiwts.png" alt="Server-Driven UI for Perl" width="395" height="597"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What This Example Demonstrates
&lt;/h3&gt;

&lt;p&gt;The memory game demonstrates several important WebForms Core capabilities in a single Perl application:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Event registration with &lt;code&gt;set_comment_event&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Command indexes with &lt;code&gt;start_index&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Conditional execution with &lt;code&gt;is_equal_to&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Temporary browser-side values with &lt;code&gt;Save&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;DOM targeting with &lt;code&gt;InputPlace&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Attribute and text retrieval with &lt;code&gt;Fetch&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;DOM modification&lt;/li&gt;
&lt;li&gt;Class manipulation&lt;/li&gt;
&lt;li&gt;Element disabling&lt;/li&gt;
&lt;li&gt;Counters and state changes&lt;/li&gt;
&lt;li&gt;Delayed execution&lt;/li&gt;
&lt;li&gt;Browser messages&lt;/li&gt;
&lt;li&gt;Page reload&lt;/li&gt;
&lt;li&gt;Server-generated commands embedded in HTML comments&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most importantly, the example demonstrates that WebForms Core can be used for &lt;strong&gt;interactive browser applications&lt;/strong&gt;, not only traditional server forms.&lt;/p&gt;

&lt;p&gt;The server defines the game behavior and generates the WebForms Core command sequence. WebFormsJS then executes that sequence in the browser.&lt;/p&gt;

&lt;p&gt;This provides a different model from a conventional JavaScript application: instead of implementing the complete game logic in a frontend JavaScript application, the server can construct the interaction flow through WebForms Core commands.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Use WebForms Core with Perl?
&lt;/h2&gt;

&lt;p&gt;WebForms Core gives Perl developers another option for building interactive web interfaces.&lt;/p&gt;

&lt;p&gt;A Perl application can keep its application and UI orchestration logic on the server while using a browser runtime for command execution. The developer does not need to introduce a separate React, Vue, or similar frontend project simply to perform server-controlled UI operations.&lt;/p&gt;

&lt;p&gt;This approach is particularly interesting for Perl applications that already have server-side business logic and want to add richer browser interaction without moving the entire application UI layer into a JavaScript framework.&lt;/p&gt;

&lt;p&gt;WebForms Core also keeps the HTML document model visible. The application works with HTML elements and selectors rather than replacing the HTML document with a separate component model.&lt;/p&gt;

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

&lt;p&gt;WebForms Core provides a Server-Driven UI approach for Perl by introducing a server-side &lt;code&gt;WebForms&lt;/code&gt; class and a browser-side WebFormsJS runtime.&lt;/p&gt;

&lt;p&gt;The Perl application acts as the Commander: it determines which UI operations should occur and generates the corresponding commands. WebFormsJS acts as the Executor: it receives those commands and performs the required operations on the browser DOM.&lt;/p&gt;

&lt;p&gt;With the &lt;code&gt;WFC&lt;/code&gt; package available through CPAN, this architecture can be used directly from Perl applications such as Mojolicious. The result is a model in which Perl remains responsible for application and UI orchestration logic, while the browser executes the commands through WebFormsJS.&lt;/p&gt;

&lt;h2&gt;
  
  
  Related links
&lt;/h2&gt;

&lt;p&gt;In Elanat:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://elanat.net/page_content/web_forms_core" rel="noopener noreferrer"&gt;WebForms Core Page&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://elanat.net/page_content/web_forms_js" rel="noopener noreferrer"&gt;WebFormsJS Page&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;in GitHub:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/webforms-core" rel="noopener noreferrer"&gt;WebForms Core Organizations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/webforms-core/Web_forms" rel="noopener noreferrer"&gt;WebFormsJS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/webforms-core/Web_forms_classes" rel="noopener noreferrer"&gt;WebForms Classes&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;in CPAN:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://metacpan.org/dist/WFC" rel="noopener noreferrer"&gt;WebForms Core Package&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>perl</category>
      <category>mojolicious</category>
      <category>cpan</category>
      <category>webformscore</category>
    </item>
  </channel>
</rss>
