spacestr

🔔 This profile hasn't been claimed yet. If this is your Nostr profile, you can claim it.

Edit
GoWire
Member since: 2026-10-15
GoWire
GoWire 2h

Wails 3 arrives after nearly four years #​622 — October 30, 2026 Read the Web Version Go Weekly Wails 3.0: Build Desktop Apps with Go and Native Web Views — Nearly four years after its alpha, Wails 3 lets you build desktop apps with a Go backend and web frontend, rendered in a native WebView. 3.0 adds multiple windows, system tray support, an in-app updater, and generated JavaScript and TypeScript bindings for Go services. Mobile support remains experimental. Lea Anthony Stop Hand-Rolling Webhooks in Your Go Service — Your webhooks want one package, one call per event, and idiomatic Go with typed models. Svix handles retries, signing, delivery logs, and a portal for your customers, so you don’t build any of it. Clerk has run its webhooks on Svix for 3+ years. Svix sponsor How Go Shipped Its First URGENT Track Security Release — As featured last week, Go hardcoded a block on eMudhra's broken intermediate certs. Now the Go security team explains why the notes were vague, how the fix shipped hours after they were alerted, and its plan for revocation checking on Linux. Roland Shoemaker (Go Team) IN BRIEF: 🔒 golang.org/x/net v0.62.0 fixes two bugs in its html package: a quadratic slowdown on crafted input and a raw text rendering flaw. Filippo Valsorda has proposed friendlier crypto/aead packages for symmetric encryption, plus crypto/cobblestone for messages too big to hold in memory. 𝕏 Emma Twersky, familiar to many from Angular's DevRel team, now leads Frameworks and Languages DevRel at Google, covering Go alongside Flutter and Dart. 🔒 Go on Linux and CVE-2026-98432: Patch Your Kernel — Go enables Multipath TCP by default for listeners in apps whose main module declares go 1.24 or later. Anthropic's remote root exploit for a new Linux kernel bug used such a listener, but the bug isn't MPTCP-specific. Update your kernel, as GODEBUG=multipathtcp=0 is only "a fragile mitigation". Neal Patel (Go Security Team) 💡 An issue that proposes Go turn the default off is open, but the Go team says any change would be premature for now. The issue is ultimately with Linux, not Go. Go Concurrency Distilled — A handy interactive refresher where Anton boils Go's numerous concurrency concepts and mechanisms down into a single page, covering everything from channels and select to context, synctest and the scheduler, with examples you can edit and run in place. Anton Zhiyanov 📊 Measuring Go 1.28's HTTP/2 'Parking' Memory Savings — Thanks to a change by Brad Fitzpatrick, an idle HTTP/2 server connection in Go 1.28 can let its serve goroutine exit. With 5,000 idle connections, a dev build ran 5,000 fewer goroutines and used about 40% less RSS. Mohammad Abdolirad Proposal: Let go test Run Your Project's Own Analyzers — //go:analyze directives would add custom analyzers to go test, and libraries could ship checks that run on packages that import them, like vet checks Printf calls. It's still early but being actively discussed. Alan Donovan (Go Team) đŸ“ș Profiling Go with pprof: Flame Graphs and Memory Leaks – A quick, six minute primer that finds a CPU hog and leak in an app. HĂŒseyin Babal 📄 Partial Updates in Go with Field Masks – How to separate update intent from values in PATCH requests. Redowan Delowar 📄 Where Go 1.27's HTTP/1 Connection Reuse Stops Working Lleg 🛠 Code & Tools gohawk: Static Analysis for Leaks and Lock Bugs — Finds leaked files, unjoined goroutines, unreaped processes and lock inversions, using Infer-style function summaries to track ownership across packages. It's a young project, but has already led to merged fixes in Moby and Caddy. (GitHub repo.) James Ko TinyGo 0.44: Smaller, Faster, Better — The Go compiler for microcontrollers and WebAssembly now does more init work at compile time for smaller binaries that start faster, drops needless slice bounds checks, and adds multicore goroutines on the ESP32-S3. Support for the Arduino Uno R4 also brings TinyGo's first Renesas CPU support. The TinyGo Team You Chose Go for Simplicity. Keep Your Data Stack Simple Too — TimescaleDB extends Postgres with compression and continuous aggregates. Your Go code doesn’t change. Get $1000 credit. Tiger Data (creators of TimescaleDB) sponsor noalloc: Keep Your Hot Paths Allocation-Free — Mark a function with //noalloc:root and this CLI checks its call tree for heap allocations, flagging offending lines. It's a days-old, AI-written experiment that borrows an idea from OxCaml's zero_alloc. Phil Eaton (The Consensus) 🔒 Echo 5.4.4 – The popular web framework has had four patch releases in eight days, including a fix for a critical access control bypass in its proxy middleware's WebSocket handling. go-json 0.12 – Fast encoding/json-compatible library. Adds a jsontext package and an early encoding/json/v2-style API. cel-go 0.33 – Google's Common Expression Language for Go gets an opt-in parser that's 8-19x faster. Huma 2.40 – Framework for building HTTP APIs with OpenAPI 3 specs. mockery 3.9 – The popular mock generator for Go interfaces. (Docs.) 📱 Elsewhere in the ecosystem ✹ Richard Seroter, Google Cloud's Chief Evangelist and the exec with product and engineering responsibility for Go, 𝕏 says Go has just become the most-used language on Google Cloud by raw SDK API requests, with Java not far behind. Before 'distributed SQLite' became a busy, venture-funded category, there was rqlite, built in Go in 2014. Its creator tells the story of the ecosystem's growth. Lisette is a Rust-inspired language with algebraic data types, pattern matching and no nil that compiles to readable Go and can call Go packages directly. ⚠ A reminder that the 2026 Go Developer Survey closes for submissions on November 3, so there are a few more days to have your say. https://golangweekly.com/issues/622 #nearlyfour #fouryears #wails #weeklywails #team #builddesktop #securityteam #desktopapps #webviews #linux #rss #feeds #linksharing #qwibbit

#nearlyfour #fouryears #wails #weeklywails #team
GoWire
GoWire 4d

Our Response To The eMudhra Key Disclosure Incident The Go Blog Our Response To The eMudhra Key Disclosure Incident Roland Shoemaker, on behalf of the Go Security team 26 October 2026 On October 19, the Go team initiated an expedited security release to protect Go users and their applications from a critical public key infrastructure (PKI) compromise involving certificates issued by eMudhra. Within approximately seven and a half hours of being notified, we shipped a targeted patch, which was included in our first-ever URGENT track security release. Here is the context behind the incident, why Go stepped in at the runtime level to protect our users and how our incident response unfolded. eMudhra Incident On October 17, Mozilla added eight intermediate certificates (six used for TLS, and two used for code signing) issued by a root certificate controlled by eMudhra to OneCRL, effectively blocking their usage in Firefox. Soon after, a number of security researchers noticed this and began investigating what might’ve caused this. On October 19, the Go Security team was made aware of these investigations and their conclusions, which showed that the keys associated with these intermediates were trivially weak, allowing recovery of the private keys in microseconds. Due to the fact that the eMudhra root certificate was present in most trusted root programs, recovering the private keys would allow any attacker to sign arbitrary TLS certificates for any domain name, without the usual requirement to show proof of control of said domain name. This would allow an attacker to man-in-the-middle (MITM) TLS connections and present a valid certificate for a domain name they did not control, effectively allowing them to impersonate any TLS server the targeted machine attempted to connect to. Go ships a TLS certificate verifier in the standard library. When users use net/http or crypto/tls to connect to a TLS service, the verifier is called to check if the certificates the other side of the connection presents are valid. On Windows and macOS we delegate these checks to the platform APIs, and on Linux, which lacks platform APIs, we use our own verifier implementation. Since Linux does not have a uniform built-in mechanism to handle revocation checking, and in order to provide a timely fix for users on other platforms that might not receive platform updates, we decided the best way to protect Go users was to do an URGENT track security release which similarly removed trust. Incident Timeline A typical Go security release follows a multi-day process, with advanced pre-announcements in order to allow those who rely on Go to prepare. In this case, because we believed that private key exposure was imminent, our team chose to use the URGENT track for the first time in order to ship protections before active public exploitation could begin. 11:45 PDT Our Security team was alerted by an independent external researcher, citing unreported actions by Mozilla and other organizations to remove trust in eight eMudhra intermediates. It became clear quickly that this was due to weak private keys they used. 12:30 PDT Mozilla independently reported the issue to our Security team, confirming the issue, and asking that we not immediately disclose the issue, but encouraging us to release a fix as soon as possible. 14:00 PDT We finalized a patch which blocked the usage of certificates which chained to the compromised intermediates, and thanks to the researcher who initially alerted us to the issue, had a set of certificates signed using the recovered keys to test against. 15:00 PDT We began the process to release minor Go versions 1.27.3 and 1.26.10 containing our patch. Due to the urgent nature of this issue and its exploitability, and with the belief that the private keys would likely become publicly known within hours, we decided an immediate release was the most prudent option. 19:13 PDT We finalized the release and announced it publicly. At this time the underlying issue was still not widely known. In an effort to give other defenders a chance to protect as many users as possible without revealing to attackers how the issue could be exploited, our patch and communications were somewhat opaque, warning users that we were “blocking trust in a small set of intermediate certificates due to specific security concerns around their operation” and urging users to immediately upgrade to this release. In under seven and a half hours from initial notification, patched Go releases were live worldwide, giving users everything they needed to secure their deployments before the keys became public. By the morning of October 20, numerous independent researchers had publicly disclosed the weak keys. Lessons Learned and Future Improvements This was our first ever URGENT track security release, and during the release process we ran into a number of issues which caused the release to take longer than expected. While we are happy we were able to get a release out the same day we were notified of the issue, in the modern security environment we feel that we should be able to provide releases in a more compressed timeline. The issues we ran into caused our release process to take just under four and a quarter hours from start to finish. These issues had previously not been problematic, since the typical release process is split up over a number of days. We’ve subsequently made a number of changes to improve our release efficiency, which should significantly reduce the time it takes us to push out a release, enhancing our ability to quickly respond to urgent security threats. PRIVATE track security fixes are pre-announced three to seven days before their release. URGENT track fixes happen on a shorter time schedule, but we could have pre-announced the upcoming release when we began the release process, giving users at least a few hours to prepare. While on Windows and macOS we rely on the revocation mechanisms the platform APIs provide, on Linux we don’t currently have a similar mechanism. The lack of this support was one of our major drivers to issue an expedited security release, as we did not want to leave Linux users exposed to this issue longer than was necessary. Hence we are planning on prioritizing work to bring parity to revocation support on Linux, to help mitigate this class of issues in the future. Part of this work will involve investigating adding support for the upki project, which aims to “provide reliable, privacy-preserving and efficient certificate revocation” for Linux (see issue #82402). Upgrading and Verifying Your Deployments If you run Go binaries which interact with network services using TLS (such as directly via net/http or crypto/tls or via a dependency such as gRPC), ensure you are running on the latest minor releases. Binaries rebuilt with Go 1.27.3 and 1.26.10 will automatically reject certificates issued by the compromised eMudhra intermediates. You can verify your current toolchain version using go version and you can check the version of Go a binary was built with using go version -m . The govulncheck tool can also be used to determine if a binary is affected by this issue: $ GOTOOLCHAIN=go1.27.3+auto go install golang.org/x/vuln/cmd/govulncheck@latest $ govulncheck -mode=binary Securing Go Deployments Everywhere For us, securing Go and its users extends beyond fixing direct security vulnerabilities in the runtime and libraries we ship. In order to keep the ecosystem secure, we believe we also need to provide users with the right tools to write secure software, look towards the future of cryptographic algorithms and protocols, and proactively respond to ecosystem wide issues when we can. We are grateful to the independent security researchers and the Mozilla security team for this rapid notification and coordination during this incident. Previous article: Help set Go's priorities for next year Blog Index https://go.dev/blog/emudhra-incident #rss #feeds #linksharing #qwibbit

#82402 #rss #feeds #linksharing #qwibbit
GoWire
GoWire 7d

Why Go had to hardcode a block on broken certs #​621 — October 23, 2026 Read the Web Version Go Weekly Interactive Refactoring in gopls — LSP refactorings can't 'ask' you anything, so "Add struct tags" in gopls just guessed json and camelCase. gopls can now pop up dialogs to collect your input. It uses a stateless, form-like protocol extension the Go and Dart teams have proposed as an LSP standard. Hongxiang Jiang (Go Team) 💡 For now it works in VS Code, with Neovim and Emacs support at proof-of-concept stage. A Move declaration refactoring is coming soon, with Change signature to follow. Deploy Self-Healing Apps on Kubernetes — Learn Kubernetes by building a real production setup. Erik Reinert takes you from a local Kind cluster to Amazon EKS with health probes, autoscaling, safe rollbacks, and GitOps with Argo CD. Master.dev sponsor đŸš« Go Hardcodes a Block on Broken eMudhra Certs — Eight intermediate CA certificates had trivially recoverable private keys, so Go 1.27.3 and 1.26.10 now refuse chains through them. It's hardcoded because, as Filippo Valsorda notes, Linux trust stores have no way to pass revocations on to apps. The Go Team IN BRIEF: đŸ“ș The GopherCon Europe 2026 talks are now online, including ▶ using Go to build for the Sega Dreamcast(!) and a ▶ panel with the Go team. 🇼🇳 GopherCon India 2026 takes place in Hyderabad on November 22, with tickets now on sale. Fiber has marked its v2 module as deprecated, so Go's tooling will now nudge v2 users toward Fiber v3. GO 1.28 & PROPOSALS: Go 1.28 will let you omit a composite literal's type when the context supplies it (so p = {1, 2} will work). iter.Seq could gain Map and Filter methods now that Go has generic methods, with a new proposal's thread already debating where to stop. Fold? Keys? Map2? net/http is getting Server.HandleRequest (accepted last week), while maps.Grow and an RSS-based memory profile for runtime/pprof are both likely accepts. Better HTTP/1 Connection Reuse — You can now (mostly) stop draining HTTP/1 response bodies in Go 1.27 as the client now drains the leftovers in the background, within limits, making io.Copy(io.Discard, resp.Body) helpers largely redundant when you close the body. Nicholas Husin and Damien Neil (Go Team) 💡 The release notes add a caveat the post skips: programs that let idle connections pile up (say, with MaxIdleConns set to 0 or a new Client per request) may get slower. SIMD and Go: How the New Packages Work Under the Hood — A heavily illustrated tour of Go's experimental SIMD support, covering what vector instructions actually do, the operations offered by simd/archsimd and the new portable simd package, and how the compiler turns them into machine code. JesĂșs Espino One Less System to Operate. Everything in SQL — TimescaleDB extends Postgres so your metrics and app data share one database and one SQL join. Get $1000 credit. Tiger Data (creators of TimescaleDB) sponsor 📄 Spinning is a Bounded Bet: Why Go Hides Its Spinlocks – Part one of a four-part series on spinning versus parking. Alex Rios 📄 ConcurrentML: Improving on Go's Concurrency Model – Makes the case for composable events as a fix for the limits of select. Nikhil Marathe 📄 Cutting a Go Git Server's RAM Usage by Two-Thirds – Using pprof to take a push from 617MB to 199MB. Xe Iaso (Tigris) 📄 Why a Healthy Go Heap Can Still Get OOM-Killed in Kubernetes Gulcan Topcu 📄 Dancing Backwards with Go: Why TDD Feels Weird John Arundel 🛠 Code & Tools MyGo: Build Desktop Apps in Go with No Cgo Required — Build macOS, Windows and Linux apps with a UI drawn on the GPU from pure Go, or a web frontend in the system webview that calls Go via a generated TypeScript client. Apps can be just a few megabytes. GitHub repo. EGOIST TinyGo 0.43: Go for Microcontrollers and WebAssembly — The Go compiler 'for small places' closes more gaps with regular Go, adding testing/synctest, parallel tests, panic recovery on Wasm, and more. Much of the work comes from Jake Bailey of TypeScript's Go port fame. The TinyGo Team 💡 For some TinyGo fun, Hoani Bryson's Trick Shot II won this year's Nokia 3310 Jam, built on his own Go engine that even runs on a Pico inside a real 3310. coregex: A Faster Drop-In Replacement for regexp — Brings the multi-engine design of Rust's regex crate to Go, with lazy DFA, PikeVM, one-pass matching and SIMD prefilters. The author claims 15–240x speedups. Andrey Kolkov 💡 The standard library may close some of that gap: a port of RE2's lazy DFA to regexp is up for review, with early benchmarks showing big performance improvements. gopls 0.24 – The official Go language server moves to LSP 3.18 and adds hover, highlighting and references in Go assembly files (interactive refactoring is covered in the feature at the top of the issue). GoReleaser 2.19 – The release automation tool graduates several experimental features and adds tunable zstd compression for archives. fasthttp 1.76 – The fast HTTP package gets extra hardening against request smuggling and message-framing attacks. decimal 1.6 – Arbitrary-precision fixed-point decimals, now with Sqrt, Root and BSON Decimal128. chi 5.5 – Lightweight router, now with RFC 9745 deprecation middleware. 📰 Classifieds Build your Golang app faster. WarpBuild runners are twice as fast at half the cost. Get $50 in free credits with code START50. CodeAF, an open-source coding harness written in Go: #1 of ten on DeepSWE on the same model, at 2x to 25x less per fix than the others. đŸȘ Send webhooks from your Go service in minutes. Svix handles retries, signing, delivery logs, and a portal for your customers. ⭐ And finally
 Help Set Go's Priorities with the 2026 Go Developer Survey — The Go team uses the results to decide what to work on. Last year, the top frustration was keeping Go code idiomatic and following best practices, which led to the rewritten go fix in Go 1.26 and more modernizers in 1.27. Cameron Balahan (Go Team) https://golangweekly.com/issues/621 #rss #feeds #linksharing #qwibbit

#1 #rss #feeds #linksharing #qwibbit
GoWire
GoWire 9d

Help set Go's priorities for next year The Go Blog Help set Go's priorities for next year Cameron Balahan, on behalf of the Go team 21 October 2026 Hi Gophers! The 2026 Go Developer Survey is now open. We run this survey every year to understand how you use Go and the challenges you face. Your answers directly shape how we plan and prioritize our work. Last year, 5,379 of you responded, and your top frustration was making sure your code follows best practices and Go idioms (33% of respondents). Since then, we shipped a rewritten go fix in Go 1.26 that automatically modernizes your code, and added more modernizers in Go 1.27. You can read everything we learned in the 2025 results. Take the survey here. It’s open through November 3, takes about 10–20 minutes, and every question is optional. We’ll share the results on this blog in early 2027. Please share the survey with your colleagues, friends, and online communities—the more Go developers we hear from, the better we understand what you need. Thank you for helping shape the future of Go! Previous article: Interactive refactoring in gopls Blog Index https://go.dev/blog/survey2026-announce #nextyear #cameronbalahan #set #survey #blogindex #october #developersurvey #gophers #november #interactive #rss #feeds #linksharing #qwibbit

#nextyear #cameronbalahan #set #survey #blogindex
GoWire
GoWire 14d

Interactive refactoring in gopls The Go Blog Interactive refactoring in gopls Hongxiang Jiang 16 October 2026 When editing code in a modern IDE or editor, developers rely on its refactoring features to automate common transformations. Today, we are excited to introduce interactive refactoring in gopls, powered by a new capability we are proposing for the Language Server Protocol (LSP) that brings dynamic, multi-step dialogs directly into your favorite editor. Crucially, we designed this capability (in collaboration with the Dart team) not just for Go, but as an open standard for all programming languages and editor ecosystems. Working support is already available in gopls v0.24.0 and the official Go extension for VS Code v0.56.0. What is the Language Server Protocol (LSP)? The LSP is an open standard that decouples language-specific features from specific text editors. As you navigate and edit code, your editor (such as VS Code, Neovim, or Emacs) and a language server (like gopls) engage in a continuous JSON-RPC exchange to provide features like autocomplete, hover documentation, diagnostics, and code actions. Multi-step code transformation Today, almost every code transformation in the LSP is like a function of no parameters: you trigger the operation, and the server immediately computes the edits. (Renaming a symbol is the sole exception: because it is a function of one parameter, the desired new name, it required its own dedicated PrepareRename RPC in the protocol.) "Add struct tags", without questions The language server must deduce the user’s intent from context alone, namely the cursor position and the enclosing syntax tree. When that context is not enough, the server is forced into one of two choices: apply a one-size-fits-all default, or refrain from offering the transformation altogether. The limitation lies not in gopls’s ability to compute the necessary edits, but in the LSP’s lack of a mechanism for language servers to ask the user for input. For many transformations, this parameterless model works well. But many others need additional input from the user: which struct tags to add and in what naming convention, which interface to implement, which file to move a declaration to. Without a way to ask, gopls could only guess—“Add struct tags”, for example, always produced json tags in camelCase—or not offer the refactoring at all. With interactive refactoring, language servers can now easily provide new operations with one or more parameters. "Add struct tags", with questions While some language extensions have worked around this limitation by embedding custom, language-specific dialog logic directly into individual editors, doing so leaves behind other editors (such as Neovim and Emacs) that stick strictly to the LSP with minimal custom client code. More importantly, editor-specific workarounds go against the fundamental purpose of the LSP: to decouple language-specific features from editors so that each server improvement benefits every client. Our LSP interactive refactoring proposal (microsoft/language-server-protocol#1164) solves this by establishing a standard mechanism for language servers to collect user input before computing text edits. For Go developers, this unlocks a suite of long-awaited refactorings, including: golang/go#70583: Move Declaration golang/go#38028: Change Signature golang/vscode-go#1547: Implement Interface golang/vscode-go#2002: Modify Struct Tags among many others. Interactive refactorings in action Adding and removing struct tags (gopls v0.23.0) When configuring serialization formats, developers frequently need custom tags and casing conventions. Previously, running “Add struct tags” unconditionally injected json tags using camelCase formatting. With interactive refactoring: Place your cursor on any struct definition and select the “Add struct tags” code action. An input dialog appears, pre-filled with json, allowing you to customize any combination of tags (such as json,yaml,db). A second dialog lets you select your desired naming convention (such as camelCase, snake_case, or PascalCase). Gopls generates and applies the formatted struct tags across your type definition. Interactive "Add struct tags" in VS Code Here is the before-and-after transformation: type UserProfile struct { ID int64 FirstName string LastName string EmailAddr string } type UserProfile struct { ID int64 `json:"id" db:"id"` FirstName string `json:"first_name" db:"first_name"` LastName string `json:"last_name" db:"last_name"` EmailAddr string `json:"email_addr" db:"email_addr"` } Similarly, “Remove struct tags” now asks you for the specific tag keys you wish to delete (for example, removing only db tags while preserving the json tag), rather than wiping out all struct tags indiscriminately. Interactive "Remove struct tags" in VS Code Implementing interfaces with dynamic symbol search When creating a type to satisfy an interface, developers previously had to copy the interface declaration and manually turn it into a set of methods on the receiver type (or rely on external tools like impl by manually typing the receiver and qualifying the name of the interface). Since gopls v0.23.0, with interactive refactoring: Place your cursor on any concrete type and select the “Add methods to X to implement an interface
” code action. A text entry field appears, inviting you to choose the name of an interface type. It makes dynamic queries to gopls to auto-complete names of types in your workspace and the standard library (for example, maphash.Hasher). If the selected interface has type parameters, gopls asks for a concrete type argument for each type parameter (such as Foo). Gopls generates complete method stubs with appropriate receiver names and instantiated method signatures. Interactive "Add methods to implement an interface..." in VS Code type Foo struct{} type MyHasher struct{} type Foo struct{} type MyHasher struct{} // Equal implements [maphash.Hasher]. func (m *MyHasher) Equal(x Foo, y Foo) bool { panic("unimplemented") } // Hash implements [maphash.Hasher]. func (m *MyHasher) Hash(*maphash.Hash, Foo) { panic("unimplemented") } Moving declarations across files and packages (preview) Moving declarations manually by cutting and pasting can easily break references and requires tedious import cleanup across multiple files. While scheduled for an upcoming gopls release, our working implementation already demonstrates how interactive file selection streamlines cross-file and cross-package moves: Place your cursor on any top-level declaration and select the “Move declaration X” code action. A file picker dialog lets you choose an existing destination .go file or specify a new file path. Gopls moves the declaration along with its dependent declarations (such as unexported helpers or methods) while leaving unrelated symbols in place, updates references across your workspace, and cleans up imports in both the source and destination files. Interactive "Move declaration" in VS Code In the example below, we move the type Foo from package from to package to. Its method Print and the unexported constant bar, which only Foo uses, move along with it, while the unrelated function Baz stays behind: // from/from.go package from import ( "fmt" "strings" ) const bar = "bar" // Doc comment for Foo type Foo struct{} func (f Foo) Print() { fmt.Println(bar) } func Baz() string { return strings.ToUpper("baz") } // from/from.go package from import "strings" func Baz() string { return strings.ToUpper("baz") } // to/to.go package to import "fmt" const bar = "bar" // Doc comment for Foo type Foo struct{} func (f Foo) Print() { fmt.Println(bar) } Slaying the dragon (gopls v0.24.0) As a demonstration of multi-step interactive dialogs and a self-contained test case for client editor implementations, gopls v0.24.0 offers a “Slay the dragon” code action when you place your cursor on a package-level variable named dragonSlayer (for example, var dragonSlayer string). Happy hunting! What’s on the Horizon Interactive refactoring establishes a foundational capability in gopls, opening up several exciting directions on our roadmap: Change signature refactoring (#38028): Adding, removing, or reordering function parameters across a workspace requires input that cannot be deduced from syntax alone, such as the new parameter order or the default argument expression to insert at existing call sites. Interactive forms allow gopls to collect these details before rewriting the declaration and all call sites. Interactive conflict resolution: When a code transformation encounters naming collisions, identifier shadowing, or ambiguous references, gopls can ask the user for guidance, such as asking for permission to proceed or offering to rename conflicting symbols on the fly. Interactive commands beyond code edits: Because interactivity is modeled at the LSP command layer, it naturally generalizes to non-edit server operations that require user configuration, such as configuring test or benchmark runs with profiling flags (CPU, memory, tracing). Getting Started and Sharing Feedback Interactive refactoring is available in gopls v0.24.0 and vscode-go v0.56.0 (with proof-of-concept client integrations also explored for Neovim and Emacs). We would love to hear your thoughts as we continue refining interactive code actions in gopls: For general feedback or feature requests, file an issue on the Go issue tracker. To read the full technical specification—including the stateless form protocol design and alternative approaches we explored—or to join the discussion with the broader LSP community, check out the LSP Interactive Code Actions design document and the ongoing conversation in microsoft/language-server-protocol#1164. (Special thanks to Alan Donovan, Alex Putman, Brian Wilkerson, Danny Tuppeny, Hana Kim, Madeline Kalil, Peter Weinberger, and Robert Findley for their insights, discussions, feedback, and collaboration on this work.) Happy refactoring! Previous article: Better HTTP/1 connection reuse Blog Index https://go.dev/blog/interactive-refactoring #rss #feeds #linksharing #qwibbit

#38028 #rss #feeds #linksharing #qwibbit
GoWire
GoWire 15d

Building cgo code without a C compiler? #​617 — September 11, 2026 Read the Web Version Go Weekly Could Go Build cgo Packages Without a C Compiler? — Cross-compiling with import "C" can be painful as it needs a C toolchain. This proposal would let packages that only call pre-built C libraries describe the interface in annotated Go files, so anyone building the package wouldn't need a C compiler. Matloob, Mui, et al. (Go Team) 💡 Another approach is to skip cgo entirely, which the SIMD and Ebitengine items later in this issue do in two quite different ways
 Become a Confident Go Backend Engineer — Build a production-grade Go backend and learn by coding. Practice the skills you need to guide your AI coding agents. Hands-on online training from the authors of Watermill. Opens in the coming weeks. Join the waitlist. Three Dots Labs sponsor How Debian Code Search Got Fast TurboPFor in Pure Go with SIMD — One for performance fans! A detailed write-up of using Go’s experimental simd/archsimd package to replace a C library with native Go that runs faster. Covers PGO surprises, generics for compile-time specialization, AVX2/AVX512 kernels, and more. Michael Stapelberg IN BRIEF: 🎉 JetBrains recently held a Go 1.27 'release party' featuring some of the Go team. ▶ Watch the recording here, including Robert Griesemer who explains why generic methods took so long to arrive. Long-time contributor thepudds (a.k.a. PJ) has joined the core Go team. Russ Cox is a fan, saying "What a great hire for the Go team." Go 1.28 seems likely to reject string(x) for integers other than byte or rune, in line with go vet's warnings. (Rob Pike proposed this 14 years ago!) Jake Bailey has some CLs in review to make encoding/json/v2 marshal slices ~4% faster than v1, after Daniel Lemire found it 1.5x slower recently. đŸ•č Ebitengine 2.10: Now Pure Go on Desktop Platforms — After years of effort, the popular 2D game engine no longer needs cgo on macOS, Linux or BSD (joining Windows in this regard) so cross-compilation is a lot easier. There’s also a new ability to run apps as a controllable guest process, either headlessly for testing or embedded into other apps. Hajime Hoshi 💡 The cgo-free approach is made possible by purego, the Ebitengine team's library for calling C functions from Go without cgo. Open Source Hits Frontier-Level Code Review at a Tenth of the Cost — PR-AF places #2 of 42 on Martian's Code-Review-Bench. Verified findings only, self-hosted, any open model. AgentField.ai sponsor 📄 Four Ways to Do Super Fast Packet Processing in Go – AF_PACKET, AF_XDP, DPDK and Mellanox Direct Verbs compared, with real throughput numbers, and a library wrapping them. Andree Toonk 📄 Sloc Cloc and Code: Did I Just Get Buster Scrugged? – A tale of profiling scc after a Rust rival counted code 2.5x faster, and winning back the lead. Ben Boyter 📄 Implementing Type Contracts via Mutually Referencing Type Parameters Nick Tobey (DoltHub) 📄 I Contributed to Go: Here's How You Can Too Alex Pliutau 📄 The 14-Year Road to encoding/json/v2 Yoshi Yamaguchi 🛠 Code & Tools gomodjail 2.0: An Experimental Jail for Go Modules — From the creator of Lima comes an interesting way to confine Go dependencies: mark a module with a comment in go.mod and a gomodjail analyze check fails if it can reach the filesystem, network, raw syscalls, etc. Akihiro Suda VHS 0.12: The 'Home Video Recorder' for Your CLI — A tool and scripting language for performing actions on the terminal that get recorded into an animated GIF, MP4, WebM, or PNG frames. Great for demos or tutorials. v0.12.0 lets you size the output by rows and columns (instead of just pixels). Charm đŸ€– yzma 1.26: Local LLM Inference from Go, Now in the Browser — Run vision and language models from Go through llama.cpp with no cgo required (thanks to purego and ffi). Notably, v1.26.0 adds WebAssembly support, so a TinyGo build can run inference directly on a web page. The Hybrid Group go-oracledb: An Official Pure Go Driver for Oracle Database — It's beta for now, but interesting to see an official Go client from Oracle. The established third party options are go-ora (also pure Go) and godror (which uses Oracle’s client libraries via cgo). Oracle 📰 Classifieds Your Go stack is minimal. Your data layer can be too. TimescaleDB extends Postgres for metrics and analytics. Get $1000 credit. Software Engineer - Join our "kick ass" team! Our software team operates from 17 countries and we're looking for more exceptional engineers to join our team. 🔊 Oto 3.5 – Library to play audio on multiple platforms. Used by Ebitengine, it's now cgo-free on Linux and BSD using PulseAudio, with an ALSA fallback. gofumpt 0.12 – Stricter formatter for Go that enforces additional rules beyond gofmt. Now based on Go 1.27's gofmt but works on Go 1.26 and up. go-tui 0.20 – Build declarative terminal UIs with a React-inspired approach. workers-go 0.35 – Run HTTP servers written in Go on Cloudflare Workers. 🌐 TZF 2.0 – Fast timezone finder from lat/long coordinates. go-brrr 1.1 – Pure Go Brotli compression/decompression. https://golangweekly.com/issues/617

GoWire
GoWire 15d

Generic Methods The Go Blog Generic Methods Mark Freeman 26 August 2026 Generics was a profound change for Go—it fundamentally expanded the kinds of programs that gophers could write by adding type parameters to the language. One could now express generic types and functions in Go. These constructs decreased the need for specialized data types and functions, reducing program verbosity and improving the ergonomics of the language in those cases. To illustrate, different kinds of linked lists could now be condensed into a single type definition: // before Go 1.18 type ListOfInts struct { elem int next *ListOfInts } type ListOfStrings struct { elem string next *ListOfStrings } // ... // after Go 1.18 type List[E any] struct { elem E next *List[E] } Likewise, sorting different kinds of ordered data could be expressed as a single function: // before Go 1.18 func SortInts(s []int) { /* ... */ } func SortStrings(s []string) { /* ... */ } // ... // after Go 1.18 func Sort[E cmp.Ordered](s []E) { /* ... */ } However, no such capability came to methods. The generics proposal reasoned that because generic interface methods are difficult to implement efficiently (discussed later), it didn’t make sense to add type parameters to non-interface (or “concrete”) methods either. In that view, methods are primarily the means of implementing an interface. Go 1.27 takes a different view and consequently adds generic methods to Go. In this post, we’ll explain this change of view and demonstrate some uses of this new feature. Methods for organization Methods enable organizing functionality around types. To illustrate, let’s reconsider the linked list from above (adding some conveniences): type List[E any] struct { elem E next *List[E] } func NewList[E any](elems ...E) List[E] { /* ... */ } func (List[E]) String() string { /* ... */ } Suppose that one wanted to map this structure to hold a value of some other type, like a string. A method like ToString would do: func (List[E]) ToString(f func(E) string) List[string] { /* ... */ } By providing a “transform” function f, ToString can be customized with “off-the-shelf” routines. For example, strconv.Itoa might work for a List[int]: func main() { fmt.Println(NewList(1, 2, 3).ToString(strconv.Itoa)) // [1 2 3] } For a List[[]byte], more options come to mind (depending on the use case): func main() { l := NewList([]byte("Hallo Welt"), []byte("Helló világ")) fmt.Println(l.ToString(hex.EncodeToString)) // [48616c6c6f2057656c74 48656c6cc3b32076696cc3a167] fmt.Println(l.ToString(base64.StdEncoding.EncodeToString)) // [SGFsbG8gV2VsdA== SGVsbMOzIHZpbMOhZw==] } Note that parameterizing List allowed generalization of the source type, but not the destination type, since that depends on the transformation being applied. This might be reasonable with just a single destination type, but what if there were many? In Go 1.18, a generic function could be used for this: // after Go 1.18 func MapList[E, R any](l List[E], f func(E) R) List[R] { /* ... */ } But using a function has the disadvantage of moving MapList into the package scope—if many data types support mapping operations, things could get crowded. Furthermore, chained calls must be written “inside out”: func main() { fmt.Println(MapList(MapList(NewList(0, 2, 4), add(2)), divideBy(2))) // [1 2 3] } Because Go 1.18 didn’t support generic methods, we needed a generic function as a workaround. This is now remedied in Go 1.27: // after Go 1.27 func (List[E]) Map[R any](f func(E) R) List[R] { /* ... */ } This is compact, expressive, and locally scoped. Additionally, chained calls are more readable, as they can be written more naturally from left to right: func main() { fmt.Println(NewList(0, 2, 4).Map(add(2)).Map(divideBy(2))) // [1 2 3] } Prefer the “inside out” form? A method expression can convert any method, including a generic one, into its function equivalent. Thus, a function call structure can be recovered if desired: func main() { f := List[int].Map[int] fmt.Println(f(f(NewList(0, 2, 4), add(2)), divideBy(2))) // [1 2 3] } Generic methods, like other generics in Go, must be instantiated (either explicitly or implicitly) before they are used (called or converted to a function). Decoupling things If one views methods also as an organizational tool, then Go 1.18’s reasoning appears overly restrictive. While a generic concrete method can’t help implement an interface (without generic interface methods), it can still be useful for code organization. In other words, these concerns can be decoupled. To elaborate, let’s consider a simple interface: type I interface { M() } type T struct{} // a struct, not an interface func (T) M[P any]() { /* ... */ } // a generic *concrete* method Here, T.M is parameterized by P. Any instantiation of T.M would result in a method signature identical to that of I.M: func main() { T{}.M[int]() } Both T.M[int] and I.M have the signature func M(). However, this doesn’t mean T implements I. Interface implementation is a property of a (possibly instantiated) type, not of any particular method. Importantly, T does not declare T.M[int], but rather its generic (and thus uninstantiated) counterpart T.M. For T.M to participate in interface implementation, there would need to exist a suitable generic method I.M: type I interface { M[P any]() // a generic *interface* method } type T struct{} func (T) M[P any]() { /* ... */ } Since the Go 1.27 syntax doesn’t allow interface methods to declare type parameters, this code is impossible to write. But why can’t Go have generic interface methods? To understand, a bit of a detour is needed. The trouble with generic interface methods An interface value is a box that can hold some other value—the boxed value can be of any type, as long as that type implements the interface. This means that the declared methods on the type are a superset of those declared on the interface. To illustrate, T implements I below: type I interface { M() } type T struct{} func (T) M() { /* ... */ } One can call methods on interface values: func main() { F(T{}) } func F(i I) { i.M() // "backed" by T.M } Above, it’s easy to observe that the call to i.M will be routed to T.M. But in more complex programs, the relation between an interface value method call and its possible targets is significantly less obvious. This relation typically spans across packages, making it difficult or impossible to deduce in the general case. To illustrate, let’s introduce a package boundary: // -- package main -- import "p" func main() { p.F(T{}) } type T struct{} func (T) M() { /* ... */ } // -- package p -- func F(i I) { i.M() } type I interface { M() } Because the two packages are compiled separately, the main package won’t know how p.F uses T{}. To ensure the existence of any method that p.F might call, the compiler generates code for all non-generic methods of a type at its declaration (or instantiation). That way, regardless of what p.F does with T{}, the necessary code will exist at runtime. Now, suppose that I.M were generic: // -- package main -- import "p" func main() { p.F(T{}) } type T struct{} func (T) M[P any]() { /* ... */ } // -- package p -- func F(i I) { i.M[int]() } type I interface { M[P any]() } Again, the main package won’t know how p.F uses T{}—including how it might instantiate T.M. To handle any usage of T{} inside p.F, the compiler would need to instantiate T.M with every possible type argument. This is impractical with Go’s approach to instantiation, wherein the compiler generates specific code for each method based on the type arguments. If method arguments were “boxed” (i.e. passed as values of their constraint interfaces), each instantiation would share the same code. This would avoid having too many instantiations at the cost of indirect call overhead—even for direct calls to instantiated methods. Conclusion Go 1.27 introduces type parameters on concrete methods—this feature has been highly desired by the Go community, as it permits more ergonomic and readable code. Although we can’t support generic interface methods, we decided that allowing type parameters for concrete methods was still worthwhile. We hope you enjoy using Go’s generic methods and find helpful ways to use them in your projects! Next article: Goroutine Leak Profiles Previous article: Go 1.27 is released Blog Index https://go.dev/blog/generic-methods

GoWire
GoWire 16d

Platform-independent SIMD in Go The Go Blog Platform-independent SIMD in Go David Chase and Junyang Shao 24 September 2026 Go 1.26 and 1.27 include experimental APIs for Single Instruction Multiple Data (SIMD) operations. SIMD is a native feature of many modern CPUs that allows software to perform uniform operations across vectors of data very quickly, such as adding 8 pairs of float64 values in a single instruction. It can significantly speed up many computationally-intensive tasks, ranging from cryptography to data processing to AI. In fact, Go’s Green Tea garbage collector even makes use of SIMD to accelerate scanning memory for live objects. Prior to these new experimental APIs, the only way to access this functionality from Go was by writing Go assembly. This was only worth it for truly performance-critical compute kernels, which meant plenty of software that could benefit from SIMD simply left a lot of the CPU unused. Go 1.26 introduced a SIMD API for amd64, and Go 1.27 added APIs for arm64 (specifically NEON) and wasm. However, a basic challenge for a SIMD API is the enormous variation between platforms, not simply in what operations they support, but even in how vectors are represented. Some platforms provide fixed-size vectors, typically between 128 bits and 512 bits, while on others the vector size isn’t known at build time and must be queried when the program starts. To provide full access to the breadth of these platforms, these APIs live in an architecture-dependent archsimd package. But Go 1.27 goes beyond these architecture-dependent APIs and introduces an experimental, fully portable, platform- and size-agnostic SIMD interface, loosely based on Highway for C++. The goal is to support write-once near-asm-performance “simd” code on platforms with SIMD support, and to provide a competent emulation on those platforms that do not (yet) have SIMD support. The simd package currently supports AVX, AVX2, and AVX512 on amd64, NEON on arm64, and wasm’s SIMD instructions. Motivation: variation among SIMD architectures SIMD architectures vary in several dimensions. Some provide a single fixed vector size (wasm, PowerPC, and s390x, 128 bits). Some provide several fixed vector sizes (amd64, with 128, 256, and 512; loong64 with 128 and 256). Riscv64 supports vectors of unspecified size between 128 and 65536 bits, though the length is limited to powers of 2. Arm64 supports one fixed size (128 bits, NEON), and one variable size (128-2048 bits, powers of two only, SVE). On a given instance of a particular architecture, determining what sizes that particular instance happens to support requires feature checks: amd64, but is it AVX, AVX2, or AVX512? Arm64, but is it NEON or SVE? If SVE, how large? Which variant of SVE: SVE, SVE2, or SVE2.1? Different SIMD architectures vary in how they handle vector masking. For vectors, if-then-else across a vector can be implemented with masks; do the operation, but only assign the result (or load, or store) where the mask is “true”. Some SIMD variants do not provide masks; all operations work across all elements, and “masking” is done with vector bitmasks and vector boolean operations (wasm, AVX, AVX2, NEON). Some provide special mask registers, with one bit governing operations on one vector element (AVX512 and RVV). Others (SVE) allocate one bit per vector byte, but the least-significant bit of each element’s mask bits governs masked operations. AVX2 also supports masked loads and stores, but using a plain vector as the mask, and with the most-significant bit governing the operation. A third source of variation is in the operations themselves. Each architecture provides its own primitives for rearranging vector elements; some require constant inputs, others support variable inputs. Different SIMD architectures support different crypto-related operations. Even basic arithmetic can have varying support; for example wasm lacks comparisons for vectors of 64-bit integers. Even for a given vector length on a particular architecture, instruction support depends on “features” that must be checked. Even though Go’s architecture-dependent archsimd package was designed to be as uniform as possible across architectures, many of these quirks remain, and make designing, writing, and testing code for multiplatform SIMD onerous. We could do more in the archsimd package to make the different architectures appear more similar, but we can only go so far without compromising efficiency. Overview The new simd package hides these differences by removing fixed-size vectors from the type system, and by only supporting those operations that are in the intersection of all the different platforms, and fills gaps in the intersection with efficient emulation in terms of other SIMD instructions. The goal is a set of operations that is adequate to support many data processing algorithms that benefit from a vectorized implementation (but are not tied to a particular vector size), is as efficient as assembly language when the source code operations match the underlying hardware, is otherwise emulated as well as possible, and is easy to read and understand (even/especially if an LLM ends up writing the code). On platforms that lack SIMD instructions or that lack support in archsimd, all of the operations are emulated, so that code written using the simd package will always run. To use this experimental package, set GOEXPERIMENT=simd at build time, just like using the experimental archsimd package. The simd vector types are just capitalized, plural, primitive types, for example simd.Uint8s or simd.Float32s. Vectors are loaded from and stored to slices, for example: // innerProduct returns the inner product of x and y. func innerProduct(x, y []float32) float32 { var a simd.Float32s var i int for i = 0; i < len(x)-a.Len()+1; i += a.Len() { u := simd.LoadFloat32s(x[i : i+a.Len()]) v := simd.LoadFloat32s(y[i : i+a.Len()]) a = u.MulAdd(v, a) } if i < len(x) { u, _ := simd.LoadFloat32sPart(x[i:]) v, _ := simd.LoadFloat32sPart(y[i:]) a = u.MulAdd(v, a) } return sum(a) } // sum returns scalar sum of elements of x. func sum(x simd.Float32s) float32 { s := make([]float32, x.Len()) x.Store(s) var r float32 for _, e := range s { r += e } return r } This example also shows one of the limitations of the first experimental release of this package; because there’s no common way to sum across all the elements of a vector, it’s not supported by simd in Go 1.27, though ReduceSum will appear in the next release so sum can be replaced with just simd.ReduceSum. SIMD comparisons produce mask values, which are specific to the corresponding vector element width, so that comparisons of Int8s produce Mask8s, etc., and mask values can be used to select and filter vectors. Supported simd package operations as of Go 1.27 In this table, V and U are vector types, M is a mask type, E is a scalar type, and W is a width. Package-Level Load / Broadcast Functions Function Int8s Int16s Int32s Int64s Uint8s Uint16s Uint32s Uint64s Float32s Float64s LoadV([]E) V Y Y Y Y Y Y Y Y Y Y LoadVPart([]E) (V, int) Y Y Y Y Y Y Y Y Y Y BroadcastV(E) V Y Y Y Y Y Y Y Y Y Y Store/String operations (x V).Method(...) Int8s Int16s Int32s Int64s Uint8s Uint16s Uint32s Uint64s Float32s Float64s Store(s []E) Y Y Y Y Y Y Y Y Y Y StorePart(s []E) int Y Y Y Y Y Y Y Y Y Y String() string Y Y Y Y Y Y Y Y Y Y Arithmetic operations (x V).Method(...) V Int8s Int16s Int32s Int64s Uint8s Uint16s Uint32s Uint64s Float32s Float64s Abs() V Y Y Y Y Y Add(y V) V Y Y Y Y Y Y Y Y Y Y AddSaturated(y V) V Y Y Y Y Average(y V) V Y Y Div(y V) V Y Y IfElse(mask MaskWs, y V) V Y Y Y Y Y Y Y Y Y Y Len() int Y Y Y Y Y Y Y Y Y Y Masked(mask MaskWs) V Y Y Y Y Y Y Y Y Y Y Max(y V) V Y Y Y Y Y Y Y Y Min(y V) V Y Y Y Y Y Y Y Y Mul(y V) V Y Y Y Y Y Y Y Y MulAdd(y V, z V) V Y Y Neg() V Y Y Y Y Y Y Not() V Y Y Y Y Y Y Y Y Or(y V) V Y Y Y Y Y Y Y Y Sqrt() V Y Y Sub(y V) V Y Y Y Y Y Y Y Y Y Y SubSaturated(y V) V Y Y Y Y Xor(y V) V Y Y Y Y Y Y Y Y Boolean and vector masking operations (x V).Method(...) V Int8s Int16s Int32s Int64s Uint8s Uint16s Uint32s Uint64s Float32s Float64s And(y V) V Y Y Y Y Y Y Y Y AndNot(y V) V Y Y Y Y Y Y Y Y CarrylessMultiplyEven(y V) V Y CarrylessMultiplyOdd(y V) V Y IfElse(mask MaskWs, y V) V Y Y Y Y Y Y Y Y Y Y Masked(mask MaskWs) V Y Y Y Y Y Y Y Y Y Y Not() V Y Y Y Y Y Y Y Y Or(y V) V Y Y Y Y Y Y Y Y Xor(y V) V Y Y Y Y Y Y Y Y Comparison operations (x V).Method(...) M Int8s Int16s Int32s Int64s Uint8s Uint16s Uint32s Uint64s Float32s Float64s Equal(y V) MaskWs Y Y Y Y Y Y Y Y Y Y Greater(y V) MaskWs Y Y Y Y Y Y Y Y Y GreaterEqual(y V) MaskWs Y Y Y Y Y Y Y Y Y Less(y V) MaskWs Y Y Y Y Y Y Y Y Y LessEqual(y V) MaskWs Y Y Y Y Y Y Y Y Y NotEqual(y V) MaskWs Y Y Y Y Y Y Y Y Y Y Conversion operations (x V).Method(...) U Int8s Int16s Int32s Int64s Uint8s Uint16s Uint32s Uint64s Float32s Float64s ConvertToFloatW() FloatWs Y ConvertToIntW() IntWs Y Y Y Y Y ConvertToUintW() UintWs Y Y Y Y ToMask() (to MaskWs) Y Y Y Y Mask Methods (m M).Method(...) M) Mask8s Mask16s Mask32s Mask64s And(y M) M Y Y Y Y Or(y V) V Y Y Y Y String() string Y Y Y Y ToIntWs() (to IntWs) Y Y Y Y Shift and rotate operations (x V).Method() V Int8s Int16s Int32s Int64s Uint8s Uint16s Uint32s Uint64s Float32s Float64s RotateAllLeft(dist uint64) V Y Y Y Y Y Y RotateAllRight(dist uint64) V Y Y Y Y Y Y ShiftAllLeft(dist uint64) V Y Y Y Y Y Y ShiftAllRight(dist uint64) V Y Y Y Y Y Zero-cost reshaping operations (x V).Method(...) U Int8s Int16s Int32s Int64s Uint8s Uint16s Uint32s Uint64s Float32s Float64s ToBits() UintWs Y Y Y Y Y Y ReshapeToUint8s() Uint8s Y Y Y ReshapeToUint16s() Uint16s Y Y Y ReshapeToUint32s() Uint32s Y Y Y ReshapeToUint64s() Uint64s Y Y Y BitsToFloatW() FloatWs Y Y BitsToIntW() IntWs Y Y Y Y Transition to/from platform-specific code It may happen that the simd package is too limited for all parts of a particular application, or that we have not yet provided an adequate emulation for some necessary feature. For that case, the simd package supports transition to and from architecture-specific SIMD. Each vector type in the simd package has a conversion method ToArch() returning an any. That any can be type-asserted to one of the architecture-specific types for a platform. To convert back, use one of the simd.FromArch functions. For portable code this creates an obligation to write architecture-specific code for each of the platforms, including an emulation. Here’s a complete example for a method/function that is currently missing, but should be added in Go 1.28. Suppose your algorithm needs Int8s.OnesCount() (which simd in Go 1.27 lacks). Rather than rewriting the entire algorithm for each platform, it’s possible to just implement the missing operation. First, for amd64, which lacks the instruction for AVX and AVX2, but not AVX512: //go:build goexperiment.simd && amd64 package simd_test import ( "simd" "simd/archsimd" ) var popcnt4x16 = [16]int8{0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4} var popcnt4x32 = [32]int8{ 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, } // OnesCount returns the number of one bits for each element. func OnesCount(v simd.Int8s) simd.Int8s { switch x := v.ToArch().(type) { case archsimd.Int8x16: lut := archsimd.LoadInt8x16Array(&popcnt4x16) mask0f := archsimd.BroadcastInt8x16(0x0f) lo := x.And(mask0f) hi := x.ToBits().ReshapeToUint16s().ShiftAllRight(4). ReshapeToUint8s().BitsToInt8().And(mask0f) return simd.Int8sFromArch(lut.PermuteOrZero(lo). Add(lut.PermuteOrZero(hi))) case archsimd.Int8x32: lut := archsimd.LoadInt8x32Array(&popcnt4x32) mask0f := archsimd.BroadcastInt8x32(0x0f) lo := x.And(mask0f) hi := x.ToBits().ReshapeToUint16s().ShiftAllRight(4). ReshapeToUint8s().BitsToInt8().And(mask0f) return simd.Int8sFromArch(lut.PermuteOrZeroGrouped(lo). Add(lut.PermuteOrZeroGrouped(hi))) case archsimd.Int8x64: return simd.Int8sFromArch(x.OnesCount()) default: // GODEBUG=simd=0 emulation return OnesCountEmulated(v) } } The interface conversion and type switch look like they should be inefficient, but the compiler-side implementation of simd specializes code and optimizes away the type switch. NEON and Wasm both support Int8s.OnesCount(), so their implementation is much simpler, though it still uses Int8s.ToArch and Int8sFromArch. //go:build goexperiment.simd && (wasm || arm64) package simd_test import ( "simd" "simd/archsimd" ) // OnesCount returns the number of one bits for each element. func OnesCount(v simd.Int8s) simd.Int8s { // TODO when SVE is added, this won't work switch x := v.ToArch().(type) { case archsimd.Int8x16: return simd.Int8sFromArch(x.OnesCount()) default: // GODEBUG=simd=0 emulation return OnesCountEmulated(v) } } Don’t forget that some people don’t have hardware SIMD support: //go:build goexperiment.simd && !(amd64 || wasm || arm64) package simd_test import ( "simd" ) // OnesCount returns the number of one bits for each element. func OnesCount(v simd.Int8s) simd.Int8s { return OnesCountEmulated(v) } And to complete the exercise, a separate emulation function shared as a fallback across all implementations: //go:build goexperiment.simd package simd_test import ( "simd" ) // OnesCountEmulated returns the number of one bits for each element. func OnesCountEmulated(v simd.Int8s) simd.Int8s { a := [2]uint64{} v.ToBits().ReshapeToUint64s().Store(a[:]) a0, a1 := a[0], a[1] m1 := uint64(0x5555555555555555) m2 := uint64(0x3333333333333333) m4 := uint64(0x0f0f0f0f0f0f0f0f) a0 = (a0 & m1) + ((a0 >> 1) & m1) a1 = (a1 & m1) + ((a1 >> 1) & m1) a0 = (a0 & m2) + ((a0 >> 2) & m2) a1 = (a1 & m2) + ((a1 >> 2) & m2) a0 = (a0 & m4) + ((a0 >> 4) & m4) a1 = (a1 & m4) + ((a1 >> 4) & m4) a[0], a[1] = a0, a1 return simd.LoadUint64s(a[:]).ReshapeToUint8s().BitsToInt8() } API intersection and method emulation Whatever operations the simd package offers need to run acceptably well on most architectures. As a first step, any operation that is supported everywhere, can easily be supported on simd. This tends to include loads, stores, arithmetic, and comparisons (but not all comparisons!). A naive intersection across SIMD methods from different architectures still leaves plenty of holes. These are filled by adding emulations to the various architecture-specific archsimd APIs. These APIs already contain many trivial emulations to simplify life for Go programmers; signed and unsigned integer addition use the same instruction, but in the same way that Go supports the + operator for both int and uint, the archsimd package provides both Int8x16.Add(Int8x16) and Uint8x16.Add(Uint8x16), even though those compile to the same instruction. Modern programming languages also don’t expect programmers to know how to implement floating point negation and absolute value with bit fiddling, so archsimd implements that where necessary, or “emulates” if you look at it just so. There are many emulations that require just 2 or 3 instructions; for example, some architectures support only a same-value shift distance across vector elements, while others support a different shift distance for each vector element. To support scalar shifting in simd, we emulate scalar shift with vector shift. Some architectures lack some unsigned comparisons–these are just signed comparison, plus two XORs with a constant. Not all missing instructions are that simple. The “carryless multiply” instruction is important to cryptography and CRC checksumming, but it isn’t always supported. Leaving that out of the simd API would prevent its use for some important algorithms. Therefore, we provide an emulation, and because one important use is in crypto, its run time does not vary depending on its inputs. In other cases, rather than implement a primitive instruction like “add pairs” (also called “horizontal addition”), for the simd package in the next release we will provide the higher level operation that add pairs is usually used for, which is sum reduction. This also helps insulate users from vector-length dependence; even given the hardware instruction for adding pairs, the number of reduction steps depends on the vector length. The constraint of supporting all platforms, including ones that we predict will appear in archsimd within the next year or so, forces a somewhat conservative approach to which method https://go.dev/blog/simd-experiment

GoWire
GoWire 16d

Arch-specific SIMD in Go The Go Blog Arch-specific SIMD in Go Junyang Shao and David Chase 2 October 2026 Since Go 1.26, we have supported an experimental amd64 SIMD API. Now in Go 1.27, we support two more architectures: arm64 and wasm. The new APIs can be accessed by setting GOEXPERIMENT=simd when building a program. They are defined in the simd/archsimd package. archsimd is the lower-level infrastructure that simd builds on, essentially the intrinsics layer in other languages. For exotic operations that only exist on a specific architecture, users can access them by transitioning from simd to archsimd (via ToArch and FromArch). For details, please refer to the simd blog post. For readers with prior knowledge of SIMD intrinsics in other languages, you might find that our archsimd API does not directly mirror the underlying hardware instructions: We give our APIs sensible names: e.g., instead of _mm512_slli_epi64, we just call it ShiftAllLeft. We leave some architecture details to compiler optimizations rather than exposing them in the API: e.g., instead of _mm512_maskz_add_ps(m, x, y), we optimize x.Add(y).Masked(m) into the same instruction. These design decisions make our APIs smaller and more accessible, and they also happily make the simd implementation much easier. For readers without prior knowledge of SIMD intrinsics, we hope our low-level API is a natural and pleasant journey for you. Please share your feedback and comments. Anything about usability, performance, etc., is appreciated. The parent issue for this project is #73787. What is SIMD SIMD stands for Single Instruction, Multiple Data. SIMD instructions operate on wide registers (128-bit, 256-bit, or more) containing multiple 8- to 64-bit elements, performing operations across all elements in parallel. Wider registers and parallel execution provide a significant performance boost to algorithms that can take advantage of them. Until now, anyone who wanted to use SIMD in Go had to endure the friction of writing assembly language. The new archsimd package is here to change that. Goals The goal is to support as many SIMD instructions across different architectures as possible. Currently, we have amd64, arm64, and wasm available. Our amd64 support has the largest API surface, covering AVX, AVX2, and many AVX-512 extensions. Our arm64 support currently covers NEON, with SVE and some SVE2 already on the way. Our wasm support is also mostly complete, thanks to its well-defined 128-bit SIMD abstraction. Some users might be interested in matrix extensions on certain architectures, such as AMX and SME. We haven’t fully settled on how to represent matrices effectively in Go, so they are not yet supported, but we might support them in the future. API Design and Naming Types The architecture-specific SIMD API is imported from simd/archsimd. archsimd uses distinct struct types, such as Float32x4, Int32x8, or Uint8x16, to signal the shape and element type of each vector, and defines operations as methods on those types. At this moment, archsimd supports only fixed-width vector extensions. Scalable vector extensions like arm64 SVE and RVV will have different struct types to represent vectors. Mask types also come with vector-like shapes, e.g., Mask32x4. Methods Across different vector widths, element types, and architectures, we use the same method name whenever operations are semantically identical: Regardless of vector width or architecture, element-wise addition is simply x.Add(y); the type of x determines which instruction to emit. Instead of 18 different function names for addition, there is only one method name. When instructions on different architectures look similar at a glance but differ in edge-case behavior, we give them distinct names so differences don’t silently bite you. For example, 16-byte table lookup on amd64 (VPSHUFB) zeros the output byte when the index is negative (index < 0) and wraps modulo 16 otherwise, so we call it PermuteOrZero. On arm64 NEON (VTBL) and wasm (i8x16.swizzle), any out-of-range index (index < 0 || index >= 16) zeros the output byte, so we call it LookupOrZero. On amd64, many 256-bit and 512-bit instructions operate independently within 128-bit lanes rather than across the entire register. We explicitly suffix those methods with Grouped (such as InterleaveLoGrouped or PermuteOrZeroGrouped) to make the 128-bit lane boundary obvious. Methods require a receiver value, which doesn’t work for creating a vector from memory or a scalar. For those, archsimd provides package-level functions named with the target vector type: Slices (the default): In Go 1.27, loading and storing slices use the shortest names: archsimd.LoadFloat32x4(s []float32) Float32x4 and x.Store(s []float32). For tail elements that may be shorter than a full vector, archsimd.LoadFloat32x4Part(s []float32) (Float32x4, int) zero-fills the remaining lanes and returns the number of elements loaded, paired with x.StorePart(s []float32) int. Arrays and Broadcasts: Fixed-size array pointers use the Array suffix (archsimd.LoadFloat32x4Array(y *[4]float32) and x.StoreArray(y *[4]float32)), and archsimd.BroadcastFloat32x4(v float32) broadcasts a scalar to all lanes. Type Reinterpretation Reinterpretations are type casts without any cost. SIMD algorithms frequently reinterpret bits across element types and widths. In the Go 1.26 experiment, we implemented this with As methods, which suffered from a quadratic explosion of type pairs and couldn’t generalize to width-agnostic vectors in simd or SVE. In Go 1.27, we replace them with composable zero-cost conversions: ToBits() reinterprets a signed integer or float vector as an unsigned integer vector of the same element width (e.g., Int32x4.ToBits() -> Uint32x4), and BitsToInt32() / BitsToFloat32() converts back. ReshapeToUints() on unsigned vectors changes the element width within the same register width. For example, if x is an archsimd.Uint8x16, then x.ReshapeToUint32s().BitsToFloat32() reinterprets the bits of x as an archsimd.Float32x4 at zero runtime cost. Masks Different architectures encode vector masks very differently, e.g. k mask registers on AVX-512, full vector bitmasks on AVX/AVX2, NEON, and wasm, and predicate registers on SVE. To hide this hardware detail, archsimd provides opaque Mask types (such as Mask32x4) matching each vector shape: Comparisons like x.Greater(y) produce a Mask. x.Masked(m) zeros elements where m is false, and x.IfElse(m, y) (which replaces Merge from Go 1.26) selects elements from x where m is true and from y where m is false. The compiler peepholes mask operations with the surrounding instructions: on AVX-512, x.Add(y).Masked(m) or x.Add(y).IfElse(m, z) compiles into a single zero-masked or merge-masked VPADD instruction; on AVX2, NEON, or wasm, it lowers to the appropriate bitwise AND or blend/bitselect instruction. Examples Portable algorithms like inner product can easily be implemented using the portable simd package, as shown in the companion simd blog post. However, we still expose archsimd to tap into exotic, architecture-specific instructions that do not fit into a portable intersection API, or instructions that can simply do things faster than what simd provides. On amd64, the GFNI extension exposes GaloisFieldAffineTransform operations. Putting aside what a Galois Field is, these operations do a simple thing: // Each element of A is interpreted as a matrix of 8 rows of vectors of 8 bits. // Each element of x is interpreted as a vector of 8 bits. // The b argument is likewise a vector of 8 bits. // The result is z[i] = (A[i/8] * x[i]) + b. // // The matrix * and vector + follow the usual rules for linear algebra, // but based on AND and XOR for scalar * and + // // Asm: VGF2P8AFFINEQB, CPU Feature: AVX512GFNI func (x Uint8x16) GaloisFieldAffineTransform(A Uint64x2, b uint8) Uint8x16 Each 8x8 bit matrix A is packed row-by-row into a single uint64. Because any linear combination or permutation of the 8 bits within a byte can be written as an 8x8 bit matrix, this single instruction is a Swiss Army knife for byte-level bit manipulation. For example, reversing the bit order of every byte (bits.Reverse8) normally requires nibble lookup tables, masks, shifts, and ORs in SIMD. With GaloisFieldAffineTransform, we can simply multiply each byte by the 8x8 anti-diagonal identity matrix (0x8040201008040201) to reverse all 8 bits of 64 bytes at a time in a single instruction: /* Anti-diagonal 8x8 bit matrix (0x8040201008040201): [ 0 0 0 0 0 0 0 1 ] [ x7 ] [ x0 ] [ 0 0 0 0 0 0 1 0 ] [ x6 ] [ x1 ] [ 0 0 0 0 0 1 0 0 ] [ x5 ] [ x2 ] [ 0 0 0 0 1 0 0 0 ] * [ x4 ] = [ x3 ] [ 0 0 0 1 0 0 0 0 ] [ x3 ] [ x4 ] [ 0 0 1 0 0 0 0 0 ] [ x2 ] [ x5 ] [ 0 1 0 0 0 0 0 0 ] [ x1 ] [ x6 ] [ 1 0 0 0 0 0 0 0 ] [ x0 ] [ x7 ] */ func ReverseBits(dst, src []uint8) { if !archsimd.X86.AVX512GFNI() { // A slow fallback emulation impl, details omitted. slowReverseBits(dst, src) return } if len(src) > len(dst) { // Make sure src and dst are the same size src = src[:len(dst)] } revMatrix := archsimd.BroadcastUint64x8(0x8040201008040201) var v archsimd.Uint8x64 var i int for i = 0; i < len(src)-v.Len()+1; i += v.Len() { v = archsimd.LoadUint8x64(src[i : i+v.Len()]) v.GaloisFieldAffineTransform(revMatrix, 0).Store(dst[i : i+v.Len()]) } if i < len(src) { v, _ = archsimd.LoadUint8x64Part(src[i:]) v.GaloisFieldAffineTransform(revMatrix, 0).StorePart(dst[i:]) } } Another example is matrix transpose. On amd64, the permutation instructions are shaped in a non-portable way, so using simd is cumbersome and might incur emulations. An efficient implementation can be written more directly in archsimd. The example below transposes an 8-by-8 matrix of 32-bit integers in registers on amd64 using AVX2’s 128-bit lane-grouped interleaves (InterleaveLoGrouped, InterleaveHiGrouped) and cross-lane permutations (ConcatPermuteScalarsGrouped, ConcatPermute128Scalars): func Transpose8(a0, a1, a2, a3, a4, a5, a6, a7 archsimd.Int32x8) ( b0, b1, b2, b3, b4, b5, b6, b7 archsimd.Int32x8) { if !archsimd.X86.AVX2() { // A slow fallback emulation impl, details omitted. return slowTranspose8(a0, a1, a2, a3, a4, a5, a6, a7) } /* LOW HIGH a0: abcd efgh a1: ijkl mnop a2: qrst uvwx a3: 0123 4567 a4: ABCD EFGH a5: IJKL MNOP a6: QRST UVWX a7: 89yz YZ$@ */ t0 := a0.InterleaveLoGrouped(a1) // t0 = aibj emfn t1 := a0.InterleaveHiGrouped(a1) // t1 = ckdl gohp t2 := a2.InterleaveLoGrouped(a3) // t2 = q0r1 u4v5 t3 := a2.InterleaveHiGrouped(a3) // t3 = s2t3 w6x7 t4 := a4.InterleaveLoGrouped(a5) // t4 = AIBJ EMFN t5 := a4.InterleaveHiGrouped(a5) // t5 = CKDL GOHP t6 := a6.InterleaveLoGrouped(a7) // t6 = Q8R9 UYVZ t7 := a6.InterleaveHiGrouped(a7) // t7 = SyTz W$X@ a0 = t0.ConcatPermuteScalarsGrouped(0, 1, 4, 5, t2) // a0 = aiq0 emu4 a1 = t0.ConcatPermuteScalarsGrouped(2, 3, 6, 7, t2) // a1 = bjr1 fnv5 a2 = t1.ConcatPermuteScalarsGrouped(0, 1, 4, 5, t3) // a2 = cks2 gow6 a3 = t1.ConcatPermuteScalarsGrouped(2, 3, 6, 7, t3) // a3 = dlt3 hpx7 a4 = t4.ConcatPermuteScalarsGrouped(0, 1, 4, 5, t6) // a4 = AIQ8 EMUY a5 = t4.ConcatPermuteScalarsGrouped(2, 3, 6, 7, t6) // a5 = BJR9 FNVZ a6 = t5.ConcatPermuteScalarsGrouped(0, 1, 4, 5, t7) // a6 = CKSy GOW$ a7 = t5.ConcatPermuteScalarsGrouped(2, 3, 6, 7, t7) // a7 = DLTz HPX@ b0 = a0.ConcatPermute128Scalars(0, 2, a4) // b0 = aiq0 AIQ8 b1 = a1.ConcatPermute128Scalars(0, 2, a5) // b1 = bjr1 BJR9 b2 = a2.ConcatPermute128Scalars(0, 2, a6) // b2 = cks2 CKSy b3 = a3.ConcatPermute128Scalars(0, 2, a7) // b3 = dlt3 DLTz b4 = a0.ConcatPermute128Scalars(1, 3, a4) // b4 = emu4 EMUY b5 = a1.ConcatPermute128Scalars(1, 3, a5) // b5 = fnv5 FNVZ b6 = a2.ConcatPermute128Scalars(1, 3, a6) // b6 = gow6 GOW$ b7 = a3.ConcatPermute128Scalars(1, 3, a7) // b7 = hpx7 HPX@ return } Good Practices When walking through the examples above, you might have a few questions: What is archsimd.X86.AVX512GFNI(), and can I omit it? Why is the strided loop written as i = 0; i < len(src)-v.Len()+1; i += v.Len(), instead of i = 0; i + v.Len() <= len(src); i += v.Len()? Why does Transpose8 take 8 vector parameters rather than a struct or an [8]archsimd.Int32x8 array? At first glance these choices might look like minor stylistic preferences, but each of them is chosen for an important performance or correctness reason: CPU feature checks (archsimd.X86.*, archsimd.ARM64.*) On amd64, we provide runtime feature checks like archsimd.X86.AVX(), AVX2(), AVX512(), and extension checks like AVX512GFNI() or AVX512VNNI(); on arm64, NEON is always available, and we provide checks for optional extensions like archsimd.ARM64.PMULL(), SVE(), and SVE2(). The compiler doesn’t know ahead of time whether the machine running your binary supports optional SIMD extensions. If you don’t guard your SIMD code with the appropriate feature check, your program may crash with SIGILL on hardware that lacks the instruction. Just as importantly, CPU feature checks act as compiler optimization hints. For example, AVX-512 supports hardware merge-masking on instruction outputs. How the compiler lowers x.Add(y).IfElse(m, z) on a 128-bit or 256-bit vector depends on which CPU features are known to be available. If the code is not guarded by archsimd.X86.AVX512(), the compiler must conservatively emit a vector VPADD followed by a VPBLEND instruction. Inside an if archsimd.X86.AVX512() block, however, the compiler knows AVX-512 is available and fuses the sequence into a single merge-masked AVX-512 VPADD instruction. Bounds check elimination in strided loops How you write the loop bound determines whether the compiler’s prove pass can eliminate slice bounds checks inside the loop. In i + v.Len() <= len(src), the addition i + v.Len() could theoretically overflow to a negative int if len(src) were near math.MaxInt, which prevents the compiler from proving that i is always non-negative and in-bounds. Writing i < len(src)-v.Len()+1 avoids that potential overflow, allowing the loop body to compile with zero bounds checks. Keeping vectors in registers (avoiding large composite types) Transpose8 passes 8 vector parameters rather than a struct of 8 fields or an [8]archsimd.Int32x8 array because Go’s ABI and SSA backend currently place large composite types in memory rather than in registers (a known issue tracked at #24416). Because SIMD vectors are 16 to 64 bytes each, spilling them to the stack hurts performance much more than spilling scalar values. This applies to both function parameters and local variables, so avoid wrapping SIMD vectors inside large arrays or structs in hot loops. There are ongoing efforts to promote composite memory accesses back into registers, which have not yet landed in Go 1.27. Trying it out In Go 1.27, GOEXPERIMENT=simd supports amd64 (AVX, AVX2, and AVX-512), arm64 (NEON), and wasm (WebAssembly 128-bit SIMD) out of the box. Whether you are on an Intel/AMD machine, an arm64 server or Apple Silicon Mac (M1/M2/M3/M4), or targeting WebAssembly, you can try archsimd natively right away: GOEXPERIMENT=simd go test simd/archsimd/... You can also cross-test wasm (or amd64 via Rosetta emulation on Apple Silicon) by setting GOARCH: # Run wasm SIMD tests using a WASI runtime: GOOS=wasip1 GOARCH=wasm GOEXPERIMENT=simd go test simd/archsimd/... # Or run amd64 AVX2 tests on Apple Silicon via Rosetta: GOARCH=amd64 GOEXPERIMENT=simd go test simd/archsimd/... We’re interested in all sorts of feedback! Early users have already helped us catch bugs (such as #77582) and identify places where code generation or API ergonomics could be improved. We tried hard to pick clear, consistent names and cover the most useful instructions, but archsimd is a massive API surface and there is always room to improve. Future work For Go 1.28 and beyond, we are actively working on completing arm64 SVE and SVE2 support in archsimd (introducing width-agnostic scalable vector types like archsimd.Float32s backed directly by hardware SVE registers and predicates) and wiring it into simd. We also plan to expand archsimd to additional architectures such as riscv64, ppc64, s390x, and loong64, improve register promotion for composite types, and continue filling in instructions and compiler optimizations based on community feedback. Next article: Better HTTP/1 connection reuse Previous article: Platform-independent SIMD in Go Blog Index https://go.dev/blog/archsimd

GoWire
GoWire 16d

Go 1.27's portable SIMD #​619 — September 25, 2026 Read the Web Version 👋 We're taking a break next week, so we'll be back on Friday, October 9. __ Your editor, Peter Cooper Go Weekly Platform-Independent SIMD in Go — SIMD lets a CPU perform an operation on a vector of values at once. Go 1.27 brings experimental SIMD support to arm64 and wasm, plus a portable simd package that emulates SIMD where unavailable, so you don't need to write a plain Go fallback. David Chase and Junyang Shao (Go Team) RELATED: hash/adler32's SIMD implementation is a good, brief example of using SIMD to get over double the speed on larger inputs. Ben Boyter explains how he borrowed fzf's SIMD byte-matching routine to help cut his code search tool's user CPU time by nearly 4x. Sylvain Kerkour shows off 7.5x faster ChaCha20 encryption built on Go's SIMD. Ingest and Analytics in One Postgres. No Pipeline — Go compiles to one binary. Your data layer can be just as lean. TimescaleDB extends the Postgres you already run so ingest and analytics live in one database, not a warehouse and a pipeline. Same SQL, one system to run. Get $1000 credit to start. Tiger Data (creators of TimescaleDB) sponsor 📱 Proposals and Updates How Do You Add a New Keyword to Go? (For Sum Types) — Damien's design for sum types is being actively worked through. The latest sticking point is figuring out how to add a union keyword without breaking existing code or gofmt, with some useful input from Dart's Bob Nystrom. Damien Neil et al. Is Go's FIPS 140 Code Bloating Your Binaries? — Using crypto/rand pulls in extra crypto code even with FIPS off, so WireGuard's creator wants a build-time opt-in. Filippo Valsorda has trimmed some dependencies but argues separate builds would increase testing and maintenance work. Jason A. Donenfeld et al. AND MORE: Tests are getting automatic goroutine labels so profiles and tracebacks show which test, benchmark or fuzz run was responsible. string(x) on arbitrary integers will be restricted to byte, rune, and untyped rune constants in Go 1.28, with the proposal being accepted yesterday. Brad Fitzpatrick is prototyping Mutex.LockChan() so a select can wait on a lock and a channel at once. Just a demo for now. Rhys Hiltner has a stack of CLs to speed up the GC's stop-the-world phase transitions. 🛠 Code & Tools AX: Google's Open Agentic Orchestration Runtime — Designed for large-scale throughput, AX runs AI agents akin to how Kubernetes runs pods. Declare tasks, workspaces, and models in YAML and AX sandboxes the agents and wires it all up. GitHub repo. Jaana Dogan et al. CodeAF: The Open-Source Software Factory for Open Models — Instead of juggling a terminal for every agent, get one window for every project. Many models, one session: the right one for each call. AgentField.ai sponsor 🔎 Hister: A Go-Powered Search Engine for Your Own Stuff — The creator of SearX (and Colly) is back with a self-hosted personal search engine for re-finding your files or pages you’ve visited. GitHub repo. Adam Tauber RobotGo 1.1: Native Cross-Platform GUI Automation — Provides an API to control the mouse and keyboard, read the screen, grab screenshots, etc. on macOS, Windows, and Linux. V Caesar et al. NATS Server 2.15 – High-performance messaging system. There's an upgrade guide for existing users. JetStream stream moves and scaling are now safer to cancel mid-flight, and streams default to a limit of 1,000 consumers. Terratest 2.0 – Write automated tests for your infrastructure code (think Terraform, Kubernetes, Docker, etc). Now split into 16 modules so you only pull in the SDKs you need. (Homepage.) garble 0.18 – A tool to obfuscate Go builds so binaries have "as little information about the original source code as possible". Now requires Go 1.27, with 10-15% faster builds. compress 1.20 – Optimized (de)compression packages, now with support for LZW and Microsoft Xpress. đŸ€– Crush 0.96 – Charm's agentic coding harness now has themes! ⭐ And finally
 The First Official TinyGo Hardware 'Starter Kit' — If you want to do some hardware hacking with TinyGo, this official kit includes a RISC-V board and a variety of modules, along with tutorials for building stuff with it. If you’ve already got some boards or want to source your own, TinyGo also has a list of recommended and supported boards you can use. TinyGo Team and Seeed Studio https://golangweekly.com/issues/619

Welcome to GoWire spacestr profile!

About Me

Go programming, tools, and developer learning. Unofficial automated fan feed. Content belongs to its respective owners; not affiliated with source publishers.

Interests

  • No interests listed.

Videos

Music

My store is coming soon!

Friends