Address review feedback to remove dead code. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Host Package
Static file server optimized for serving Iris WASM applications.
Basic Setup
package main
import (
"log"
"net/http"
"git.flowmade.one/flowmade-one/iris/host"
)
func main() {
server := host.New("public", "index.html")
log.Println("Server running on http://localhost:8080")
log.Fatal(http.ListenAndServe(":8080", server))
}
Directory Structure
myapp/
├── server.go # Server code (above)
└── public/
├── index.html # Entry point
├── app.wasm # Compiled WASM binary
└── wasm_exec.js # Go WASM runtime
Serving Static Files
The server serves files from the specified public directory. Any request path maps directly to files:
/->public/index.html/app.wasm->public/app.wasm/styles.css->public/styles.css
SPA Fallback: Unknown paths and directories fall back to index.html, enabling client-side routing.
WASM MIME Types
The server automatically sets correct MIME types for all common file types:
| Extension | MIME Type |
|---|---|
.wasm |
application/wasm |
.html |
text/html; charset=utf-8 |
.js |
application/javascript |
.css |
text/css |
.json |
application/json |
.svg |
image/svg+xml |
This ensures browsers load WASM files correctly without manual configuration.
Compression
Gzip compression is automatically applied to compressible content types when the client supports it:
- HTML, CSS, JavaScript
- JSON
- WASM binaries
- SVG images
Binary assets (PNG, JPEG, etc.) are served uncompressed since they're already compressed.
Hot Reload (Development)
The DevServer provides automatic rebuild and browser reload during development:
package main
import (
"git.flowmade.one/flowmade-one/iris/host"
)
func main() {
// Create dev server with hot reload
dev := host.NewDevServer(
"public", // Static files directory
"index.html", // Index file
".", // Source directory to watch
"public/app.wasm", // WASM output path
)
// Start watching and serving
dev.ListenAndServe(":8080")
}
How It Works
- File Watcher: Monitors
.gofiles in the source directory for changes - Auto Build: Runs
GOOS=js GOARCH=wasm go buildwhen changes are detected - Browser Reload: Injects a WebSocket client into HTML pages that triggers reload on build success
Directory Structure for Development
myapp/
├── main.go # WASM application entry point
├── server/
│ └── main.go # Dev server (code above)
└── public/
├── index.html
├── app.wasm # Generated by dev server
└── wasm_exec.js
Workflow
- Start the dev server:
go run ./server - Open
http://localhost:8080in your browser - Edit your Go source files
- Save - the browser automatically reloads with your changes
Custom Watch Configuration
// Watch additional file types
watcher := host.NewWatcher(
".",
onChangeCallback,
host.WithExtensions(".go", ".html", ".css"),
host.WithInterval(100*time.Millisecond),
)
Manual Components
For advanced use cases, you can use the individual components:
// File watcher
watcher := host.NewWatcher(".", func() {
log.Println("Files changed")
})
watcher.Start()
defer watcher.Stop()
// WASM builder
builder := host.NewBuilder(".", "public/app.wasm")
result := builder.Build()
if result.Success {
log.Println("Build succeeded")
}
// Live reload (WebSocket notifications)
lr := host.NewLiveReload()
http.Handle("/__livereload", lr)
lr.NotifyReload() // Triggers reload in all connected browsers
Production
For production, use the standard Server instead of DevServer:
func main() {
server := host.New("public", "index.html")
log.Fatal(http.ListenAndServe(":8080", server))
}
Compile and deploy:
go build -o server ./server
./server
Consider adding:
- TLS termination (via reverse proxy or
http.ListenAndServeTLS) - Environment-based port configuration
- Graceful shutdown handling
Example with TLS:
func main() {
server := host.New("public", "index.html")
log.Fatal(http.ListenAndServeTLS(":443", "cert.pem", "key.pem", server))
}
Example with reverse proxy (nginx):
server {
listen 443 ssl;
server_name example.com;
location / {
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
}
}