Go architectures · 3 MIN READ
Microkernel: a small core with explicit extensions
Extend behavior through contracts without assuming dynamic shared libraries.
Extend behavior through contracts without assuming dynamic shared libraries. A microkernel or plugin architecture keeps a stable core and accepts extensions through a narrow contract. Trace the worked Go example, then compare the benefit with the cost before applying this design to your own project.
Architecture · A MAP OF THE IDEA
- Core defines an extension contract
- Startup registers an implementation
- Core invokes selected behavior
Useful when
- A product supports optional capabilities
- Extensions can follow a stable small contract
Watch out
- Contract evolution affects all extensions
- In-process extensions share the core’s failure domain
Implementation & operation cost: High
Fit depends on the task
Editorial suitability, not benchmarks or a universal ranking. Styles describe different axes and can be combined.
The design decision
A microkernel or plugin architecture keeps a stable core and accepts extensions through a narrow contract. Go can register ordinary functions at startup. This is different from loading shared objects with package plugin, which has platform and build compatibility constraints.
A complete Go example
Read this program from the entry point and follow the calls shown in the diagram. The output is included at the end so you can check the behavior without a compiler.
package main
import (
"fmt"
"strings"
)
type Transform func(string) string
type Core struct{ extensions map[string]Transform }
func (c Core) Apply(name, input string) (string, bool) {
f, ok := c.extensions[name]
if !ok {
return "", false
}
return f(input), true
}
func main() {
core := Core{extensions: map[string]Transform{"upper": strings.ToUpper}}
out, ok := core.Apply("upper", "go")
fmt.Println(out, ok)
}
// Output:
// GO true
The core dispatches through a function contract, and the startup map explicitly selects available behavior. This static registry needs no runtime code loading. Validate duplicate names and extension capabilities when building a larger registry.
Tradeoffs and the simpler alternative
Extensions in the same process can panic, block or access shared resources; an interface is not a security sandbox. Use subprocess or RPC isolation for untrusted extensions. Native plugin loading is not supported by GopherForge’s WASI runtime.
Keep the extension contract narrower than the core
The core owns stable policy and chooses extensions through a small interface or registry. An extension may format, validate or dispatch one capability. Register it explicitly at startup so dependencies and failure are visible. Compile-time implementations and process-isolated extensions are different operational models. Do not assume Go binary plugins are portable across all systems or supported inside the iOS sandbox; the lesson example uses ordinary linked Go values.
Define lifecycle and failure containment
Decide when an extension initializes, whether requests may run concurrently, who closes resources and what happens if initialization fails. A panic in an in-process extension can affect the host; an interface does not create isolation. Untrusted extensions require a real sandbox or process boundary with permissions and time budgets. Version the contract when independently delivered extensions need compatibility checks.
Resist a universal extension API
Test extensions against a shared contract, including invalid configuration and cleanup. Prefer one small extension point justified by a real variation over a generic object bag with string keys and reflection. A registry of two ordinary functions may be enough. A microkernel pays off when third-party or product-specific variation evolves independently; if every extension changes with the core, a direct function call is often easier to understand.
TAKE THIS WITH YOU
Lets a small core invoke explicitly registered behavior. Extensions in the same process can panic, block or access shared resources; an interface is not a security sandbox. Use subprocess or RPC isolation for untrusted extensions. Native plugin loading is not supported by GopherForge’s WASI runtime.
Check your understanding
Which statement best describes Microkernel: a small core with explicit extensions?
Go to the source
Progress stays in this browser. No account needed.