AssetMin is a lightweight web asset packager and minifier for Go applications. It bundles and minifies JavaScript, CSS, SVG, and HTML files with support for both memory-based and disk-based serving.
AssetMin processes and minifies web assets through a simple event-driven workflow:
- File Events: Notify AssetMin when files are created, modified, or deleted.
- Content Processing: Files are read, processed, and stored in memory.
- Minification: Content is minified and cached for fast serving.
- Output: Assets are served via HTTP or written to disk based on work mode.
Assets are organized into three content sections to ensure correct loading order:
- contentOpen: Files processed first (e.g., base themes, CSS variables).
- contentMiddle: Main content files (e.g., external module files).
- contentClose: Files processed last (e.g., application-specific overrides).
type Config struct {
OutputDir string // Directory for DiskMode output
RootDir string // Project root (used for module discovery)
AppName string // Application name used in templates
AssetsURLPrefix string // URL prefix for assets (e.g., "/static/")
Logger func(msg ...any) // Optional logging function
}AssetMin supports two work modes:
- Assets are served from memory cache only.
- No disk writes occur.
- Changes are immediately available via HTTP.
- Activated by calling
FlushToDisk(). - All in-memory assets are written to disk (overwrites stale files).
- After a successful flush, every subsequent
NewFileEventalso writes to disk automatically. - HTTP requests continue to be served from the in-memory cache.
func NewAssetMin(config *Config) *AssetMinfunc (c *AssetMin) NewFileEvent(fileName, extension, filePath, event string) errorProcesses a file system event and updates the corresponding asset bundle.
fileName: Name of the file (e.g., "button.css").extension: File extension (e.g., ".css", ".js", ".svg", ".html").filePath: Full path to the source file.event: Event type - "create", "write", "remove".
Activates the SSR event-handling branch unconditionally. Call once at startup so that .css file events route through the SSR slot logic. Does NOT register a compiler — safe to call with no SetSSRCompiler.
Registers a Go compiler callback that is invoked on .go file changes. Pure setter — does NOT call fn at registration time. Pass nil to unregister.
Snapshots all registered assets and writes them to disk (overwrites existing files). Sets the internal diskMirrored flag only on full success; subsequent NewFileEvent calls will also write to disk. Returns the first write error encountered.
// Typical usage before starting an external server:
if err := am.FlushToDisk(); err != nil {
return fmt.Errorf("assetmin flush: %w", err)
}Starts the discovery of all Go modules in the project tree, scans for asset source files (css.go, js.go, svg.go, html.go; legacy ssr.go also recognized), and extracts assets (CSS, JS, HTML, Icons) asynchronously via compile-and-invoke.
Re-extracts and updates assets for a single module directory. Used for hot reload.
Registers live component instances that implement SSR interfaces.
RootCSS() *css.Stylesheet: Routed toopenslot.RenderCSS() *css.Stylesheet: Routed tomiddleorcloseslot.RenderJS() []*js.Script: Scripts withName==""accumulate in the global bundle (script.js); scripts withName!=""are written as standalone files at the public root (e.g.sw.js).RenderHTML() stringIconSvg() map[string]string
Invalidates and regenerates JS and HTML assets. Use this when the WASM binary or initialization logic changes.
func (c *AssetMin) RegisterRoutes(mux *http.ServeMux)Registers handlers:
GET /->index.htmlGET /<prefix>style.cssGET /<prefix>script.jsGET /<prefix>favicon.svg
- Output:
script.js - Features: Automatic
'use strict'management, runtime initializer prepended.
- Output:
style.css - Features: Merged bundles from all source files and SSR modules. Supports typed CSS via
github.com/tinywasm/css.
- Sprite: Delivered exclusively inline within
index.html. No separate HTTP route. - Favicon: Served as
favicon.svg.
- Output:
index.html - Features: Template-based, automatic injection of CSS/JS/Sprite.
AssetMin is fully thread-safe, utilizing sync.RWMutex for asset caches and protecting the global state with a primary mutex.
SSR extraction uses a compile-and-invoke mechanism:
- Results are cached globally (
ssrGlobalCache) using the MD5 hash of module Go files. - Warm extractions are near-instant (~1ms).
- Cold extraction wall-time (edit -> extract) is ~300-500ms, dominated by
go run.