A new option for building interactive web interfaces has arrived in the Rust ecosystem. WebForms Core is a technology owned and developed by Elanat . It now has a Rust implementation available as the webformscore crate, allowing Rust developers to use the WebForms Core programming model with Rust web frameworks such as Actix Web. What is WebForms Core? WebForms Core is a server-orchestrated UI technology in which the server generates commands that describe changes and actions to be performed on the HTML document. At the center of the server side is the WebForms class . In Rust, the WebForms class generates WebForms Core commands. On the browser side, WebFormsJS receives those commands and executes them against the HTML DOM. The basic architecture is: Rust Server ↓ WebForms Class ↓ WebForms Core Commands ↓ WebFormsJS ↓ HTML DOM This creates a clear separation between the server-side Commander and the browser-side Executor. The Rust application does not directly manipulate the browser DOM. Instead, it generates commands, while WebFormsJS performs the corresponding DOM operations in the browser. WebFormsJS is independent of the Rust backend and can work with different server-side implementations of WebForms Core. The WebFormsJS project is available in the official WebForms Core repository. Installing WebForms Core for Rust The Rust implementation is available as the webformscore crate. Install it using Cargo CLI: cargo add webformscore Alternatively, add it manually to your Rust project's Cargo.toml : [dependencies] webformscore = "2.1.0" Then import the WebForms class and the HTML event definitions: use webformscore ::{ WebForms , html_event }; The webformscore 2.1.0 crate provides the Rust implementation of the WebForms class for WebForms Core. Installing WebFormsJS WebFormsJS is the browser-side runtime of WebForms Core. It is installed separately from the Rust crate. Option 1: npm If you use npm, install WebFormsJS with: npm install webformsjs The official WebFormsJS repository also documents npm installation. After installation, make the web-forms.js file available through your web server and include it in the HTML: Option 2: GitHub repository If you do not want to install WebFormsJS through npm, the source is available from the official repository: WebFormsJS repository The repository contains the WebFormsJS source and the web-forms.js file. For a Rust web application, you can place the required JavaScript file under your static directory, for example: static/ └── script/ └── web-forms.js and reference it from the HTML page: Option 3: Elanat Website Go to the link below and download the corresponding version of WebFormsJS. https://elanat.net/page_content/web_forms_js A Rust + Actix Web Example Let's build a simple example using Actix Web , Tera , webformscore , and WebFormsJS. The application displays a table of student grades. When the user clicks Highlighting student grades , the browser sends a request to the Rust server. The server then generates WebForms Core commands that color the table cells according to their grades. Here is the Rust server: use actix_files as fs ; use actix_web ::{ web , App , HttpServer , HttpResponse , Responder }; use std :: sync :: Arc ; use tera :: Tera ; use webformscore ::{ WebForms , html_event }; #[derive(Clone)] struct AppState { tera : Arc < Tera > , } #[actix_web::main] async fn main () -> std :: io :: Result < () > { let tera = Tera :: new ( "templates/**/" ) .unwrap (); let state = AppState { tera : Arc :: new ( tera ), }; HttpServer :: new ( move || { let state = state .clone (); App :: new () .app_data ( web :: Data :: new ( state )) .route ( "/" , web :: get () .to ( index )) .route ( "/set-background-color" , web :: get () .to ( handle_event )) .service ( fs :: Files :: new ( "/static" , "./static" ) .show_files_listing ()) }) .bind ( "127.0.0.1:8080" ) ? .run () .await } async fn index ( state : web :: Data < AppState > ) -> impl Responder { let rendered = match state .tera .render ( "index.html" , & tera :: Context :: new ()) { Ok ( html ) => html , Err ( e ) => { eprintln! ( "Template error: {}" , e ); return HttpResponse :: InternalServerError () .content_type ( "text/plain" ) .body ( format! ( "Template error: {}" , e )); } }; let mut form = WebForms :: new (); form .set_get_event ( "HighlightingGrades" , html_event :: ON_CLICK , Some ( "/set-background-color" ), ); let body = format! ( "{}{}" , rendered , form .export_to_html_comment ( Some ( true )) ); HttpResponse :: Ok () .content_type ( "text/html; charset=utf-8" ) .body ( body ) } async fn handle_event ( _state : web :: Data < AppState > ) -> impl Responder { let mut form = WebForms :: new (); form .set_background_color ( "?t>:19 \ ?t<:20" , "darkgreen" , ); form .add_style_with_name_value ( "-" , "font-weight" , "bold" , ); form .set_text_color ( "-" , "white" ); form .set_background_color ( "?t>:17 \ ?t<19" , "green" , ); form .set_background_color ( "?t>:14 \ ?t<17" , "lightgreen" , ); form .set_background_color ( "?t>:10 \ ?t<14" , "khaki" , ); form .set_background_color ( "?t>:6 \ ?t<10" , "orange" , ); form .set_background_color ( "?t>:3 \ ?t<6" , "red" , ); form .set_background_color ( "?t>:0 \ ?t<3" , "darkred" , ); form .message_i32 ( "The student's grades were successfully highlighted!" , "success" , 5000 , ); HttpResponse :: Ok () .content_type ( "text/html; charset=utf-8" ) .body ( form .response ()) } The HTML View The Tera template is a normal HTML document. No React component, JSX, or special WebForms Core markup is required. Using WebForms Core td { border : 2px solid #aaa ; padding : 5px ; text-align : center ; } Highlighting student grades
| Student Name | Math | Science | English | History | Geography | Average |
|---|---|---|---|---|---|---|
| Emily Johnson | 18 | 17 | 19 | 16 | 12 | 16.4 |
| Michael Smith | 15 | 16 | 14 | 17 | 15 | 15.4 |
| Sarah Davis | 20 | 19 | 18 | 19 | 20 | 19.2 |
| David Brown | 8 | 9 | 7 | 6 | 5 | 7.0 |
| Jessica Wilson | 17 | 18 | 16 | 18 | 17 | 17.2 |
| Daniel Martinez | 4 | 3 | 5 | 7 | 6 | 5.0 |
| Ashley Taylor | 19 | 20 | 17 | 18 | 19 | 18.6 |
| Christopher Lee | 9 | 8 | 7 | 13 | 4 | 8.2 |
| Kevin Anderson | 7 | 10 | 12 | 2 | 8 | 7.8 |
| Laura Thomas | 3 | 7 | 6 | 4 | 9 | 5.8 |
| Brian White | 10 | 8 | 7 | 9 | 6 | 8.0 |
| Megan Harris | 7 | 5 | 3 | 8 | 4 | 5.4 |


