Ultra-minimal DOM & event toolkit for Go (TinyGo WASM-optimized).
tinywasm/dom provides a minimalist, WASM-optimized way to interact with the browser DOM in Go, avoiding the overhead of the standard library and syscall/js exposure. It is designed specifically for TinyGo applications where binary size and performance are critical.
- TinyGo Optimized: Avoids heavy standard library packages like
fmtornet/httpto keep WASM binaries small. - Direct DOM Manipulation: No Virtual DOM overhead. You control the updates.
- ID-Based Caching: Efficient element lookup and caching strategy.
- Memory Safe: Automatic event listener cleanup on
Unmount.
go get github.com/tinywasm/domtinywasm/dom provides two ways to interact with the DOM:
- Global API: Quick and easy functions like
dom.Get(id),dom.Mount(parent, comp). Most applications should use this. - Instance API: If you need multiple isolated DOM instances (e.g., for testing or multiple root contexts).
Here is a simple "Counter" component example.
package main
import (
"github.com/tinywasm/dom"
. "github.com/tinywasm/fmt"
)
type Counter struct {
id string
count int
}
func NewCounter(id string) *Counter {
return &Counter{id: id}
}
func (c *Counter) HandlerName() string { return c.id }
func (c *Counter) RenderHTML() string {
return Html(
"<div id='", c.id, "'>",
"<span id='", c.id, "-val'>", c.count, "</span>",
"<button id='", c.id, "-btn'>Increment</button>",
"</div>",
).String()
}
// OnMount is called after HTML is injected.
func (c *Counter) OnMount() {
// Use the global dom.Get() to find elements
valEl, _ := dom.Get(c.id + "-val")
btnEl, _ := dom.Get(c.id + "-btn")
// Bind events using the Element interface
btnEl.Click(func(e dom.Event) {
c.count++
valEl.SetText(c.count)
})
}
func main() {
dom.Mount("app", NewCounter("my-counter"))
select {}
}For complex components (like Forms), you can use event delegation at the root level using e.TargetID() and e.TargetValue():
func (c *MyList) OnMount() {
root, _ := dom.Get(c.HandlerName())
// Catch clicks from any child button
root.On("click", func(e dom.Event) {
id := e.TargetID() // "list-item-1", "list-item-2", etc.
// Handle logic...
})
}For more detailed information, please refer to the documentation in the docs/ directory:
- Specification & Philosophy: Design goals, architecture, and key decisions.
- API Reference: Detailed definition of
DOM,Element, andComponentinterfaces. - Creating Components: Guide to building basic and nested components.
- Event Handling: Using the
Eventinterface for clicks, inputs, and forms. - tinywasm/fmt Helper: Quick guide for string conversions and manipulations.
- Advanced Patterns: Dynamic lists, decoupling, and performance tips.
- Comparison: TinyDOM vs. syscall/js, VDOM, and JS frameworks.
MIT