What is WebForms Core?
WebForms Core is a new multi-platform technology from Elanat that is designed to compete with modern front-end frameworks, not an old ported version on .NET Core.
Example of Rock Paper Scissors
This example is a completely offline implementation using WebForms Core technology. In this example, commands are written on the server that declare the nature of the behavior to the client.
Note: The HTML output of the example can be copied and used offline without the need for a server.
As you can see, there are no additional tags in the HTML file. Unlike other Server-Driven UI systems, in WebForms Core technology, the server has no direct relationship with the HTML; in fact, the server is not only stateless, but also completely blind! This is a feature of WebForms Core technology that provides the following benefits:
Flexibility: The server can serve different clients with different views (web, mobile, desktop)
Scalability: Different teams can work in parallel on the server and client sides
Easier maintenance: Changing the appearance of the site does not require changing the server logic
Security: Data is transferred raw and the client only displays what it needs
Reusability: The built-in APIs can be used in multiple projects
Interestingly, we do not experience the benefit of Server Blindness in a server-centric system.
Golden sentence:
The server is not blind because it does not understand;
It is blind because it does not need to see.
HTML
@page
@controller RockPaperScissorsController
<!DOCTYPE html>
<html>
<head>
<title>WebForms Core Technology</title>
<script type="module" src="https://cdn.jsdelivr.net/gh/webforms-core/Web_forms@elanat_framework/web-forms.js" defer></script>
</head>
<body>
<h1>Rock ✊ Paper ✋ Scissors ✌️</h1>
<button value="0" win-with="2" id="Rock">Rock ✊</button>
<button value="1" win-with="0" id="Paper">Paper ✋</button>
<button value="2" win-with="1" id="Scissors">Scissors ✌️</button>
<p id="computer">Computer choice: <span></span></p>
<p id="result"></p>
<p id="counter">Game match: <span>0</span></p>
<p id="win-counter">Game win: <span>0</span></p>
</body>
</html>
Server Code
using CodeBehind;
public partial class RockPaperScissorsController : CodeBehindController
{
public void PageLoad(HttpContext context)
{
WebForms form = new WebForms();
form.SetCommentEvent("<button>*", HtmlEvent.OnClick, "play");
form.StartIndex("play");
form.Increase("counter|<span>", 1);
form.AddSessionCacheValue("random", Fetch.Random(0,3));
form.SetText("result", "😢 You lose!");
form.IsEqualTo(Fetch.GetAttribute("$", "win-with"), Fetch.Saved("random"));
form.StartBracket();
form.SetText("result", "😀 You win!");
form.Increase("win-counter|<span>", 1);
form.EndBracket();
form.IsEqualTo(Fetch.GetAttribute("$", "value"), Fetch.Saved("random"));
form.SetText("result", "😐 Equal!");
form.IsEqualTo("0", Fetch.Saved("random"));
form.SetText("computer|<span>", "Rock ✊");
form.IsEqualTo("1", Fetch.Saved("random"));
form.SetText("computer|<span>", "Paper ✋");
form.IsEqualTo("2", Fetch.Saved("random"));
form.SetText("computer|<span>", "Scissors ✌️");
Write(form.ExportToHtmlComment());
}
}
Result
<!--[web-forms]
Eb<button>*=onclick|play|
#=play
gtcounter|<span>=i|1
SA=random|@mr3,0
stresult=😢 You lose!
{et=@$a$,win-with|@csrandom
{
stresult=😀 You win!
gtwin-counter|<span>=i|1
}
{et=@$a$,value|@csrandom
stresult=😐 Equal!
{et=0|@csrandom
stcomputer|<span>=Rock ✊
{et=1|@csrandom
stcomputer|<span>=Paper ✋
{et=2|@csrandom
stcomputer|<span>=Scissors ✌️-->
<!DOCTYPE html>
<html>
<head>
<title>WebForms Core Technology</title>
<script type="module" src="https://cdn.jsdelivr.net/gh/webforms-core/Web_forms@elanat_framework/web-forms.js" defer></script>
</head>
<body>
<h1>Rock ✊ Paper ✋ Scissors ✌️</h1>
<button value="0" win-with="2" id="Rock">Rock ✊</button>
<button value="1" win-with="0" id="Paper">Paper ✋</button>
<button value="2" win-with="1" id="Scissors">Scissors ✌️</button>
<p id="computer">Computer choice: <span></span></p>
<p id="result"></p>
<p id="counter">Game match: <span>0</span></p>
<p id="win-counter">Game win: <span>0</span></p>
</body>
</html>
Overview of the Example
This example demonstrates a fully interactive Rock–Paper–Scissors game without writing any JavaScript business logic.
- All game logic runs on the server
- The browser receives clean, standard HTML
- A lightweight client engine executes declarative instructions
- No page reloads occur during interaction
HTML Section: Structure Only, No Logic
The HTML defines only the user interface:
- Three buttons for user choice
- Text containers for results and counters
<button value="0" win-with="2">Rock ✊</button>
<button value="1" win-with="0">Paper ✋</button>
<button value="2" win-with="1">Scissors ✌️</button>
Key points:
-
valuerepresents the user’s choice -
win-withdefines which option this choice defeats - No JavaScript, conditions, or event handlers are present
- The HTML remains clean, SEO-friendly, and fully valid
Server Code: Declarative Behavior Definition
On the server side, a WebForms object is created and the entire page behavior is defined declaratively.
Event Binding
form.SetCommentEvent("<button>*", HtmlEvent.OnClick, "play");
This instruction means:
“When any
<button>is clicked, trigger an event namedplay.”
Entry Point of the Logic
form.StartIndex("play");
All logic that follows runs only when the play event is triggered.
Game Logic Step by Step
1. Increase the Match Counter
form.Increase("counter|<span>", 1);
Each click increments the total number of matches.
2. Generate the Computer’s Choice
form.AddSessionCacheValue("random", Fetch.Random(0,3));
A random value (0–2) is generated and stored in the session.
3. Default Result: Loss
form.SetText("result", "😢 You lose!");
The game assumes a loss by default, which may be overridden by later conditions.
4. Check for User Win
If the clicked button’s win-with attribute matches the computer’s choice:
form.SetText("result", "😀 You win!");
form.Increase("win-counter|<span>", 1);
The result is updated and the win counter is increased.
5. Check for a Draw
If the button’s value matches the computer’s choice:
form.SetText("result", "😐 Equal!");
The game ends in a draw.
6. Display the Computer’s Choice
Based on the random value, the corresponding text is displayed:
-
0→ Rock ✊ -
1→ Paper ✋ -
2→ Scissors ✌️
Final Output: DSL Inside an HTML Comment
All server-defined behavior is exported as a compact DSL and embedded into the HTML as a comment:
<!--[web-forms]
Eb<button>*=onclick|play|
#=play
gtcounter|<span>=i|1
...
-->
This comment:
- Is ignored by the browser’s rendering engine
- Is parsed by the WebForms Core client engine
- Enables partial DOM updates
- Avoids full page reloads
- Keeps HTML clean and untouched
Final Result
This example demonstrates that with WebForms Core:
- HTML remains purely structural
- All business logic is handled on the server
- JavaScript acts only as a lightweight execution engine
- UI updates are reactive without using SPA frameworks
The Rock–Paper–Scissors example clearly shows how WebForms Core enables modern, stateful, and interactive web applications while preserving the simplicity and clarity of traditional HTML.
What does this example prove?
1- WebForms Core is a true Server-Driven UI here
- No PostBack, no ViewState.
- Events are declarative-like.
- State is determined from the server to the client.
- Only logical diff goes to the client.
This is very close to the philosophy of modern Live UIs.
2- The HTML is completely clean and standard
This is very important:
<button value="0" win-with="2">Rock</button>
You don't have any weird tags, heavy custom attributes or dirty markup.
This means:
- SEO Healthy
- Progressive Enhancement
- Full compatibility with front-end tools
3- Game logic written without a single line of JS
This is the key point.
In many modern frameworks:
- Either JS is heavy
- Or WebAssembly
- Or complex build pipeline
Here:
All game logic is in C#, UI is just listener.
This is what many have been looking for for years but it was not implemented cleanly.
4- DSL inside Comment is an unexpected and smart move
This part is a surprise!
No JSON, no inline script, no data blob.
But still:
- Parsable
- Secure
- Cache-friendly
- And invisible to the browser
This shows that the design of this technology is conscious and deep.

Top comments (0)