惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

The Last Watchdog
The Last Watchdog
量子位
博客园 - 聂微东
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
有赞技术团队
有赞技术团队
MongoDB | Blog
MongoDB | Blog
Stack Overflow Blog
Stack Overflow Blog
GbyAI
GbyAI
雷峰网
雷峰网
M
MIT News - Artificial intelligence
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - Franky
V
Visual Studio Blog
C
Check Point Blog
爱范儿
爱范儿
罗磊的独立博客
Engineering at Meta
Engineering at Meta
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
小众软件
小众软件
H
Help Net Security
B
Blog
Recent Announcements
Recent Announcements
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
博客园 - 叶小钗
B
Blog RSS Feed
Cisco Talos Blog
Cisco Talos Blog
S
Schneier on Security
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
T
Tor Project blog
TaoSecurity Blog
TaoSecurity Blog
Scott Helme
Scott Helme
AI
AI
D
DataBreaches.Net
Simon Willison's Weblog
Simon Willison's Weblog
V
Vulnerabilities – Threatpost
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
L
Lohrmann on Cybersecurity
C
CERT Recently Published Vulnerability Notes
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Last Week in AI
Last Week in AI
T
Threatpost
Y
Y Combinator Blog
Martin Fowler
Martin Fowler
Know Your Adversary
Know Your Adversary
T
Tailwind CSS Blog
N
News and Events Feed by Topic
N
News and Events Feed by Topic
The Hacker News
The Hacker News
P
Proofpoint News Feed

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python) The Hidden Cost of AI Systems Nobody Talks About. undefined vs undeclared, and how typeof behaves Switching from file-based jobs to NATS/Kafka in Rust without changing code io_uring Adventures: Rust Servers That Love Syscalls Why Agentic AI is Killing the Traditional Database The POUR principles of web accessibility for developers and designers Quantum Neural Network 3D — A Deep Dive into Interactive WebGL Visualization How To Install Caveman In Codex On macOS And Windows Automation Pipeline Reliability: Why Your Workflow Breaks When Nobody Is Watching I Built an 'Open World' AI Coding Agent — It Works From ANY Folder From Freelancing to Product: A Tech Service Company's SaaS Transformation China's AI Giants: Adding Tencent Hunyuan & ByteDance Doubao to AI University (74 Providers) On the Vibe Coders and Their Lies clerk: Auto-Summarize Your Claude Code Sessions AI Weekly — 2026/04/10–04/17 | The Model Lockdown Is Here, but the Toolchain Is the Real Battleground AI 週報 — 2026/04/10–2026/04/17 模型封鎖潮來了,但工具鏈才是真戰場 Maybe this is how Open-Source apps are born... 🚀 Fine-Tune LLMs with LoRA and QLoRA: 2026 Guide tRPC v11 + Next.js App Router: End-to-End Type Safety Without the Boilerplate ShadCN UI in 2026: Why I Stopped Installing Component Libraries and Started Owning My Components SaaS Billing in React Server Components: Stripe + Supabase Without a Single `useEffect` Join our DEV Weekend Challenge — $1,000 in Prizes Across TEN winners! Submissions Due April 20 at 6:59 AM UTC. Implementing FSRS Spaced Repetition in Flutter + Supabase — Adding Memory Science to an AI Learning App "I Texted My Localhost From the Train — Claude Code Fixed the Bug Before I Got Home" I Built a Sales Prep AI and It Went Deeper Than Expected Design to Code #2: One JSON, Eleven Outputs Solving the 100M-Row Problem: A Summary Table Pattern for High-Volume Push Notification Logs Flutter Web With Wasm: What Actually Changes For Developers I Built 50 Royalty-Free Soundtracks for My Side Project in a Weekend Using AI Music Generation The Vibe Coding Security Checklist: 7 Things to Check Before You Ship Stop Letting Googlebot Guess Fix Your React App's SEO Right Desconstruindo o Streaming do LinkedIn: Como Criar um Engine de Extração de Vídeo de Alta Performance com HLS e FFmpeg (EDA Part-1) EDA (Exploratory Data Analysis) Explained With Real Life — Why Looking at Your Data Is the Most Important Step in Machine Learning Brand Relationship Management at Scale: Our 4-Touch Outreach System for 200+ Brands Why String.fromEnvironment() Might Return an Empty String in Dart JGuardrails 1.0.0 — Hardening Java LLM Apps Against Jailbreaks, Toxicity, and Prompt Injection Plan and Schedule a Full Week of Threads Content From One Claude Conversation Coding Cat Oran Ep3, Five Tables Changed Everything Updated: BFF Pattern I'm done watching freelancers get buried by 200 proposals. So I'm building the alternative. This is my first post BFS Algorithm in Java Step by Step Tutorial with Examples Tracking LLM Pricing Monthly: An Open Dataset for 22 AI Models How We Measure Content ROI on a Comparison Site: Revenue Attribution Without Perfect Data Introducing Nova AI Ops: The AI-Native Operating System for SRE Teams I built a free desktop video downloader for Windows — Grabbit How Talkie OCR Helps Vision-Impaired & Dyslexic Users Read the World Around Them VRCFaceTracking安装和iPhone面捕配置教程,有bug Even CrowdStrike Can't See Your Agents The Automation Gold Rush: What n8n Workflows and Claude Are Opening Up for Developers Right Now
gogpu/compose: Multi-Process GUI Composition in Pure Go
Andrey Kolko · 2026-05-17 · via DEV Community

A Raspberry Pi displays a smart mirror. Clock in the top corner. Weather below. Notifications slide in from the bottom. Each panel is a separate process — if weather crashes, the clock keeps ticking.

This is gogpu/compose: a Pure Go library that lets independent processes render UI into offscreen buffers and ship pixels to a single compositor over Unix sockets.

go get github.com/gogpu/compose

Enter fullscreen mode Exit fullscreen mode

The Problem

Desktop applications are monolithic. One process, one crash domain. A bug in the notification panel takes down the entire display.

Wayland solved this at the OS level — every application is a separate client, and the compositor (KWin, Mutter, Sway) combines their surfaces. Android SurfaceFlinger does the same thing for mobile apps.

But what if you need this pattern inside your application? A dashboard where each data source is an independent process. A kiosk where third-party modules render into slots. A plugin host where untrusted code runs in its own crash domain.

There was no Go library for this. You had to roll your own socket protocol, frame encoding, connection management, flow control. Every project reinvented the same plumbing.

What We Built

compose is a two-sided library: a Server (compositor) accepts connections, a Client (module) publishes frames. One import, one socket path.

Module side

client, _ := compose.Dial("/tmp/compose.sock",
    compose.WithName("clock"),
    compose.WithFrameSize(400, 120),
    compose.WithFPS(1),
)
defer client.Close()

client.OnFrameRequest(func() {
    dc := gg.NewContext(400, 120)
    dc.SetRGB(1, 1, 1)
    dc.DrawString(time.Now().Format("15:04:05"), 20, 60)

    client.PublishFrame(compose.Frame{
        Pixels: dc.ImageRGBA().Pix,
        Width:  400,
        Height: 120,
    })
})

Enter fullscreen mode Exit fullscreen mode

Compositor side

srv, _ := compose.Listen("/tmp/compose.sock",
    compose.WithMaxModules(8),
    compose.WithCompression("lz4"),
)

srv.OnFrame(func(f compose.Frame) {
    layout.Place(f.Name, f.Pixels)
})

srv.OnConnect(func(id uint64, name string) {
    log.Printf("module connected: %s", name)
})

srv.OnDisconnect(func(id uint64, name string) {
    log.Printf("module gone: %s", name)
})

Enter fullscreen mode Exit fullscreen mode

That's it. The module renders into a pixel buffer, publishes it. The compositor receives frames, positions them on screen. Hot-plug is automatic — modules come and go without restarting the compositor.

The Wire Protocol

Every frame travels as a 64-byte header followed by pixel data.

┌──────────────────────────────────────────────────────────┐
│ Magic "COMP" │ Version │ MsgType │ Flags                 │
│ ModuleID     │ Sequence              │ Timestamp         │
│ Width │ Height │ Stride  │ DirtyRect (x,y,w,h)           │
│ PixelFormat │ Compression │ PayloadSize │ Uncompressed   │
└──────────────────────────────────────────────────────────┘
64 bytes, little-endian, cache-line aligned

Enter fullscreen mode Exit fullscreen mode

The header is fixed-size — one io.ReadFull call parses it. No variable-length fields, no schema negotiation mid-stream. Encode and decode take under 10 ns and under 25 ns respectively, with zero allocations.

The protocol carries dirty rectangles (only the changed region's pixels), compression flags, and monotonic sequence numbers for frame ordering.

Handshake

When a module connects, it sends a 128-byte HelloMsg (name, dimensions, preferred FPS). The compositor replies with a 128-byte WelcomeMsg (assigned module ID, granted transport). Fixed-size messages — no JSON parsing, no protobuf dependency, no allocation.

LZ4 Compression

GUI pixels compress exceptionally well. Buttons, backgrounds, text labels — large flat-color regions that LZ4 handles at near-memcpy speed.

Frame Size Encode Decode Ratio
400×120 (small module) 2,753 MB/s 1,175 MB/s 99.6% savings
1920×1080 (full HD) 2,728 MB/s 1,446 MB/s varies

A 192 KB module frame compresses to ~810 bytes. At 60 FPS, that's 47 KB/s over the socket — trivial for any transport.

Compression is optional. Static modules (clock, weather) benefit most. Animated modules with random pixel patterns can disable it with a flag in the frame header.

Pull-Based Flow Control

We studied how Wayland handles frame pacing. The compositor sends a frame callback — "I'm ready, give me a frame." The client renders only when asked.

compose follows this pattern:

  1. Compositor → Module: FrameRequest
  2. Module renders → sends Frame
  3. Compositor processes → sends next FrameRequest

If the module is slow, the compositor displays the last frame. If the compositor is slow, the module blocks — no wasted work. After 3 consecutive missed responses, the flow controller halves the request rate (adaptive backoff).

This is the opposite of the naive "push frames as fast as possible" model, which floods slow compositors and wastes CPU on frames nobody will ever see.

Architecture: Enterprise internal/

The public API has fewer than 15 exported declarations — 5 types, 2 constructors, 5 option functions, and a handful of sentinel errors. Everything else is hidden behind internal/ packages:

compose/                        # Public: Listen, Dial, Frame, options
├── internal/protocol/          # Wire format (100% coverage)
├── internal/codec/             # Raw + LZ4 (97% coverage)
├── internal/conn/              # Module lifecycle (98.9% coverage)
├── internal/flow/              # Pull-based pacing (100% coverage)
└── internal/transport/socket/  # Unix sockets (95.1% coverage)

Enter fullscreen mode Exit fullscreen mode

The dependency graph is a clean DAG — protocol is the leaf (imported by all, imports nothing), codec/conn/flow are independent, transport/socket imports only protocol. No cycles possible by construction.

This isn't an accident. We designed compose the way database/sql is designed: public Server/Client wrap internal implementations. Users never import sub-packages. Adding a shared memory transport (Phase 2) won't change the public API — it's a new internal/transport/shm/ behind an existing WithSharedMemory() option.

By the Numbers

Metric Value
Source code 2,897 LOC
Test code 5,619 LOC
Total 8,516 LOC
Test cases 171
Packages 6
Files 38
Coverage (internal avg) 98%
Header encode < 10 ns, 0 allocs
Header decode < 25 ns, 0 allocs
LZ4 encode throughput 2.7+ GB/s
Socket throughput 5.9+ GB/s
Dependencies 1 (pierrec/lz4/v4)
CGO Zero
CI Ubuntu + macOS + Windows
Lint (30+ rules) 0 issues

2× more test code than source code. Every internal package is independently testable with its own benchmark suite.

Who Needs This

Smart mirrors and kiosks. Independent modules (time, weather, transit, notifications) render into slots. A crash in one module doesn't affect the display.

Modular dashboards. Each data source is its own process, possibly developed by different teams. The compositor arranges them on screen.

Plugin hosts. Third-party plugins run in separate processes. The host application composites their output without trusting their code. f4 by @unxed — a full Go reimplementation of Far Manager — already uses --gui=gogpu for GPU-accelerated rendering and has an out-of-process plugin architecture (MessagePack RPC supporting Go, Python, Rust, Node.js, C++, Lua). compose could serve as the pixel transport between f4's plugin host and its GUI modules.

Cross-language UIs. The wire protocol is language-agnostic. A Rust module or a Python script can participate — anything that writes RGBA to a Unix socket.

KiGo by @AgentNemo00 — a modular Go application — is already using offscreen rendering with multi-process composition and is evaluating compose v0.1.0.

These aren't hypothetical users waiting for a stable release. They're building real software on the GoGPU stack right now — and finding real bugs that make the ecosystem better. Every project that adopts GoGPU accelerates the path to enterprise grade. If you have a desktop app, a dashboard, a kiosk, a file manager, an IDE panel — there's never been a better time to try it in Pure Go.

What's Next

Phase 2: Reference examples. Three separate binaries — compositor, clock module, notification module — demonstrating the full multi-process workflow.

Phase 3: Shared memory transport. Triple-buffer ring in mmap'd memory with atomic slot states. Zero-copy pixel transfer for 60 FPS at 1080p. The public API stays the same — you just pass WithSharedMemory().

Phase 4: Delta frames. Send only the dirty rectangle's pixels, not the full frame. The protocol already carries dirty rects in the header — we just need the compositor-side texture cache.

Try It

go get github.com/gogpu/compose

Enter fullscreen mode Exit fullscreen mode

Part of the GoGPU Ecosystem

compose is the newest member of GoGPU — 800K+ lines of Pure Go GPU computing:

Library Purpose
wgpu Pure Go WebGPU (Vulkan/Metal/DX12/GLES)
naga Shader compiler (WGSL → SPIR-V/MSL/GLSL/HLSL/DXIL)
gg 2D graphics with GPU acceleration
ui Enterprise GUI toolkit (22+ widgets, 4 themes)
gogpu Application framework, windowing
compose Multi-process composition (this library)
systray System tray (Win32/macOS/Linux)
audio Pure Go audio engine

Help Us Get to Enterprise Grade

The ecosystem grows faster with every pair of eyes on it. Here's how you can help:

  • Test it. Run go get github.com/gogpu/compose, build a two-process prototype, tell us what breaks. Edge cases on your OS, your hardware, your use case — that's what we can't find ourselves.
  • Validate the API. Does Listen/Dial/PublishFrame feel right? Is the wire protocol missing a field you need? The API is still v0.x — now is the time to reshape it, before it freezes.
  • Propose and discuss. Open an issue or join the compose RFC discussion. Real use cases drive the roadmap — not hypotheticals.
  • Spread the word. Star the repo, share this article, mention it in your Go meetup. The more developers use the ecosystem, the faster it reaches enterprise grade.
  • Contribute. Every PR matters — from typo fixes to new transport implementations. See CONTRIBUTING.md.

The entire GoGPU ecosystem — 800K+ lines of Pure Go — is built by a small team. But the libraries are production-ready enough that people are building real products on them: a Far Manager rewrite with GPU rendering, an ML framework fully migrated to our WebGPU stack, a Quake 1 engine port running on gogpu/wgpu Vulkan (demo), modular app platforms. The more developers who start building on GoGPU — whether it's a new project or porting an existing one — the faster the entire ecosystem matures. Your project's edge cases become our test suite. Your feature requests become our roadmap.

Start building. We'll make sure the foundation holds.


Building what Go "can't do." One library at a time.