[HN Gopher] Go on Embedded Systems and WebAssembly
       ___________________________________________________________________
        
       Go on Embedded Systems and WebAssembly
        
       Author : uticus
       Score  : 200 points
       Date   : 2026-04-03 16:57 UTC (1 days ago)
        
 (HTM) web link (tinygo.org)
 (TXT) w3m dump (tinygo.org)
        
       | nasretdinov wrote:
       | Tinygo made a lot of progress over the years -- e.g. they've
       | recently introduced macOS support!
       | 
       | It does indeed produce much smaller binaries, including for
       | macOS.                 yuriy@MacBookAir ~/t/tinygo> time tinygo
       | build -o test-tiny main.go
       | ________________________________________________________
       | Executed in    1.06 secs    fish           external          usr
       | time    1.18 secs    0.31 millis    1.18 secs          sys time
       | 0.18 secs    1.50 millis    0.18 secs
       | yuriy@MacBookAir ~/t/tinygo> time go build -o test-normal main.go
       | ________________________________________________________
       | Executed in   75.79 millis    fish           external
       | usr time   64.06 millis    0.41 millis   63.64 millis
       | sys time   96.76 millis    1.75 millis   95.01 millis
       | yuriy@MacBookAir ~/t/tinygo> ll       total 5096       -rw-r--
       | r--@ 1 yuriy  staff    74B  3 Apr 19:17 main.go       -rwxr-xr-x@
       | 1 yuriy  staff   2.3M  3 Apr 19:18 test-normal*       -rwxr-xr-x@
       | 1 yuriy  staff   192K  3 Apr 19:18 test-tiny*
       | yuriy@MacBookAir ~/t/tinygo> cat main.go       package main
       | import "fmt"              func main() {
       | fmt.Printf("Hello world!\n")       }
        
         | maccard wrote:
         | What does it look like if you pass -ldflags="-s -w"?
        
           | guessmyname wrote:
           | With Go v1.26.1                 package main       import
           | "fmt"       func main() {         fmt.Printf("Hello
           | World!\n")       }
           | 
           | Binary sizes:
           | 
           | * 2581616B (2.5MB) - 1714560B (1.6MB) (with -ldflags="-s -w")
           | 
           | * 1531920B (1.5MB) - 753680B (0.7MB) (with upx --force-macos)
           | 
           | That said, a trivial "Hello World!" isn't a meaningful
           | benchmark. If you're going to play that game, you might as
           | well swap `fmt.Printf` for `fmt.Println`, or even `println`
           | to avoid the import statement entirely. At that point, you're
           | no longer comparing anything interesting, the binaries end up
           | roughly the same size anyway.
        
       | tatjam wrote:
       | Writing embedded code with an async-aware programming language is
       | wonderful (see Rust's embassy), but wonder how competitive this
       | is when you need to push large quantities of data through a micro
       | controller, I presume this is not suitable for real-time stuff?
        
         | nasretdinov wrote:
         | You can disable GC in tinygo, so if you allocate all the
         | necessary buffers beforehand it can have good performance with
         | real-time characteristics. If you _need_ dynamic memory
         | allocation then no, because you need GC it can't provide
         | realtime guarantees.
        
           | Groxx wrote:
           | Doesn't seem like those should be mutually exclusive, though
           | the habits involved are quite opposing and I can definitely
           | believe they're _uncommon_.
           | 
           | E.g. GC doesn't need to be precise. You could reserve CPU
           | budget for GC, and only use that much at a time before
           | yielding control. As long as you still free enough to not
           | OOM, you're fine.
        
         | carverauto wrote:
         | We're streaming RSTP camera feeds through WASM plugins and
         | host-bridge adapters, no problem. I was surprised how well it
         | worked TBH.
         | 
         | https://code.carverauto.dev/carverauto/serviceradar/src/bran...
        
         | clktmr wrote:
         | I've written a fair amount of code for EmbeddedGo. Garbage
         | Collector is not an issue if you avoid heap allocations in your
         | main loop. But if you're CPU bound a goroutine might block
         | others from running for quite some time. If your platform
         | supports async preemption, you might be able to patch the
         | goroutine scheduler with realtime capabilities.
        
         | randusername wrote:
         | Can you elaborate on this and how it would be different from
         | signaling on interrupts and DMA?
         | 
         | Hardware-level async makes sense to me. I can scope it. I can
         | read the data sheet.
         | 
         | Software async in contrast seems difficult to characterize and
         | reason about so I've been intimidated.
        
           | jamesmunns wrote:
           | It's really not so different! In embassy, DMA transfers and
           | interrupts become things that you can .await on, the process
           | is basically:                 * The software starts a
           | transaction, or triggers some event (like putting data in the
           | fifo)       * The software task yields       * When the "fifo
           | empty" interrupt or "dma transfer done interrupt" occurs, it
           | wakes the task to resume       * the software task checks if
           | it is done, and either reloads/restarts if there's more to
           | do, or returns "done"
           | 
           | It's really not different than event driven state machines
           | you would have written before, it's just "in-band" of the
           | language now, and async/await gives you syntax to do it.
           | 
           | Even if you don't know Rust, I'd suggest poking around at
           | some of the examples here:
           | 
           | https://github.com/embassy-rs/embassy/tree/main/examples
           | 
           | And if you want, look into the code behind it.
        
         | soypat wrote:
         | It is more performant than rust but less performant than Zig
         | when not doing GC heavy stuff. https://github.com/tinygo-
         | org/tinybench
        
       | carverauto wrote:
       | We're using TinyGo and the Wazero runtime for our WASM plugin
       | system in ServiceRadar, highly recommend both if you're using
       | golang.
        
         | evacchi wrote:
         | Yay wazero maintainer here, thanks for the shout-out!
        
           | pancsta wrote:
           | It was good to meet at wasm.io!
        
         | apitman wrote:
         | Wazero is awesome. For anyone wanting to embed in languages
         | other than Go, check out Extism.
        
       | mi_lk wrote:
       | What are the tradeoffs compared to standard Go?
        
         | jrockway wrote:
         | It gets better every release, but there are missing language
         | features:
         | 
         | https://tinygo.org/docs/reference/lang-support/
         | 
         | And parts of the stdlib that don't work:
         | 
         | https://tinygo.org/docs/reference/lang-support/stdlib/
        
       | pancsta wrote:
       | TinyGo doesnt have networking in WASI[0] and the WASM websocket
       | module[1] was last updated 5 years ago. Go without stdlib is not
       | Go.
       | 
       | [0] https://github.com/tinygo-org/tinygo/issues/4880
       | 
       | [1] https://github.com/Nerzal/tinywebsocket
        
         | dkegel wrote:
         | For embedded systems, see https://github.com/tinygo-org/net
         | 
         | For WASI, check out WASI Preview 2,
         | https://docs.wasmtime.dev/api/wasmtime_wasi/p2/index.html
        
           | pancsta wrote:
           | Thats the host, but the guess is missing, as stated in the
           | issue last year "I guess we could add sockets to wasip2". To
           | be honest, even BigGo failed me on websocket conns on both
           | wasmtime and wazero (connects and gets into an inf loop on
           | reply). WebWorkers and GOOS=js work like a charm tho on BigGo
           | in FF/chrome.
        
             | dkegel wrote:
             | Yeah, I suspect sockets in wasip2, and wasip2 in general,
             | are just now having the bugs shaken out of them.
             | 
             | The company I work for is just now upgrading its edge WASI
             | support to wasip2.
        
         | pjmlp wrote:
         | Interestingly enough for the C and C++ folks, compiler specific
         | dialects for embedded without standard library, are still
         | argued for as if being C and C++.
        
       | jackhalford wrote:
       | Could we compile tailscale with tinygo to run it on openwrt? Last
       | time I checked tailscale was too large for 8MB flash routers
        
         | mayama wrote:
         | Lot of stdlib, especially net, crypto, in tinygo doesn't
         | compile, or if compiles has stubs as implementation that panics
         | with not implemented. Few years ago, I tried compiling small
         | terminal http client app and failed at compile stage.
         | 
         | https://tinygo.org/docs/reference/lang-support/stdlib/
        
       | febed wrote:
       | Does it support ESP32
        
         | kitd wrote:
         | Full list is here:
         | 
         | https://tinygo.org/docs/reference/microcontrollers/
         | 
         | A few ESP32s on there.
        
           | dkegel wrote:
           | Another one was added an hour ago, https://github.com/tinygo-
           | org/tinygo/pull/5280
        
       | ghoul2 wrote:
       | Its a fantastic project, but seems almost inactive now. I have a
       | tiny PR pending for weeks, even reviewed, but not merged. I have
       | another patch I have not submitted as I want to first navigate
       | the earlier PR to completion. Both were bugs that bit me, and I
       | ended up wasting quite a lot of time trying to find it:
       | 
       | 1. go:embed supports "all:<pattern" while tinygo silently ignore
       | it. I ripped my hair out trying to figure out why my files were
       | not showing up in embedfs. PR pending.
       | 
       | 2. go allows setting some global vars at the build cli (think
       | build version/tag etc). In the code, one can define a default,
       | and then the value provided (if any) on the cli can override it
       | at build time. Tinygo fails to override the value at build-time,
       | silently, if a default value is provided for the var in code.
       | This PR I have not submitted yet, as its more intrusive.
       | 
       | I hope it picks up steam again soon. I love using go for embedded
       | and CF worker use and tinygo makes both of these use cases much
       | more viable than regular go. Honestly, I hope tinygo can be
       | rolled over into the main go toolchain as "target arch".
        
         | justinclift wrote:
         | Looking at the commit history, it seems pretty active:
         | 
         | https://github.com/tinygo-org/tinygo/commits/dev/
         | 
         | Maybe the opposite thing is happening, whereby the maintainers
         | are getting overwhelmed?
        
           | soypat wrote:
           | It'd be nice to get some help :) TinyGo developers are
           | community driven as we receive no financing.
        
             | dkegel wrote:
             | FWIW the company I work for has been helping out a little
             | here and there, one of our engineers has four commits in so
             | far this year.
        
         | dkegel wrote:
         | There have been four committers in the last week, so it's
         | active!
         | 
         | Consider joining the slack channel #tinygo-dev on
         | gophers.slack.com and pinging them about the PR.
        
       | rcarmo wrote:
       | TinyGo was instrumental in getting https://github.com/rcarmo/go-
       | rdp to work. It generates very tight, pretty high performing
       | WASM, and that allowed me to push all the RDP decoding to the
       | browser side while making sure I had a sane test suite. Heartily
       | recommended.
        
       ___________________________________________________________________
       (page generated 2026-04-04 23:01 UTC)