Skip to content
Projects

go-via/via has 40 GitHub stars and 7 forks. GitHot measured 0 stars in 24 hours, 0 in 7 days, and +1 in 15 days. Last checked 2026-11-09 19:58 UTC. Last push 2026-10-25.

How these counts are measured

Reactive web apps in pure Go

Measured star growth

in 24h
0
in 7 days
0
in 15 days
+1
in 1 month
Collecting history

Net star changes over overlapping periods, not daily totals. Missing measurements are left blank. Stars measure attention, not software quality.

README.md

Original

via

via

Go Reference CI CodeQL License: MIT

Live web UI in Go. A page is a struct, a click is a method call, and the server can push the change to every open tab. No JavaScript to write, no build step.

A counter every tab shares

via needs Go 1.27 or newer.

go mod init example.com/counter
go get github.com/go-via/via

main.go:

package main

import (
	"log"
	"net/http"
	"sync"

	"github.com/go-via/via"
	"github.com/go-via/via/h"
	"github.com/go-via/via/on"
	"github.com/go-via/via/topic"
)

var (
	mu    sync.Mutex
	count int64
	moved = topic.New[int64]()
)

func add(n int64) {
	mu.Lock()
	defer mu.Unlock()
	count += n
	moved.Publish(count)
}

func load() int64 {
	mu.Lock()
	defer mu.Unlock()
	return count
}

type Counter struct{ N via.State[int64] }

func (c *Counter) Inc(ctx *via.Ctx) { add(1) }
func (c *Counter) Dec(ctx *via.Ctx) { add(-1) }

func (c *Counter) View() h.H {
	return h.Div(
		h.Button(on.Click(c.Dec), h.Str("-")),
		h.H1(c.N.Display()),
		h.Button(on.Click(c.Inc), h.Str("+")),
	)
}

func main() {
	r := via.Handler(Counter{N: via.StateTrack(moved, load)})
	log.Fatal(http.ListenAndServe(":8080", r))
}
go run .

Open http://localhost:8080 in two tabs and click + in one. Both update. At startup via warns that no WithTrustedOrigin is set; Security covers what to set before you deploy. Getting started builds up to this program.

Why via

  • Actions are methods. on.Click(c.Inc) takes a method value, so a misspelled action is a compile error, not a dead button.
  • Live only where it needs to be. A page is plain HTTP until something on it goes live; then its tab holds one stream. Live state
  • Nothing to build. The browser client ships inside the module, and the markup is Go.
  • Testable from go test. Package vt drives pages, actions and live streams without a browser. Testing

What it costs

Live state is held on the server. What it costs lists the tradeoffs.

Documentation

Status

Pre-1.0: the API can change between minor versions. CHANGELOG.md records each release.

Contributing

./ci.sh

It is the release gate: green means releasable. It runs every check on all three modules, including the browser tier in vtbrowser, which needs Chromium or Chrome on PATH or in VIA_CHROME. It reports, never rewrites. A PR also runs ./mutation.sh origin/main, which mutates the changed lines in the root module and fails when the tests kill too few of the mutants.

CONVENTIONS.md has the code and test conventions, including the bar for a new duck-typed method.

License

MIT, see LICENSE.

Explore related projects