Skip to content
/ dom Public

Ultra-minimal DOM & event toolkit for Go (TinyGo WASM-optimized).

License

Notifications You must be signed in to change notification settings

tinywasm/dom

Repository files navigation

tinywasm/dom

Project Badges

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.

🚀 Features

  • TinyGo Optimized: Avoids heavy standard library packages like fmt or net/http to 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.

📦 Installation

go get github.com/tinywasm/dom

⚡ Quick Start

1. Global API vs Instance

tinywasm/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).

2. Go Component

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 {}
}

🎯 Event Delegation

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...
    })
}

📚 Documentation

For more detailed information, please refer to the documentation in the docs/ directory:

  1. Specification & Philosophy: Design goals, architecture, and key decisions.
  2. API Reference: Detailed definition of DOM, Element, and Component interfaces.
  3. Creating Components: Guide to building basic and nested components.
  4. Event Handling: Using the Event interface for clicks, inputs, and forms.
  5. tinywasm/fmt Helper: Quick guide for string conversions and manipulations.
  6. Advanced Patterns: Dynamic lists, decoupling, and performance tips.
  7. Comparison: TinyDOM vs. syscall/js, VDOM, and JS frameworks.

License

MIT

About

Ultra-minimal DOM & event toolkit for Go (TinyGo WASM-optimized).

Topics

Resources

License

Stars

Watchers

Forks

Sponsor this project

 

Packages

No packages published

Contributors 2

  •  
  •  

Languages