Introduction
Components are Owl's most powerful system. They attach logic to individual Roblox instances Parts, Models, NPCs, anything using CollectionService tags with a fully automatic per-instance lifecycle. Where a Service is a singleton, a Component is created and destroyed once per tagged instance: tag ten NPCs "Enemy", get ten independent EnemyComponent instances, each with its own state.
Owl vs Knit on Components
| Feature | Knit | Owl |
|---|---|---|
| Components | ✅ | ✅ |
| Based on CollectionService | ✅ | ✅ |
| Per-instance lifecycle | ❌ | ✅ |
| Automatic per-instance Trove | ❌ | ✅ |
| Extensions with hooks | ❌ | ✅ |
| Server/Client/Shared typing | ❌ | ✅ |
| Auto-watch on startup | ❌ | ✅ |
Concept
Tag "Enemy" added to workspace.NPC_Goblin
│
└── EnemyComponent instantiated automatically
├── Construct() - setup, reading Attributes
├── Start() - active logic, connections
└── Destroy() - cleanup (+ auto-destroyed _trove)
Tag "Enemy" removed, or the instance is destroyed
└── Destroy() + _trove:Destroy() automaticallyYou never call Component.new() yourself for each instance and you never manually clean one up either adding the tag creates it, removing the tag (or destroying the instance) destroys it, _trove included. See Creating a Component for the full Construct/Start/Destroy API.
Type: where a Component runs
Every Component declares a Type, which determines where it's active and how it can be watched from the opposite side:
| Type | Context | Watch() from the opposite side |
|---|---|---|
"Server" |
Server only | No-op + warning |
"Client" |
Client only | No-op + warning |
"Shared" |
Both Server and Client | - |
A "Server" Component tracking enemy AI state has no reason to exist on the client and a "Client" Component driving a hover tooltip has no reason to exist on the server declaring Type explicitly means calling Watch() for one from the wrong side fails loudly (a warning) instead of silently doing nothing useful.
Where to go next
- Creating a Component - the full
Construct/Start/Destroylifecycle and how to define one. - Extensions - sharing behavior across Components without duplicating code.
- API Reference - the complete signature:
Added,Removed,GetAlland everyComponent.newoption.