Bulma-Templ

A type-safe, SSR-first Bulma component library for Go using Templ.
Provides 1:1 mappings of Bulma CSS components with explicit composition and zero internal state.
@Button(
ButtonProps{Color: "is-primary", Size: "is-large"},
Items{Html("Get Started")},
)
Features
- ✅ Complete Bulma coverage — All elements, components, forms, and layouts
- ✅ Type-safe — Props structs with IDE autocomplete
- ✅ SSR-first — No JavaScript required for rendering
- ✅ Zero state — Pure rendering functions
- ✅ Explicit composition — Multi-child
Items pattern
- ✅ Escape hatch —
Attr for custom attributes and Alpine.js
- ✅ Stable v1.0 — Frozen architecture, no breaking changes
Quick Start
Installation
go get github.com/mtzvd/bulma-templ
That's it! Generated templ files are included in the repository.
Requirements
- Go 1.25+
- Bulma CSS (via CDN or bundled)
Basic Example
package main
import "github.com/mtzvd/bulma-templ/elements"
templ Page() {
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@1.0.0/css/bulma.min.css">
</head>
<body>
@elements.Button(
elements.ButtonProps{Color: "is-primary"},
elements.Items{elements.Html("Click Me")},
)
</body>
</html>
}
Examples
// Primary button
@elements.Button(
elements.ButtonProps{Color: "is-primary", Size: "is-large"},
elements.Items{elements.Html("Primary")},
)
// With loading state
@elements.Button(
elements.ButtonProps{Color: "is-info", IsLoading: true},
elements.Items{elements.Html("Loading...")},
)
Card
@components.Card(
components.CardProps{},
components.Items{
components.CardHeader(
components.CardHeaderProps{},
components.Items{
components.CardHeaderTitle(
components.Items{elements.Html("Card Title")},
),
},
),
components.CardContent(
components.Items{
elements.Content(
elements.ContentProps{},
elements.Items{elements.Html("<p>Card content</p>")},
),
},
),
},
)
@form.Field(
form.FieldProps{},
form.Items{
form.Label(
form.LabelProps{},
form.Items{elements.Html("Email")},
),
form.Control(
form.ControlProps{},
form.Items{
form.Input(
form.InputProps{
Type: "email",
Placeholder: "user@example.com",
},
),
},
),
},
)
Alpine.js Integration
@elements.Button(
elements.ButtonProps{
Color: "is-primary",
Attr: templ.Attributes{
"x-on:click": "alert('Clicked!')",
},
},
elements.Items{elements.Html("Interactive")},
)
Philosophy
Bulma-Templ is intentionally conservative.
- 1:1 Bulma mapping — No abstractions, no re-interpretation
- Explicit composition — Multi-child
Items pattern
- Zero state — Components render HTML only
- Type-safe — Compile-time validation
- Stable — v1.0 architecture frozen
What this is:
- Type-safe Bulma components for Go/Templ
- Predictable HTML output
- Foundation for server-rendered UIs
What this is NOT:
- UI framework with routing/state
- JavaScript component library
- Theme engine or CSS abstraction
Component API
Every component follows this pattern:
templ ComponentName(props ComponentNameProps, content Items)
Props struct — Configuration via typed struct with Bulma modifiers
Items — Multi-child composition model ([]templ.Component)
Attr — Escape hatch for custom attributes (Alpine.js, ARIA, etc.)
Example Props:
type ButtonProps struct {
Color string // is-primary, is-link, etc.
Size string // is-small, is-medium, is-large
Disabled bool // Disabled state
Attr templ.Attributes // Escape hatch
}
Available Components
Elements
block, box, button, content, delete, icon, image, notification, progress, skeleton, table, tag, title
Components
breadcrumb, card, dropdown, menu, message, modal, navbar, pagination, panel, tabs
checkbox, control, field, file, help, input, label, radio, select, textarea
Layout
container, footer, hero, level, media, section
Columns
columns, column
Grid
grid
Documentation
Development
Quick Start
Note: *_templ.go files are generated and tracked in git for pkg.go.dev compatibility.
For contributors: If you modify .templ files, regenerate with task templ before committing.
task templ # Generate Templ files (after modifying .templ files)
task run # Run dev server
task test # Run tests
Testing
The project has 183 tests with 80.9% coverage for core packages, covering:
- Infrastructure primitives (Wrap, BaseElement, Items)
- Components with conditional logic (Progress, Navbar, Modal, Dropdown, Form inputs)
- Smoke tests for thin wrapper components
# Run all tests
go test ./...
# Run tests with race detection
go test ./... -race
# Run tests for specific package
go test ./elements -v
go test ./components -v
go test ./form -v
CI/CD
All pull requests automatically run:
- ✅ Full test suite with race detection and coverage reporting
- ✅
templ generate verification (ensures generated files build correctly)
- ✅ Kitchen Sink and example compilation checks
- ✅ Multi-OS build verification (Linux, Windows, macOS)
- ✅
go vet and gofmt formatting checks
- ✅ golangci-lint static analysis
Project Status
Version 1.0 — Architecture is frozen. No breaking changes will be introduced.
All core Bulma components are implemented and stable. Future work focuses on documentation, examples, and community support.
Contributing
Contributions are welcome! Please read CONTRIBUTING.md before submitting PRs.
What's welcome:
- Bug fixes
- Documentation improvements
- Test coverage
- Examples
- Accessibility enhancements
What's out of scope:
- New components (beyond Bulma)
- Framework-specific integrations
- State management
- Routing
License
MIT © 2026 mtzvd
Acknowledgments
- Bulma by Jeremy Thomas
- Templ by Joe Davidson
- Inspired by the Go and HTMX communities