Skip to content

TachUI Plugin Architecture - Simplified v2.0 ​

Overview ​

TachUI's streamlined plugin architecture provides 40-60% bundle size reduction through modular design while maintaining simplicity and performance. The simplified architecture removes over-engineered features in favor of essential, high-performance plugin functionality.

Architecture Components ​

1. Simplified Plugin Manager (simplified-plugin-manager.ts) ​

  • Purpose: Essential plugin lifecycle management
  • Features: Install, uninstall, basic validation
  • Performance: Minimal overhead, fast plugin registration

2. Simplified Component Registry (simplified-component-registry.ts) ​

  • Purpose: Efficient component registration and discovery
  • Features: Component categorization, plugin tracking, bulk operations
  • Performance: O(1) lookups, minimal memory footprint

3. Streamlined TachUI Instance (simplified-tachui-instance.ts) ​

  • Purpose: Central instance with plugin integration
  • Features: Plugin management, component registration, service management
  • Performance: Direct method calls, no event system overhead

Plugin System Benefits ​

Bundle Size Optimization ​

  • Core Only: ~60KB (tachUI Core)
  • Core + Forms: ~95KB (Core + Forms plugin)
  • Full Framework: ~150KB (All plugins)

Applications can choose exactly what they need, achieving 40-60% smaller bundles compared to monolithic frameworks.

Performance Characteristics ​

  • Plugin Installation: <10ms for typical plugins
  • Component Registration: <1ms per component
  • Service Lookup: O(1) constant time
  • Memory Usage: Minimal overhead per plugin

Architecture Diagram ​

TachUI Application
├── Core Framework (60KB)
│   ├── Simplified Plugin Manager
│   ├── Component Registry
│   ├── Service Registry
│   └── Runtime System
│
├── Optional: Forms Plugin (35KB)
│   ├── Form Components
│   ├── Validation System
│   └── Form State Management
│
├── Optional: Navigation Plugin (30KB)
│   ├── Navigation Components
│   └── Routing Utilities
│
└── Optional: Symbols Plugin (15KB)
    └── Icon Components

Usage Examples ​

Basic Plugin Installation ​

typescript
import { SimplifiedTachUIInstance } from '@tachui/core'
import { FormsPlugin } from '@tachui/forms'

const instance = new SimplifiedTachUIInstance()
await instance.installPlugin(FormsPlugin)

Component Registration Pattern ​

typescript
const MyPlugin: TachUIPlugin = {
  name: 'my-plugin',
  version: '1.0.0',
  
  async install(instance) {
    // Register components with metadata
    instance.registerComponent('MyButton', MyButton, {
      category: 'input',
      tags: ['button', 'interactive']
    })
    
    // Register services for shared functionality
    instance.registerService('myService', new MyService())
  }
}

Plugin Discovery and Inspection ​

typescript
// Check plugin installation
if (instance.isPluginInstalled('forms')) {
  console.log('Forms plugin is available')
}

// Discover components by category
const formComponents = instance.components.listByCategory('forms')
console.log('Available form components:', formComponents.map(c => c.name))

// Get system statistics
const stats = instance.getStats()
console.log('System overview:', {
  plugins: stats.plugins.installed,
  components: stats.components.totalComponents,
  services: stats.services.registered
})

Implementation Details ​

Plugin Interface ​

typescript
interface TachUIPlugin {
  name: string                    // Unique identifier
  version: string                 // Semantic version
  description?: string            // Optional description
  install(instance: TachUIInstance): Promise<void> | void
  uninstall?(): Promise<void> | void
}

Component Registration ​

typescript
interface ComponentRegistrationOptions {
  category?: string               // Logical grouping
  tags?: string[]                // Discovery tags
}

Automatic Cleanup ​

  • Components are automatically removed when plugins are uninstalled
  • Services can be manually cleaned up in the uninstall() method
  • No manual dependency tracking required

Migration from Complex System ​

Before (Complex) ​

typescript
const plugin = createPlugin({
  name: 'my-plugin',
  dependencies: ['@tachui/forms'],
  configSchema: { /* JSON schema */ },
  preload: { routes: ['/admin'] },
  
  install(instance, options) {
    const config = options.config
    instance.registerUtility('helper', helper, { namespace: 'my' })
    instance.registerThemeProvider('my-theme', themeProvider)
  }
})

After (Simplified) ​

typescript
const plugin: TachUIPlugin = {
  name: 'my-plugin',
  version: '1.0.0',
  
  async install(instance) {
    instance.registerComponent('MyComponent', MyComponent, {
      category: 'custom'
    })
    instance.registerService('myService', new MyService())
  }
}

Performance Testing Results ​

Installation Performance ​

  • Small Plugin (1-3 components): 2-5ms
  • Medium Plugin (10-20 components): 8-15ms
  • Large Plugin (50+ components): 25-50ms

Memory Usage ​

  • Base Instance: ~2MB
  • Per Plugin: ~200KB average
  • Per Component: ~10KB average
  • Per Service: ~5KB average

Lookup Performance ​

  • Component Discovery: O(1) - <1ms
  • Service Retrieval: O(1) - <0.1ms
  • Plugin Status Check: O(1) - <0.1ms

Best Practices ​

Plugin Structure ​

my-plugin/
├── src/
│   ├── components/          # Plugin components
│   ├── services/           # Shared services
│   ├── types.ts           # TypeScript definitions
│   └── index.ts           # Plugin entry point
├── tests/                 # Plugin tests
└── package.json

Error Handling ​

typescript
const plugin: TachUIPlugin = {
  name: 'error-safe-plugin',
  version: '1.0.0',
  
  async install(instance) {
    try {
      // Plugin registration
      instance.registerComponent('SafeComponent', SafeComponent)
      instance.registerService('safeService', new SafeService())
    } catch (error) {
      console.error('Plugin installation failed:', error)
      throw new Error(`Failed to install ${this.name}: ${error.message}`)
    }
  },
  
  async uninstall() {
    try {
      // Custom cleanup
      await cleanup()
    } catch (error) {
      console.warn('Cleanup error (non-fatal):', error)
      // Don't throw - allow uninstallation to complete
    }
  }
}

Testing Pattern ​

typescript
describe('MyPlugin', () => {
  let instance: SimplifiedTachUIInstance
  
  beforeEach(() => {
    instance = new SimplifiedTachUIInstance()
  })
  
  it('should install correctly', async () => {
    await instance.installPlugin(MyPlugin)
    
    expect(instance.isPluginInstalled('my-plugin')).toBe(true)
    expect(instance.components.has('MyComponent')).toBe(true)
    expect(instance.hasService('myService')).toBe(true)
  })
  
  it('should uninstall cleanly', async () => {
    await instance.installPlugin(MyPlugin)
    await instance.uninstallPlugin('my-plugin')
    
    expect(instance.isPluginInstalled('my-plugin')).toBe(false)
    expect(instance.components.has('MyComponent')).toBe(false)
  })
})

Future Considerations ​

The simplified plugin architecture provides a solid foundation that can be extended if needed:

  • Selective Feature Addition: Add specific advanced features (like dependency resolution) only if compelling use cases emerge
  • Performance Monitoring: Optional performance utilities can be added as separate packages
  • Advanced Loading: Lazy loading can be implemented at the application level using dynamic imports

The key principle is to maintain simplicity while providing the essential functionality needed for modular TachUI applications.

Released under the MPL-2.0 License.