{"id":34187241,"url":"https://github.com/tinywasm/client","last_synced_at":"2026-01-13T17:29:23.282Z","repository":{"id":296123739,"uuid":"990800337","full_name":"tinywasm/client","owner":"tinywasm","description":"tinywasm is a lightweight toolbox designed to streamline the compilation of Go packages to WebAssembly (WASM) using the TinyGo compiler.","archived":false,"fork":false,"pushed_at":"2025-12-18T14:18:15.000Z","size":282,"stargazers_count":1,"open_issues_count":2,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-12-18T14:33:58.392Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tinywasm.png","metadata":{"files":{"readme":"README.md","changelog":"Change.go","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-05-26T16:50:45.000Z","updated_at":"2025-12-18T14:18:17.000Z","dependencies_parsed_at":"2025-05-29T04:18:52.201Z","dependency_job_id":"627b434b-65d7-485e-a703-ff7f4c5ddd27","html_url":"https://github.com/tinywasm/client","commit_stats":null,"previous_names":["cdvelop/tinywasm","tinywasm/client"],"tags_count":68,"template":false,"template_full_name":null,"purl":"pkg:github/tinywasm/client","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tinywasm%2Fclient","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tinywasm%2Fclient/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tinywasm%2Fclient/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tinywasm%2Fclient/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tinywasm","download_url":"https://codeload.github.com/tinywasm/client/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tinywasm%2Fclient/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28394265,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-13T14:36:09.778Z","status":"ssl_error","status_checked_at":"2026-01-13T14:35:19.697Z","response_time":56,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-12-15T15:06:28.395Z","updated_at":"2026-01-13T17:29:23.261Z","avatar_url":"https://github.com/tinywasm.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# tinywasm\n\u003c!-- START_SECTION:BADGES_SECTION --\u003e\n\u003ca href=\"docs/img/badges.svg\"\u003e\u003cimg src=\"docs/img/badges.svg\" alt=\"Project Badges\" title=\"Generated by badges.sh from github.com/tinywasm/devscripts\"\u003e\u003c/a\u003e\n\u003c!-- END_SECTION:BADGES_SECTION --\u003e\n\nGo package for intelligent WebAssembly compilation with automatic file detection and 3-mode compiler system.\n\n## Features\n\n- **3-Mode Compiler System**: Large (\"L\"), Medium (\"M\"), Small (\"S\")\n- **DevTUI Integration**: FieldHandler interface for interactive mode switching\n- Smart file detection via prefixes (frontend/backend separation)\n- Triple compiler support: Go standard (fast dev), TinyGo debug (-opt=1), TinyGo production (-opt=z)\n- VS Code auto-configuration for WASM development\n- **Dual Output Architecture**: WASM binaries in `src/web/public/`, watchable JS in `src/web/ui/js/`\n\n## Quick Start\n\n```go\n// Basic usage\nconfig := tinywasm.NewConfig() // Pre-configured with defaults\nconfig.SourceDir = \"src/cmd/webclient\"\nconfig.OutputDir = \"src/web/public\"\nconfig.WasmExecJsOutputDir = \"src/web/ui/js\"\n\ntw := tinywasm.New(config)\ntw.NewFileEvent(\"src/cmd/webclient/main.go\", \".go\", \"src/cmd/webclient/main.go\", \"write\")\n\n// DevTUI Integration - 3 Mode System\nfmt.Println(\"Current mode:\", tw.Value()) // \"L\" (coding / large build)\n\n// New API: Change now reports progress via a channel instead of returning (msg, err).\n// Create and consume a progress channel before calling Change to avoid blocking.\nprogress := make(chan string)\ngo func() {\n\tfor p := range progress {\n\t\tfmt.Println(\"Status:\", p)\n\t}\n}()\ntw.Change(\"M\", progress) // Switch to medium (debug) mode; messages arrive on the progress channel\n\n// Advanced configuration\nconfig := \u0026tinywasm.Config{\n    AppRootDir:          \"/path/to/project\",\n    SourceDir:           \"src/cmd/webclient\",\n    OutputDir:           \"src/web/public\",\n    WasmExecJsOutputDir: \"src/web/ui/js\",\n    MainInputFile:       \"main.go\",\n    OutputName:          \"main\",\n\tBuildLargeSizeShortcut:   \"L\",  // Customizable shortcuts (default: L = Large/fast with go)\n\tBuildMediumSizeShortcut:    \"M\",\n\tBuildSmallSizeShortcut: \"S\",\n    Logger:              logger,\n}\n```\n\n\n## DevTUI FieldHandler Interface\n\nTinyWasm implements the DevTUI FieldHandler interface for interactive development:\n\n```go\n// DevTUI Integration\nlabel := tw.Label()           // \"Compiler Mode\"\ncurrent := tw.Value()         // Current mode shortcut (\"L\", \"M\", \"S\")\ncanEdit := tw.Editable()      // true\ntimeout := tw.Timeout()       // 0 (no timeout)\n\n// Interactive mode change with the new Change API\n// Change now has signature: Change(newValue string, progress chan\u003c- string)\n// All validation messages, warnings (e.g. auto-compilation failed) and success\n// messages are sent through the provided channel. The channel is closed when\n// the operation completes.\nprogress := make(chan string)\ngo func() {\n\tfor p := range progress {\n\t\t// Handle progress messages (show in TUI, log, etc.)\n\t\tfmt.Println(\"Progress:\", p)\n\t}\n}()\ntw.Change(\"M\", progress)\n// No return values; read errors and status from the progress channel above.\n```\n\n## VS Code Integration\n\nAuto-creates `.vscode/settings.json` with WASM environment:\n```json\n{\"gopls\": {\"env\": {\"GOOS\": \"js\", \"GOARCH\": \"wasm\"}}}\n```\n\n## API\n\n**Core:**\n- `New(config *Config) *TinyWasm`\n- `NewConfig() *Config` - Pre-configured with sensible defaults\n- `NewFileEvent(fileName, ext, path, event string) error`\n- `ShouldCompileToWasm(fileName, path string) bool`\n\n**DevTUI FieldHandler Interface:**\n- `Label() string` - Returns \"Compiler Mode\"\n- `Value() string` - Current mode shortcut (\"L\", \"M\", \"S\")\n- `Editable() bool` - Returns true (field is editable)\n- `Change(newValue string, progress chan\u003c- 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.\n- `Timeout() time.Duration` - Returns 0 (no timeout)\n\n**Legacy Compiler Methods (deprecated):**\n- `TinyGoCompiler() bool` - Use `Value()` instead\n- `SetTinyGoCompiler(bool) error` - Use `Change()` instead\n- `VerifyTinyGoInstallation() error`\n\n**Utils:**\n- `MainInputFileRelativePath() string`\n- `UnobservedFiles() []string`\n- `JavascriptForInitializing() (string, error)`\n\n## Config\n\n```go\ntype Config struct {\n\tAppRootDir          string        // application root directory (absolute), defaults to \".\"\n\tSourceDir           string        // directory containing Go source (relative) eg: \"src/cmd/webclient\"\n\tOutputDir           string        // directory for WASM binary output (relative) eg: \"src/web/public\"\n\tWasmExecJsOutputDir string        // directory for watchable JS runtime (relative) eg: \"src/web/ui/js\"\n\tMainInputFile       string        // main input file for WASM compilation (default: \"main.go\")\n\tOutputName          string        // output name for WASM file (default: \"main\")\n\tLogger              func(message ...any) // For logging output to external systems (e.g., TUI, console)\n\n\t// NEW: Shortcut configuration (default: \"f\", \"b\", \"m\")\n\tBuildLargeSizeShortcut    string // \"L\" (large/fast) compile fast with go\n\tBuildMediumSizeShortcut     string // \"M\" (medium/debug) compile with tinygo debug\n\tBuildSmallSizeShortcut string // \"S\" (small/minimal) compile with tinygo minimal binary size\n\n\t// gobuild integration fields\n\tCallback           func(error)     // Optional callback for async compilation\n\tCompilingArguments func() []string // Build arguments for compilation (e.g., ldflags)\n\n\t// DisableWasmExecJsOutput prevents automatic creation of wasm_exec.js file\n\t// Useful when embedding wasm_exec.js content inline (e.g., Cloudflare Pages Advanced Mode)\n\tDisableWasmExecJsOutput bool\n}\n\n// Pre-configured constructor (recommended)\nfunc NewConfig() *Config\n```\n\n## Dual Output Architecture\n\nTinyWasm produces **two types of outputs** that serve different purposes in the build pipeline:\n\n### 1. **WASM Binary Output** (`OutputDir`)\n- **Location:** `src/web/public/main.wasm`\n- **Purpose:** Final compiled WebAssembly binary loaded by the browser\n- **Consumed by:** Browser at runtime\n- **Modes:** All three compilation modes produce output here\n\n### 2. **Watchable JavaScript Output** (`WasmExecJsOutputDir`)\n- **Location:** `src/web/ui/js/wasm_exec.js`\n- **Purpose:** Mode-specific JavaScript runtime that:\n  - Informs external tools about the current compilation mode (Go vs TinyGo)\n  - Triggers file watchers to reload the browser when mode changes\n  - Gets compiled together with other JavaScript by external asset bundlers\n- **Consumed by:** File watchers (e.g., `devwatch`) and asset bundlers (e.g., `assetmin`)\n- **Important:** TinyWasm's **only responsibility** is writing the correct `wasm_exec.js` according to the active mode. External tools handle final bundling.\n\n### Why Two Separate Directories?\n\n1. **Separation of Concerns:** Runtime assets vs. build-time integration\n2. **Build Pipeline Integration:** File watchers track `wasm_exec.js` changes\n3. **No Dev/Prod States:** All modes use the same directories\n4. **Mode Transparency:** External tools detect mode changes via `wasm_exec.js`\n\n## Mode Switching\n```go\n// Example usage with the new channel-based Change API:\nprogress := make(chan string)\ngo func() {\n\tfor p := range progress {\n\t\tfmt.Println(p)\n\t}\n}()\ntw.Change(\"S\", progress) // production mode with TinyGo -opt=z\n\n// Repeat for other modes as needed (always provide and consume a progress channel)\n// tw.Change(\"M\", progress)\n// tw.Change(\"L\", progress)\n```\n\n## Requirements\n\n- Go 1.20+\n- TinyGo (optional, required for debug/production modes)\n- DevTUI (optional, for interactive development)\n\n\n\n**Benefits:**\n- 🎯 **3 optimized modes** instead of binary choice\n- 🔧 **DevTUI integration** for interactive development  \n- 📦 **Smaller debug builds** with TinyGo -opt=1\n- ⚡ **Auto-recompilation** on mode switch\n- 🛠️ **Better error handling** with validation\n- 🏗️ **Dual output architecture** for better build pipeline integration\n\n\n## [Contributing](https://github.com/tinywasm/cdvelop/blob/main/CONTRIBUTING.md)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftinywasm%2Fclient","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftinywasm%2Fclient","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftinywasm%2Fclient/lists"}