There’s a lot of excitement right now around AI agents, tools, and modular systems.
Define tools.
Describe them well.
Let something else decide when to use them.
Sound familiar?
It should.
Because we’ve been doing this for years | we just called them plugins.
The core idea
A well-designed system doesn’t hardcode features.
Instead, it does one thing at startup:
Load modules (plugins)
That’s it.
No giant Program.cs doing everything.
No tightly coupled feature logic.
Just a host application that loads capabilities dynamically.
Everything is a plugin
In this model:
- Pages → plugins
- UI components → plugins
- Business logic → plugins
- Side effects (logging, API calls, events) → plugins
Even things you don’t normally think about, like routing, become plugins.
Why this matters
When every feature is a plugin:
- Adding a feature → drop in a file
- Removing a feature → delete a file
- Replacing a feature → swap a file
No refactoring. No ripple effects.
This is true modularity.
A simple mental model
Think of your app like this:
App = Host + Plugins
The host:
- Loads plugins
- Provides shared context
- Coordinates execution
Plugins:
- Declare what they do
- Register themselves
- Execute when needed
Mini example using TOPS (stream-oriented)
Let’s make it concrete.
Using a stream-oriented approach like TOPS, everything becomes part of a flow.
Entry point
var app = new App();
app.LoadPlugins("plugins/");
app.Run();
That’s it.
Router plugin
public class RouterPlugin : IPlugin
{
public void Register(IApp app)
{
app.UseRouter(routes =>
{
routes.Map("/", "HomePage");
routes.Map("/about", "AboutPage");
});
}
}
Home page plugin
public class HomePagePlugin : IPlugin
{
public void Register(IApp app)
{
app.RegisterPage("HomePage", ctx =>
{
return "<h1>Home</h1>";
});
}
}
Navbar plugin
public class NavbarPlugin : IPlugin
{
public void Register(IApp app)
{
app.RegisterComponent("Navbar", ctx =>
{
return "<nav>...</nav>";
});
}
}
Now here’s the interesting part:
👉 Remove HomePagePlugin.cs → home page disappears
👉 Remove NavbarPlugin.cs → navbar is gone
👉 Remove RouterPlugin.cs → no routing
No changes anywhere else.
Effects are plugins too
In real systems, it gets more powerful.
Things like:
- Logging
- API calls
- Background jobs
- Event handling
…can all be plugins.
Example:
public class LoggingPlugin : IPlugin
{
public void Register(IApp app)
{
app.OnEvent("RequestStarted", ctx =>
{
Console.WriteLine("Request started");
});
}
}
This is basically how AI tools work
Modern AI systems:
- Define tools (plugins)
- Describe them
- Let the model choose which one to call
That’s not new.
That’s just:
Plugin architecture + dynamic orchestration
The difference is:
- Instead of a developer calling the plugin
- An AI decides which plugin to use
The real takeaway
The important shift isn’t AI.
It’s this:
Capabilities should be decoupled from the core system
Whether it’s:
- a web app
- a backend service
- or an AI agent
The winning pattern is the same:
- Small, focused modules
- Clear contracts
- Easy to add/remove
If you're not doing this yet
Start simple:
- Extract one feature into a module
- Give it a clear interface
- Load it dynamically
You’ll quickly see the benefits:
- cleaner code
- easier testing
- faster iteration
Final thought
AI didn’t invent modular systems.
It just made us realize how powerful they are when something else | not you | decides how to use them.
And if your system is already plugin-based?
You’re already ahead.
Top comments (0)