{"slug": "purego", "name": "purego", "category": "dev-libs", "category_name": "Libraries and frameworks", "description": "", "recommenders": 3, "commenters": 5, "warners": 0, "score": 2.981, "rising": -0.98, "first": "2025-12-12", "latest": "2026-05-17", "why": "The purego lib generalizes this idea. I haven't got round to trying this yet but it looks very promising.", "why_is_quote": true, "has_verdict": false, "sentiment": {"recommend": 4, "neutral": 1, "compare": 1, "warn": 0}, "spark": [0, 2, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0], "listed": true, "loved": [], "caveat": "", "short_quote": "The purego lib generalizes this idea. I haven't got round to trying this yet but it looks very promising.", "kind": "", "icon": true, "domain": null, "github_repo": "github.com/ebitengine/purego", "official_url": "https://github.com/ebitengine/purego", "pricing": "", "aliases": ["purego"], "verdict": null, "praise": [{"label": "", "summary": "", "quotes": [{"id": 769106304, "item_id": 48069144, "url": "https://news.ycombinator.com/item?id=48069144", "by": "impulser_", "date": "2026-05-08", "version": null, "stance": "recommend", "quote": "You can just embed the C library into the binary of the Go app call it directly in Go.", "excerpt": "Have you tried purego? You can just embed the C library into the binary of the Go app call it directly in Go. Most of the time I have found calling C from Go faster or on par with calling C from Python. https://github.com/ebitengine/purego", "context": "", "use_case": "Call C from Go", "switched_from": "", "story": "Just Fucking Use Go"}, {"id": 744707552, "item_id": 46544222, "url": "https://news.ycombinator.com/item?id=46544222", "by": "cyberax", "date": "2026-01-08", "version": null, "stance": "recommend", "quote": "If you want to avoid Cgo, you can use https://github.com/ebitengine/purego", "excerpt": "If you want to avoid Cgo, you can use https://github.com/ebitengine/purego or Goffi to call the native functions. It's a bit cursed, but works.", "context": "", "use_case": "calling native functions from Go", "switched_from": "", "story": "Tailscale state file encryption no longer enabled by default"}, {"id": 740052944, "item_id": 46253309, "url": "https://news.ycombinator.com/item?id=46253309", "by": "nickcw", "date": "2025-12-13", "version": null, "stance": "recommend", "quote": "The purego lib generalizes this idea. I haven't got round to trying this yet but it looks very promising.", "excerpt": "That is a nice approach. I'll have to give that a try with rclone. I tried lots of things in the past but not using Alpine which is a great idea Another alternative is https://github.com/ebitengine/purego You can use this to dynamic load shared objects / DLLs so in the OP example they could disable systemd support if the systemd shared object did not load. This technique is used in the cgofuse library ( https://githu", "context": "", "use_case": "dynamic loading shared objects in Go", "switched_from": "", "story": "Go is portable, until it isn't"}, {"id": 740045584, "item_id": 46252849, "url": "https://news.ycombinator.com/item?id=46252849", "by": "cyberax", "date": "2025-12-12", "version": null, "stance": "recommend", "quote": "you can use https://github.com/ebitengine/purego to generate the bindings", "excerpt": "Cgo is terrible, but if you just want some simple C calls from a library, you can use https://github.com/ebitengine/purego to generate the bindings. It is a bit cursed, but works pretty well. I'm using it in my hardware-backed KMIP server to interface with PKCS11.", "context": "", "use_case": "calling C libraries from Go", "switched_from": "", "story": "Go is portable, until it isn't"}]}], "caveats": [], "who": [], "tags": [], "use_cases": ["call c from go", "calling c from go without cgo", "calling native functions from go", "dynamic loading shared objects in go", "calling c libraries from go"], "compared": [], "makers": [], "threads": [{"url": "https://news.ycombinator.com/item?id=46180911", "title": "Go is portable, until it isn't", "mentions": 2}, {"url": "https://news.ycombinator.com/item?id=48142108", "title": "A Few Words on DS4", "mentions": 1}, {"url": "https://news.ycombinator.com/item?id=48062997", "title": "Just Fucking Use Go", "mentions": 1}, {"url": "https://news.ycombinator.com/item?id=47218566", "title": "Goffi \u2013 Pure Go FFI with hand-written assembly for System V, Win64, ARM64", "mentions": 1}, {"url": "https://news.ycombinator.com/item?id=46531925", "title": "Tailscale state file encryption no longer enabled by default", "mentions": 1}], "sentiment_by_month": {"2025-11": {}, "2025-12": {"recommend": 2}, "2026-01": {"recommend": 1}, "2026-02": {}, "2026-03": {"compare": 1}, "2026-04": {}, "2026-05": {"recommend": 1, "neutral": 1}, "2026-06": {}, "2026-07": {}, "2026-08": {}, "2026-09": {}, "2026-10": {}}, "versions": [], "version_unnamed": 0, "quotes": [{"id": 770683810, "item_id": 48167738, "url": "https://news.ycombinator.com/item?id=48167738", "by": "neomantra", "date": "2026-05-17", "version": null, "stance": "neutral", "quote": "Initial release wraps the API using purego", "excerpt": "Literal #showerthought: \"why don't you just make the same thing for ds4, it will be awesome\" Toweled off and got to work: https://github.com/NimbleMarkets/ds4-go The concept is marrying the flexibility of Golang with a specific local high-performance inferencing engine. The clean C interface made it easy. Initial release wraps the API using purego and requires pointing to a DS4 installation. I'm now adding some pre-b", "context": "", "use_case": "", "switched_from": "", "story": "A Few Words on DS4"}, {"id": 769106304, "item_id": 48069144, "url": "https://news.ycombinator.com/item?id=48069144", "by": "impulser_", "date": "2026-05-08", "version": null, "stance": "recommend", "quote": "You can just embed the C library into the binary of the Go app call it directly in Go.", "excerpt": "Have you tried purego? You can just embed the C library into the binary of the Go app call it directly in Go. Most of the time I have found calling C from Go faster or on par with calling C from Python. https://github.com/ebitengine/purego", "context": "", "use_case": "Call C from Go", "switched_from": "", "story": "Just Fucking Use Go"}, {"id": 755497073, "item_id": 47218567, "url": "https://news.ycombinator.com/item?id=47218567", "by": "kolkov", "date": "2026-03-02", "version": null, "stance": "compare", "quote": "purego supports 8 GOARCHes and 20+ OS\u00d7ARCH combinations", "excerpt": "Hi HN! Author here. Some of you may remember the purego discussion from 2023 (https://news.ycombinator.com/item?id=34763681, 268 points). It proved that calling C from Go without CGO is viable. We built on that foundation. Why another FFI library? We needed to call wgpu-native (WebGPU) from Go \u2014 thousands of FFI calls per frame. purego's reflect-based dispatch (RegisterFunc \u2192 reflect.MakeFunc \u2192 sync.Pool per call) wa", "context": "", "use_case": "calling C from Go without CGO", "switched_from": "", "story": "Goffi \u2013 Pure Go FFI with hand-written assembly for System V, Win64, ARM64"}, {"id": 744707552, "item_id": 46544222, "url": "https://news.ycombinator.com/item?id=46544222", "by": "cyberax", "date": "2026-01-08", "version": null, "stance": "recommend", "quote": "If you want to avoid Cgo, you can use https://github.com/ebitengine/purego", "excerpt": "If you want to avoid Cgo, you can use https://github.com/ebitengine/purego or Goffi to call the native functions. It's a bit cursed, but works.", "context": "", "use_case": "calling native functions from Go", "switched_from": "", "story": "Tailscale state file encryption no longer enabled by default"}, {"id": 740052944, "item_id": 46253309, "url": "https://news.ycombinator.com/item?id=46253309", "by": "nickcw", "date": "2025-12-13", "version": null, "stance": "recommend", "quote": "The purego lib generalizes this idea. I haven't got round to trying this yet but it looks very promising.", "excerpt": "That is a nice approach. I'll have to give that a try with rclone. I tried lots of things in the past but not using Alpine which is a great idea Another alternative is https://github.com/ebitengine/purego You can use this to dynamic load shared objects / DLLs so in the OP example they could disable systemd support if the systemd shared object did not load. This technique is used in the cgofuse library ( https://githu", "context": "", "use_case": "dynamic loading shared objects in Go", "switched_from": "", "story": "Go is portable, until it isn't"}, {"id": 740045584, "item_id": 46252849, "url": "https://news.ycombinator.com/item?id=46252849", "by": "cyberax", "date": "2025-12-12", "version": null, "stance": "recommend", "quote": "you can use https://github.com/ebitengine/purego to generate the bindings", "excerpt": "Cgo is terrible, but if you just want some simple C calls from a library, you can use https://github.com/ebitengine/purego to generate the bindings. It is a bit cursed, but works pretty well. I'm using it in my hardware-backed KMIP server to interface with PKCS11.", "context": "", "use_case": "calling C libraries from Go", "switched_from": "", "story": "Go is portable, until it isn't"}]}