UI Library built for the Sonr ecosystem. It leverages Templ, TailwindCSS 4, and Shoelace Web Components.
- 40+ UI Components: Comprehensive set of pre-built components (buttons, cards, forms, charts, etc.)
- TailwindCSS 4: Modern CSS framework for rapid UI development
- Shoelace Web Components: Customizable and extensible web components
- Templ: Type-safe Go HTML template engine
- HTTP Middleware: Built-in asset serving for JavaScript and CSS
- Zero Configuration: CDN-based dependencies, no local build required
- Integrated Build Process: Automated TailwindCSS and Templ generation
- Flexible Asset Serving: Embedded or local filesystem modes via build tags
- go:generate Support: Standard Go toolchain integration
go get github.com/go-sonr/uiIf you're contributing or need to regenerate assets:
# Install build tools
go run github.com/go-sonr/ui/build.go -install-deps
# Or if you have the module cloned
cd $GOPATH/src/github.com/go-sonr/ui
make install-depsWhen using this module as a dependency in your project, all assets are pre-built and embedded. No additional build steps are required:
import "github.com/go-sonr/ui"The module includes:
- Pre-generated Go code from Templ templates
- Minified CSS from TailwindCSS
- Embedded JavaScript assets
- All components ready to use
package main
import (
"net/http"
ui "github.com/go-sonr/ui"
)
func main() {
mux := http.NewServeMux()
// Setup asset serving
ui.ServeAssets(mux)
// Add your routes
mux.HandleFunc("/", homeHandler)
http.ListenAndServe(":8080", mux)
}package main
import (
"net/http"
ui "github.com/go-sonr/ui"
)
func main() {
// Wrap your existing handler with UI middleware
handler := ui.Middleware(yourHandler)
http.ListenAndServe(":8080", handler)
}The library provides 40+ components organized in categories:
- Forms: button, input, textarea, checkbox, radio, selectbox, inputotp
- Layout: card, accordion, tabs, sidebar, separator, sheet
- Data: table, chart, pagination
- Feedback: alert, toast, dialog, tooltip, popover
- Navigation: breadcrumb, dropdown
- Display: avatar, badge, progress, skeleton, rating
Returns a handler for serving embedded JavaScript assets.
- Mount at
/assets/js/to match component expectations - Serves minified JavaScript files for components
Returns a handler for serving embedded CSS assets.
- Mount at
/assets/css/to match component expectations - Serves CSS files including generated Tailwind CSS
Wraps an existing handler to automatically serve UI assets.
- Intercepts requests to
/assets/js/*and/assets/css/* - Passes through all other requests
Convenience function to setup asset serving on a ServeMux.
Alternative name for Middleware() for clarity.
Adds security headers including:
- Content Security Policy (CSP) for CDN resources
- X-Content-Type-Options
- X-Frame-Options
- X-XSS-Protection
- Referrer-Policy
Adds preload headers for CDN resources to improve initial page load.
Adds cache control headers for static assets.
Build with tag: go build -tags chi
import (
"github.com/go-chi/chi/v5"
ui "github.com/go-sonr/ui"
)
func main() {
r := chi.NewRouter()
// Option 1: Configure router
ui.ChiRouter(r)
// Option 2: Use middleware
r.Use(ui.ChiMiddleware())
r.Get("/", homeHandler)
http.ListenAndServe(":8080", r)
}Build with tag: go build -tags gin
import (
"github.com/gin-gonic/gin"
ui "github.com/go-sonr/ui"
)
func main() {
r := gin.Default()
// Option 1: Configure router
ui.GinRouter(r)
// Option 2: Use middleware
r.Use(ui.GinMiddleware())
r.GET("/", homeHandler)
r.Run(":8080")
}import (
"github.com/labstack/echo/v4"
ui "github.com/go-sonr/ui"
)
func main() {
e := echo.New()
// Use standard middleware wrapper
e.Use(echo.WrapMiddleware(ui.Middleware))
e.GET("/", homeHandler)
e.Start(":8080")
}import (
"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/middleware/adaptor"
ui "github.com/go-sonr/ui"
)
func main() {
app := fiber.New()
// Adapt the standard HTTP handler
app.Use(adaptor.HTTPMiddleware(ui.Middleware))
app.Get("/", homeHandler)
app.Listen(":8080")
}package main
import (
"context"
"log"
"net/http"
"github.com/a-h/templ"
ui "github.com/go-sonr/ui"
"github.com/go-sonr/ui/layout"
"github.com/go-sonr/ui/components/button"
"github.com/go-sonr/ui/components/card"
)
func HomePage() templ.Component {
return templ.ComponentFunc(func(ctx context.Context, w templ.RenderWriter) error {
// Use UI layout components
layout.HTML().Render(ctx, w)
layout.Head().Render(ctx, w)
// Head includes all component scripts automatically
layout.Body().Render(ctx, w)
// Your content here
card.Card(card.Props{
Class: "max-w-md mx-auto mt-10",
}).Render(ctx, w)
button.Button(button.Props{
Variant: button.VariantDefault,
}).Render(ctx, w)
return nil
})
}
func main() {
mux := http.NewServeMux()
// Setup UI assets
ui.ServeAssets(mux)
// Add routes
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
HomePage().Render(r.Context(), w)
})
// Apply security and performance middleware
handler := ui.SecurityHeaders(
ui.PreloadMiddleware(
ui.CacheControl(3600)(mux),
),
)
log.Println("Server running on :8080")
log.Fatal(http.ListenAndServe(":8080", handler))
}The middleware serves the following assets:
/assets/js/*.min.js- Minified JavaScript files for interactive components/assets/css/*.css- CSS files (including generated Tailwind CSS)
Components that include JavaScript:
- avatar, calendar, carousel, chart, code, collapsible, datepicker, dialog
- dropdown, input, inputotp, label, popover, progress, rating, selectbox
- sidebar, slider, tabs, tagsinput, textarea, timepicker, toast
The UI components also depend on CDN resources that are loaded directly:
- TailwindCSS 4 (Beta)
- Shoelace Web Components
- HTMX
- ApexCharts
- D3.js
- Helia (IPFS)
- Dexie (IndexedDB)
These are automatically included when using the layout.Head() component.
The build process integrates TailwindCSS CLI and Templ generation:
# Complete build (TailwindCSS + Templ + Go)
go run build.go
# or
make all
# or
go generate ./...
# Build with local assets (not embedded)
go build -tags localassets ./...
# or
make build-local
# Development with watch mode
go run build.go -watch
# or
make dev# Install dependencies only
go run build.go -install-deps
# Generate CSS only
go run build.go -css-only
# Generate Templ files only
go run build.go -templ-only
# Skip specific steps
go run build.go -skip-css -skip-templ
# Verbose output
go run build.go -v# Add a new component
templui add button
# Add multiple components
templui add button card dialog
# List available components
templui list
# After adding components, regenerate
go generate ./...
# or
make generate# Build all examples
make examples
# Run server example
make examples-run
# Clean example binaries
make examples-cleanFor automated builds in CI/CD pipelines:
# GitHub Actions
- name: Setup and Build
run: |
go run build.go -install-deps
go generate ./...
go build ./...
go test ./...# Docker
RUN go run build.go -install-deps && \
go run build.go && \
go build -o appIf you need to serve assets from a different path:
// Serve from /static/ instead of /assets/js/
mux.Handle("/static/", http.StripPrefix("/static", ui.StaticHandler()))For development or custom deployments, you can build with local assets instead of embedding:
# Build with local assets
go build -tags localassets ./...
# Set custom assets path
export UI_ASSETS_PATH=/path/to/ui/assets
# Use local vendor files (no CDN)
export UI_USE_LOCAL_VENDOR=trueSee BUILD_TAGS.md for detailed information about build tags and BUILD.md for complete build process documentation.
- Always include
layout.Head()in your templates - it loads all necessary dependencies - Use
ui.ServeAssets()orui.Middleware()** to serve component JavaScript - Apply security headers in production environments
- Enable caching for better performance with
CacheControl() - Use preload headers to improve initial page load times
- Run
go generate ./...after modifying.templfiles or CSS - Use
-tags localassetsfor development to avoid rebuilding for asset changes
- Ensure you've called
ui.ServeAssets(mux)or are usingui.Middleware() - Check that assets are mounted at
/assets/js/and/assets/css/ - Verify the embedded files exist in
/assets/directories
- Ensure the component's Script() is included in the Head
- Check browser console for JavaScript errors
- Verify CDN resources are loading (check network tab)
- If using custom CSP, ensure CDN domains are whitelisted
- Use the provided
SecurityHeaders()middleware as a starting point
MIT License - see LICENSE file for details