| Crates.io | forge-rsx |
| lib.rs | forge-rsx |
| version | 0.1.0 |
| created_at | 2026-01-23 20:04:41.542678+00 |
| updated_at | 2026-01-23 20:04:41.542678+00 |
| description | A Rust macro library for declarative, JSX-like HTML generation. It allows you to write HTML structures with embedded logic, attributes, nested tags, loops, and more, directly in Rust code with a concise syntax. |
| homepage | https://github.com/dr-montasir/forge-rsx |
| repository | https://github.com/dr-montasir/forge-rsx |
| max_upload_size | |
| id | 2065382 |
| size | 23,889 |
forge-rsx is a Rust macro library for declarative, JSX-like HTML generation. It allows you to write HTML structures with embedded logic, attributes, nested tags, loops, and more, directly in Rust code with a concise syntax.
rsx! macroRun the following Cargo command in your project directory:
cargo add forge-rsx
Or add forge-rsx as a dependency in your Cargo.toml:
[dependencies]
forge-rsx = "MAJOR.MINOR.PATCH" # Replace with the latest version
In your Rust code, import the macro:
use forge_rsx::rsx;
lined: produces HTML without indentation or line breaks (single-line output)btfy0: uses 0 spaces (no indentation, minified output)btfy2: Indentation with 2 spaces per level.btfy4: Indentation with 4 spaces per level.rsx!(btfy0, div { "No indentation" });
rsx!(btfy2, div { "Indented with 2 spaces" });
rsx!(btfy4, div { "Indented with 4 spaces" });
let greeting = rsx!(lined, span { "Hello, World!" });
println!("{}", greeting);
let nested_html = rsx!(lined, div {
header {
span { "Navigation" }
}
section {
p { "Welcome to the forge-rsx template!" }
}
});
println!("{}", nested_html);
let button_html = rsx!(lined, button {
class: "btn-primary",
"data-toggle": "modal",
"Click me!"
});
println!("{}", button_html);
let users = vec!["Ahmed", "Mohamed", "Montasir"];
let list_html = rsx!(lined, ul {
for user in &users => {
li { { format!("User: {}", user) } }
}
});
println!("{}", list_html);
use forge_rsx::{rsx, get_char};
fn main() {
let apple = "🍎 Apple";
let apple_component = rsx!(lined, span { {&apple} });
let fruits = vec!["🍇", "mango", "orange"];
let div = rsx!(btfy4, div { "..."
{"<!-- How to use attributes with hyphens, like x-show in Alpine.js -->"}
span {
id: "my-id",
class: "my-class",
"x-show": "",
":class": "p-4",
"..."
}
"..."
});
let span = rsx!(btfy0, span { "..." });
let empty_p = rsx!(btfy2, p { });
let p = rsx!(btfy2, p {"..."});
let section = rsx!(btfy4, section { div { ol {
for fruit in &fruits => {
li {
span {
{
if fruit == &"🍇" {
&format!("{} {}", fruit.to_string(), "Grapes")
} else if fruit == &"mango" {
&format!("{} {}", "🥭", fruit.to_lowercase())
} else {
&fruit.to_uppercase()
}
}
}
}
}
li {
{"<!-- How to join RSX component -->"}
{&apple_component.to_string()}
{
if get_char(&apple, 1).to_string() == "🍎" {
"🍎".to_string()
} else {
apple_component.to_string()
}
}
}
} } });
println!(
"{}\n\n{}\n\n{}\n\n{}\n\n{}",
div, span, empty_p, p, section
);
// <div>
// ...
// <!-- How to use attributes with hyphens, like x-show in Alpine.js -->
// <span id="my-id" class="my-class" x-show='' :class='p-4'>
// ...
// </span>
// ...
// </div>
//
// <span>
// ...
// </span>
//
// <p></p>
//
// <p>
// ...
// </p>
//
// <section>
// <div>
// <ol>
// <li>
// <span>
// 🍇 Grapes
// </span>
// </li>
// <li>
// <span>
// 🥭 mango
// </span>
// </li>
// <li>
// <span>
// ORANGE
// </span>
// </li>
// <li>
// <!-- How to join RSX component -->
// <span>🍎 Apple</span>
// 🍎
// </li>
// </ol>
// </div>
// </section>
}
MIT License
{} can contain any Rust expression that implements Display.