Dynamic Loading and Symbols
Loading plugins at runtime and calling exported symbols
Dynamic Loading and Symbols is a free Go Academy lesson on CoddyKit — lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Go Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
plugin.Open
plugin.Open(path) loads a compiled .so file. It initialises the plugin's init() functions and package-level variables, then makes symbols available.
p, err := plugin.Open("./plugins/mymodule.so")
if err != nil { log.Fatalf("load: %v", err) }p.Lookup
p.Lookup(name) finds an exported symbol by name. It returns an any; type-assert to the expected type.
sym, err := p.Lookup("NewProcessor")
if err != nil { log.Fatalf("lookup: %v", err) }
fn, ok := sym.(func() Processor)
if !ok { log.Fatal("wrong type") }Loading multiple plugins
Load each .so from a directory and register them in a loop:
entries, _ := os.ReadDir("./plugins")
for _, e := range entries {
if !strings.HasSuffix(e.Name(), ".so") { continue }
p, err := plugin.Open("./plugins/" + e.Name())
if err != nil { log.Printf("skip %s: %v", e.Name(), err); continue }
loadPlugin(p)
}Factory function pattern
Plugins export a factory function (NewXxx() Processor) rather than a value, so the host gets a fresh instance per call:
sym, _ := p.Lookup("NewProcessor")
factory := sym.(func() Processor)
proc := factory() // new instanceError handling on lookup
Lookup errors mean the symbol is not exported or the name is wrong. Handle gracefully — skip the plugin or log and continue loading others.
plugin.Open is idempotent
Calling plugin.Open on the same path twice returns the same plugin. The plugin is only initialised once.
Lazy loading
Load plugins on demand (first use) rather than at startup to reduce startup time. Use a sync.Once per plugin to ensure it is loaded exactly once.
var mu sync.Mutex
var loaded = map[string]*plugin.Plugin{}
func getPlugin(path string) (*plugin.Plugin, error) {
mu.Lock(); defer mu.Unlock()
if p, ok := loaded[path]; ok { return p, nil }
p, err := plugin.Open(path)
if err != nil { return nil, err }
loaded[path] = p
return p, nil
}Symbol naming conventions
Use capitalised CamelCase names for exported symbols (Go's visibility rule applies). Common convention: Plugin for the main value or New for the factory.
Handling plugin panics
If a plugin panics, the recover middleware in the host may catch it, but the plugin's goroutines may be in an undefined state. Log and skip the plugin; do not retry.
Validating plugin metadata
After loading, check a metadata symbol (e.g., PluginVersion string) to validate compatibility before registering:
ver, _ := p.Lookup("PluginVersion")
if *ver.(*string) != expectedVersion { log.Fatal("incompatible") }Quick Check
What happens if you call plugin.Open twice with the same path?
Recap: Dynamic Loading and Symbols
Key points:
- plugin.Open loads .so; p.Lookup returns any → type-assert
- Load plugins from a directory in a loop for a plugin system
- plugin.Open is idempotent; init() runs once per path
- Prefer factory functions over value symbols for fresh instances
Frequently asked questions
Is the “Dynamic Loading and Symbols” lesson free?
Yes — the full text of “Dynamic Loading and Symbols” is free to read here on the web, and the Go Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Go Academy course, upgrade to CoddyKit PRO.
What will I learn in “Dynamic Loading and Symbols”?
Loading plugins at runtime and calling exported symbols You practise Go Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Go Academy?
No prior experience is required. Go Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 3 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Dynamic Loading and Symbols” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Go Academy lesson?
Yes. Every Go Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Go plugin Package Basics
- Designing a Plugin Interface
- Dynamic Loading and Symbols
- Alternatives: HashiCorp go-plugin