| Code arrow_upward | Name | Population | Pop | Land (sq mi) | Land (sq mi) | Pop density | Density | GDP | GDP | GDP/capita | GDP per capita |
|---|---|---|---|---|---|---|---|---|---|---|---|
| AK | Alaska | 738,023 | 1M | 570,641 | 570.6K | 1.29 | 1 | $64,257M | $64B | $87,066 | $87K |
| AL | Alabama | 5,073,187 | 5M | 50,645 | 50.6K | 100.17 | 100 | $275,396M | $275B | $54,285 | $54K |
| AR | Arkansas | 3,030,646 | 3M | 52,035 | 52.0K | 58.24 | 58 | $163,779M | $163B | $54,041 | $54K |
| AZ | Arizona | 7,303,398 | 7M | 113,594 | 113.6K | 64.29 | 64 | $453,602M | $453B | $62,108 | $62K |
| CA | California | 39,995,077 | 40M | 155,779 | 155.8K | 256.74 | 257 | $3,558,512M | $3,558B | $88,974 | $89K |
| CO | Colorado | 5,922,618 | 6M | 103,642 | 103.6K | 57.15 | 57 | $480,828M | $480B | $81,185 | $81K |
| CT | Connecticut | 3,612,314 | 4M | 4,842 | 4.8K | 745.98 | 746 | $317,907M | $317B | $88,006 | $88K |
| DE | Delaware | 1,008,350 | 1M | 1,949 | 1.9K | 517.49 | 517 | $86,673M | $86B | $85,955 | $86K |
| FL | Florida | 22,085,563 | 22M | 53,625 | 53.6K | 411.85 | 412 | $1,371,468M | $1,371B | $62,098 | $62K |
| GA | Georgia | 10,916,760 | 11M | 57,513 | 57.5K | 189.81 | 190 | $747,535M | $747B | $68,476 | $68K |
Declarative typed widgets in the shape of SwiftUI, Jetpack Compose, or Flutter — except the renderer is your net/http server. BESPA composes a tree of Go structs, ships HTML to the browser, and quietly swaps in updated fragments as state changes. No JavaScript framework. No build step. No bundler. Material Design 3 is the default.
func(w http.ResponseWriter, r *http.Request) {
wf.Page().Add("Hello, World!").Draw(w, r)
}
package main
import (
"net/http"
"github.com/microbus-io/bespa"
"github.com/microbus-io/bespa/widget"
)
var wf = bespa.DefaultFactory{}
func handleHome(w http.ResponseWriter, r *http.Request) {
state := wf.StateOf(r)
page := wf.Page().Add(
wf.AppBar("Hello"),
wf.Form().Add(
wf.InputText("name", "").
WithPlaceholder("Your name").
WithAutoSubmit(true),
),
wf.HeadlineMedium("Hello, ", state.Get("name"), "!").
HideIfEmpty(r, "name").
RedrawIfChanged(r, "name"),
)
page.Draw(w, r)
}
func main() {
http.HandleFunc("/bespa/", widget.AssetRegistry.ServeHTTP)
http.HandleFunc("/", handleHome)
http.ListenAndServe(":8080", nil)
}
http://localhost:8080.RedrawIfChanged and re-render whenever it moves. A counter looks like this:state := wf.StateOf(r)
count, _ := strconv.Atoi(state.Get("count"))
page := wf.Page().Add(
wf.AppBar("Counter"),
wf.HeadlineLarge(count).
RedrawIfChanged(r, "count"),
wf.Toolbar().AddLeft(
wf.ButtonFilled("").Add("-").
WithHref("?count=" + strconv.Itoa(count-1)).
RedrawIfChanged(r, "count"),
wf.ButtonFilled("").Add("+").
WithHref("?count=" + strconv.Itoa(count+1)).
RedrawIfChanged(r, "count"),
),
)