| Crates.io | webrust |
| lib.rs | webrust |
| version | 2.0.0 |
| created_at | 2025-07-08 22:56:26.22699+00 |
| updated_at | 2025-11-01 14:59:58.701499+00 |
| description | Python-like Rust for Web Applications - A bridge between Python simplicity and Rust power |
| homepage | https://github.com/gerarddubard/webrust |
| repository | https://github.com/gerarddubard/webrust |
| max_upload_size | |
| id | 1743694 |
| size | 408,649 |
Python-like Rust for Web Applications – A bridge between Python's simplicity and Rust's power.
Write a single .rs file and instantly see interactive charts, tables, animations, and LaTeX in your browser. No HTML, CSS, or JavaScript required.
use webrust::prelude::*;
#[gui]
fn main() {
println("<white !green r8 p6 w480 h50>Hello, WebRust !").align("center");
let sales = vec![120.0, 200.0, 150.0, 300.0, 250.0];
bar(&["Jan", "Feb", "Mar", "Apr", "May"], &sales);
}
Run with cargo run – browser opens automatically at http://127.0.0.1:8080.
[dependencies]
webrust = "2.0.0"
<red b !white> syntax$(E = mc^2)WebRust supports two coordinate modes that affect all positioning operations.
| Mode | Origin | Description |
|---|---|---|
coord("css") |
Top-left (0, 0) | Default. +y increases downward |
coord("cartesian") |
Center (0, 0) | Mathematical coordinates. +y increases upward |
use webrust::prelude::*;
#[gui]
fn main() {
coord("css"); // Default mode
print("Top-left").at(0.0, 0.0);
print("bottom-right").at(*TW + 40, *TH - 20);
coord("cartesian"); // Switch to center origin
print("Center").at(0.0, 0.0);
}
| Method | Description |
|---|---|
print(text) |
Print inline (no newline) |
println(text) |
Print with newline |
.at(x, y) |
Position absolutely |
.align("left" | "center" | "right") |
Text alignment |
.sticky() |
Keep visible on scroll (with .at()) |
Format: <attributes>content</>
| Tag | Description | Example |
|---|---|---|
<color> |
Text color | <red>, <blue>, <darkgreen> |
!color |
Background color | <white !navy>, <black !gold> |
b |
Bold | <red b> |
i |
Italic | <blue i> |
u |
Underline | <green u> |
s |
Strikethrough | <gray s> |
14 |
Font size (px) | <red 18> |
Courier New |
Font family | <Courier New> (use _ for spaces) |
| Tag | Description | Example |
|---|---|---|
t2 |
Border thickness | <t2>, <t3> |
|color |
Border color | <|red>, <|blue> |
solid, dashed, dotted, double |
Border style | <dashed> |
r8 |
Border radius | <r8>, <r10> |
w200 |
Width (px) | <w200>, <w{*TW}> |
h50 |
Height (px) | <h50> |
p6 |
Padding (all sides) | <p6> |
m10 |
Margin (all sides) | <m10> |
pt8, pb12 |
Padding top/bottom | <pt8>, <pb12> |
pl5, pr15 |
Padding left/right | <pl5>, <pr15> |
mt10, mb20 |
Margin top/bottom | <mt10>, <mb20> |
ml5, mr15 |
Margin left/right | <ml5>, <mr15> |
| Style | Description |
|---|---|
B |
Bottom border only |
T |
Top border only |
L |
Left border only |
R |
Right border only |
H |
Horizontal (top + bottom) |
V |
Vertical (left + right) |
| Tag | Description |
|---|---|
tl |
Top-left |
tc |
Top-center |
tr |
Top-right |
ml |
Middle-left |
mc |
Middle-center (default) |
mr |
Middle-right |
bl |
Bottom-left |
bc |
Bottom-center |
br |
Bottom-right |
j |
Justify text |
| Constant | Description |
|---|---|
{*TW} |
Total width / 2 |
{*TH} |
Total height / 2 |
{*CW} |
Content width (TW - 40) |
{*CH} |
Content height (TW - 40) |
Syntax: $(expression)
println(r"Einstein: $(E = mc^2)");
println(r"Quadratic: $(x = \frac{-b \pm \sqrt{b^2-4ac}}{2a})");
| Function | Description | Signature |
|---|---|---|
line |
Line chart (category axis) | line(&[&str], &[f64]) |
line_xy |
Line chart (numeric x,y) | line_xy(&[f64], &[f64]) |
curve |
Smooth curve (category) | curve(&[&str], &[f64]) |
curve_xy |
Smooth curve (numeric x,y) | curve_xy(&[f64], &[f64]) |
area |
Area chart (category) | area(&[&str], &[f64]) |
area_xy |
Area chart (numeric x,y) | area_xy(&[f64], &[f64]) |
bar |
Bar chart | bar(&[&str], &[f64]) |
scatter |
Scatter plot | scatter(&[f64], &[f64]) |
pie |
Pie chart | pie(&[&str], &[f64]) |
doughnut |
Doughnut chart | doughnut(&[&str], &[f64]) |
radar |
Radar chart | radar(&[f64], &[(&str, f64)]) |
gauge |
Gauge meter (0-100) | gauge(f64) |
funnel |
Funnel chart | funnel(&[(&str, f64)]) |
matrix |
Heatmap | matrix(&[Vec<f64>], &[&str], &[&str]) |
treemap |
Treemap (flat or hierarchical) | treemap(&[(&str, f64)]) |
tree |
Tree diagram | tree(&[&str]) or tree(&serde_json::Value) |
function |
Function plot | function(impl Fn(f64)->f64, f64, f64, f64) |
| Method | Description |
|---|---|
.at(x, y) |
Position chart |
.size(width, height) |
Dimensions in percentage |
use webrust::prelude::*;
#[gui]
fn main() {
let months = vec!["Jan", "Feb", "Mar", "Apr", "May"];
let sales = vec![120.0, 200.0, 150.0, 300.0, 250.0];
line(&months, &sales);
pie(&["A", "B", "C"], &[45.0, 30.0, 25.0]);
}
table(&data) // Accepts: arrays, matrices, structs, nested objects
| Method | Description |
|---|---|
.header(&[...]) |
Set column headers (supports LaTeX) |
.pivot() |
Transpose rows and columns |
.merge() |
Merge consecutive identical cells |
.sort() |
Enable multi-column sorting (shift+click) |
.filter() |
Enable global search/filter |
.paginate() |
Enable pagination (default 10 rows) |
.page_size(n) |
Set rows per page |
.at(x, y) |
Position table |
.size(w, h) |
Set dimensions in pixels |
.align("left" | "center" | "right") |
Alignment |
use webrust::prelude::*;
#[gui]
fn main() {
let data = vec![vec![1, 2, 3], vec![4, 5, 6]];
table(&data)
.header(["$(x)", "$(y)", "$(z)"])
.pivot()
.header(["Row 1", "Row 2"]);
}
let obj = object(); // Create drawable object
let grp = group(); // Create object group
| Method | Description |
|---|---|
.color(color) |
Set stroke color |
.fill(color) |
Set fill color |
.width(w) |
Set line width |
.dash(down, up) |
Set dash pattern |
.at(x, y) |
Set position |
.pos() |
Get current position (f64, f64) |
.to(angle) |
Set pen angle (degrees) |
.angle() |
Get current angle |
.left(angle) |
Turn left |
.right(angle) |
Turn right |
.forward(distance) |
Move forward |
.backward(distance) |
Move backward |
.penup() |
Lift pen (no drawing) |
.pendown() |
Lower pen (drawing) |
| Method | Description |
|---|---|
.point(x, y) |
Draw point |
.line(x1, y1, x2, y2) |
Draw line |
.circle(radius) |
Draw circle |
.arc(radius, sweep_angle) |
Draw arc |
.ellipse(rx, ry) |
Draw ellipse |
.rectangle(length, width) |
Draw rectangle |
.square(side) |
Draw square |
.rhombus(side, angle) |
Draw rhombus |
.parallelogram(len, width, angle) |
Draw parallelogram |
.polygon(points) |
Draw polygon Vec<[f64; 2]> |
| Method | Description |
|---|---|
.speed(px_per_sec) |
Set animation speed |
.ease(name) |
Set easing function |
.translate(dx, dy) |
Animate translation |
.rotate(angle) |
Animate rotation |
.scale(sx, sy) |
Animate scaling |
.reflect(axis) |
Mirror ("x", "y", or "xy") |
.reverse() |
Reverse animation |
.wait(ms) |
Wait duration |
linear, sineIn, sineOut, sineInOut, quadIn, quadOut, quadInOut, cubicIn, cubicOut, cubicInOut, quartIn, quartOut, quartInOut, quintIn, quintOut, quintInOut, expoIn, expoOut, expoInOut, circIn, circOut, circInOut, backIn, backOut, backInOut, elasticIn, elasticOut, elasticInOut, bounceIn, bounceOut, bounceInOut
| Method | Description |
|---|---|
.add(&object) |
Add object to group |
.remove(&object) |
Remove object from group |
.translate(dx, dy) |
Animate group translation |
.rotate(angle) |
Animate group rotation |
.scale(sx, sy) |
Animate group scaling |
.ease(name) |
Set easing for group |
.reverse() |
Reverse group animation |
.wait(ms) |
Wait duration |
use webrust::prelude::*;
#[gui]
fn main() {
let ball = object();
ball.color("red").fill("tomato").at(100.0, 50.0).circle(20.0);
ball.ease("bounceOut").speed(140.0).translate(0.0, 200.0);
}
| Function | Description |
|---|---|
grid(rows, cols) |
Create grid layout |
cell(row, col, anchor) |
Get cell coordinates (f64, f64) |
size_pct(w_pct, h_pct) |
Get size in pixels from percentage |
| Constant | Description |
|---|---|
*CW |
Cell width |
*CH |
Cell height |
"top left" / "tl", "top center" / "tc", "top right" / "tr",
"middle left" / "ml", "center" / "mc", "middle right" / "mr",
"bottom left" / "bl", "bottom center" / "bc", "bottom right" / "br",
"left", "right", "top", "bottom"
Applied to charts and tables for grid integration:
chart.size(80, 90) // 80% of cell width, 90% of cell height
use webrust::prelude::*;
#[gui]
fn main() {
grid(1, 2);
let (cx, cy) = cell(0, 0, "center");
print("<white !navy r3 p1>cell (0,0)").at(cx, cy);
let (cx, cy) = cell(0, 1, "top-right");
bar(&["A", "B"], &[10.0, 20.0]).at(cx, cy).size(80, 80);
}
Enable with: webrust = { version = "2.0.0", features = ["sql"] }
query(sql_string) // Execute SQL and display results as table
Supports DuckDB features: window functions, CTEs, JSON operations, aggregates, joins.
use webrust::prelude::*;
#[gui]
fn main() {
query("CREATE TABLE sales(product TEXT, amount REAL)");
query("INSERT INTO sales VALUES ('Laptop', 999), ('Mouse', 25)");
query("SELECT product, amount FROM sales ORDER BY amount DESC");
}
SQL queries → Python (pandas) → Plotly → Flask → Deploy
↓ ↓ ↓ ↓ ↓
Context Type loss Boilerplate Frontend Infrastructure
vs
Rust (WebRust) → Browser (automatic)
↓ ↓
Type safety Rich visualization
Performance Zero deployment
Single file, single language, instant visualization.
memchr/memmem for fast string parsingSmallVec<[Cell; 12]>)compact feature reduces string allocations[features]
default = ["rwlock"]
sql = ["duckdb"] # Enable SQL analytics
compact = ["compact_str"] # Use compact string representation
rwlock = [] # Use RwLock for concurrent reads (default)
To use Mutex instead of RwLock:
webrust = { version = "2.0.0", default-features = false }
Run with cargo run --example <name>:
| Example | Description |
|---|---|
simpleio |
Basic I/O operations |
advancedio |
Advanced formatting |
latexio |
LaTeX rendering |
string |
String manipulation |
utils |
Utility functions |
table |
Table operations |
chart |
All 17+ chart types |
turtle |
Graphics & animation |
mixed |
Complete dashboard |
dyntable |
Dynamic tables |
simplesql |
Basic SQL |
advancedsql |
Advanced SQL |
!<color> syntaxparking_lotrwlock feature for concurrent readsSee CHANGELOG.md for complete details.
MIT License – see LICENSE for details.
WebRust is built upon excellent open-source projects:
Made with ❤️ for Rustaceans who miss Python's simplicity but crave Rust's power.