https://github.com/tinywasm/client
tinywasm is a lightweight toolbox designed to streamline the compilation of Go packages to WebAssembly (WASM) using the TinyGo compiler.
https://github.com/tinywasm/client
Last synced: 5 months ago
JSON representation
tinywasm is a lightweight toolbox designed to streamline the compilation of Go packages to WebAssembly (WASM) using the TinyGo compiler.
- Host: GitHub
- URL: https://github.com/tinywasm/client
- Owner: tinywasm
- License: mit
- Created: 2025-05-26T16:50:45.000Z (about 1 year ago)
- Default Branch: main
- Last Pushed: 2025-12-18T14:18:15.000Z (6 months ago)
- Last Synced: 2025-12-18T14:33:58.392Z (6 months ago)
- Language: Go
- Size: 275 KB
- Stars: 1
- Watchers: 0
- Forks: 0
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- Changelog: Change.go
- License: LICENSE
Awesome Lists containing this project
README
# tinywasm
Go package for intelligent WebAssembly compilation with automatic file detection and 3-mode compiler system.
## Features
- **3-Mode Compiler System**: Large ("L"), Medium ("M"), Small ("S")
- **DevTUI Integration**: FieldHandler interface for interactive mode switching
- Smart file detection via prefixes (frontend/backend separation)
- Triple compiler support: Go standard (fast dev), TinyGo debug (-opt=1), TinyGo production (-opt=z)
- VS Code auto-configuration for WASM development
- **Dual Output Architecture**: WASM binaries in `src/web/public/`, watchable JS in `src/web/ui/js/`
## Quick Start
```go
// Basic usage
config := tinywasm.NewConfig() // Pre-configured with defaults
config.SourceDir = "src/cmd/webclient"
config.OutputDir = "src/web/public"
config.WasmExecJsOutputDir = "src/web/ui/js"
tw := tinywasm.New(config)
tw.NewFileEvent("src/cmd/webclient/main.go", ".go", "src/cmd/webclient/main.go", "write")
// DevTUI Integration - 3 Mode System
fmt.Println("Current mode:", tw.Value()) // "L" (coding / large build)
// New API: Change now reports progress via a channel instead of returning (msg, err).
// Create and consume a progress channel before calling Change to avoid blocking.
progress := make(chan string)
go func() {
for p := range progress {
fmt.Println("Status:", p)
}
}()
tw.Change("M", progress) // Switch to medium (debug) mode; messages arrive on the progress channel
// Advanced configuration
config := &tinywasm.Config{
AppRootDir: "/path/to/project",
SourceDir: "src/cmd/webclient",
OutputDir: "src/web/public",
WasmExecJsOutputDir: "src/web/ui/js",
MainInputFile: "main.go",
OutputName: "main",
BuildLargeSizeShortcut: "L", // Customizable shortcuts (default: L = Large/fast with go)
BuildMediumSizeShortcut: "M",
BuildSmallSizeShortcut: "S",
Logger: logger,
}
```
## DevTUI FieldHandler Interface
TinyWasm implements the DevTUI FieldHandler interface for interactive development:
```go
// DevTUI Integration
label := tw.Label() // "Compiler Mode"
current := tw.Value() // Current mode shortcut ("L", "M", "S")
canEdit := tw.Editable() // true
timeout := tw.Timeout() // 0 (no timeout)
// Interactive mode change with the new Change API
// Change now has signature: Change(newValue string, progress chan<- string)
// All validation messages, warnings (e.g. auto-compilation failed) and success
// messages are sent through the provided channel. The channel is closed when
// the operation completes.
progress := make(chan string)
go func() {
for p := range progress {
// Handle progress messages (show in TUI, log, etc.)
fmt.Println("Progress:", p)
}
}()
tw.Change("M", progress)
// No return values; read errors and status from the progress channel above.
```
## VS Code Integration
Auto-creates `.vscode/settings.json` with WASM environment:
```json
{"gopls": {"env": {"GOOS": "js", "GOARCH": "wasm"}}}
```
## API
**Core:**
- `New(config *Config) *TinyWasm`
- `NewConfig() *Config` - Pre-configured with sensible defaults
- `NewFileEvent(fileName, ext, path, event string) error`
- `ShouldCompileToWasm(fileName, path string) bool`
**DevTUI FieldHandler Interface:**
- `Label() string` - Returns "Compiler Mode"
- `Value() string` - Current mode shortcut ("L", "M", "S")
- `Editable() bool` - Returns true (field is editable)
- `Change(newValue string, progress chan<- string)` - Switch compiler mode and report progress via the provided channel. Validation errors, auto-compilation warnings and success messages are sent to the channel; the implemention closes the channel when finished.
- `Timeout() time.Duration` - Returns 0 (no timeout)
**Legacy Compiler Methods (deprecated):**
- `TinyGoCompiler() bool` - Use `Value()` instead
- `SetTinyGoCompiler(bool) error` - Use `Change()` instead
- `VerifyTinyGoInstallation() error`
**Utils:**
- `MainInputFileRelativePath() string`
- `UnobservedFiles() []string`
- `JavascriptForInitializing() (string, error)`
## Config
```go
type Config struct {
AppRootDir string // application root directory (absolute), defaults to "."
SourceDir string // directory containing Go source (relative) eg: "src/cmd/webclient"
OutputDir string // directory for WASM binary output (relative) eg: "src/web/public"
WasmExecJsOutputDir string // directory for watchable JS runtime (relative) eg: "src/web/ui/js"
MainInputFile string // main input file for WASM compilation (default: "main.go")
OutputName string // output name for WASM file (default: "main")
Logger func(message ...any) // For logging output to external systems (e.g., TUI, console)
// NEW: Shortcut configuration (default: "f", "b", "m")
BuildLargeSizeShortcut string // "L" (large/fast) compile fast with go
BuildMediumSizeShortcut string // "M" (medium/debug) compile with tinygo debug
BuildSmallSizeShortcut string // "S" (small/minimal) compile with tinygo minimal binary size
// gobuild integration fields
Callback func(error) // Optional callback for async compilation
CompilingArguments func() []string // Build arguments for compilation (e.g., ldflags)
// DisableWasmExecJsOutput prevents automatic creation of wasm_exec.js file
// Useful when embedding wasm_exec.js content inline (e.g., Cloudflare Pages Advanced Mode)
DisableWasmExecJsOutput bool
}
// Pre-configured constructor (recommended)
func NewConfig() *Config
```
## Dual Output Architecture
TinyWasm produces **two types of outputs** that serve different purposes in the build pipeline:
### 1. **WASM Binary Output** (`OutputDir`)
- **Location:** `src/web/public/main.wasm`
- **Purpose:** Final compiled WebAssembly binary loaded by the browser
- **Consumed by:** Browser at runtime
- **Modes:** All three compilation modes produce output here
### 2. **Watchable JavaScript Output** (`WasmExecJsOutputDir`)
- **Location:** `src/web/ui/js/wasm_exec.js`
- **Purpose:** Mode-specific JavaScript runtime that:
- Informs external tools about the current compilation mode (Go vs TinyGo)
- Triggers file watchers to reload the browser when mode changes
- Gets compiled together with other JavaScript by external asset bundlers
- **Consumed by:** File watchers (e.g., `devwatch`) and asset bundlers (e.g., `assetmin`)
- **Important:** TinyWasm's **only responsibility** is writing the correct `wasm_exec.js` according to the active mode. External tools handle final bundling.
### Why Two Separate Directories?
1. **Separation of Concerns:** Runtime assets vs. build-time integration
2. **Build Pipeline Integration:** File watchers track `wasm_exec.js` changes
3. **No Dev/Prod States:** All modes use the same directories
4. **Mode Transparency:** External tools detect mode changes via `wasm_exec.js`
## Mode Switching
```go
// Example usage with the new channel-based Change API:
progress := make(chan string)
go func() {
for p := range progress {
fmt.Println(p)
}
}()
tw.Change("S", progress) // production mode with TinyGo -opt=z
// Repeat for other modes as needed (always provide and consume a progress channel)
// tw.Change("M", progress)
// tw.Change("L", progress)
```
## Requirements
- Go 1.20+
- TinyGo (optional, required for debug/production modes)
- DevTUI (optional, for interactive development)
**Benefits:**
- 🎯 **3 optimized modes** instead of binary choice
- 🔧 **DevTUI integration** for interactive development
- 📦 **Smaller debug builds** with TinyGo -opt=1
- ⚡ **Auto-recompilation** on mode switch
- 🛠️ **Better error handling** with validation
- 🏗️ **Dual output architecture** for better build pipeline integration
## [Contributing](https://github.com/tinywasm/cdvelop/blob/main/CONTRIBUTING.md)