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

  1. Core defines an extension contract
  2. Startup registers an implementation
  3. 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

Small tool or CLI3/5
Domain-rich application4/5
Independent distributed services3/5

Editorial suitability, not benchmarks or a universal ranking. Styles describe different axes and can be combined.

01

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.

02

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.

go
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
Read the code

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.

03

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.

04

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.

05

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.

06

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.