{"id":15043165,"url":"https://github.com/blackbelttechnology/pandino","last_synced_at":"2026-02-14T16:27:14.335Z","repository":{"id":58477865,"uuid":"438454022","full_name":"BlackBeltTechnology/pandino","owner":"BlackBeltTechnology","description":"An OSGi - lite framework for JavaScript runtimes.","archived":false,"fork":false,"pushed_at":"2024-10-25T04:43:18.000Z","size":4345,"stargazers_count":14,"open_issues_count":5,"forks_count":2,"subscribers_count":8,"default_branch":"develop","last_synced_at":"2024-10-25T17:17:47.750Z","etag":null,"topics":["javascript","micro-frontends","osgi","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"epl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/BlackBeltTechnology.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-12-15T01:18:15.000Z","updated_at":"2024-10-24T14:15:01.000Z","dependencies_parsed_at":"2023-11-19T20:26:19.686Z","dependency_job_id":"cc6d65f5-83a2-493d-b4f3-b0e9e982c470","html_url":"https://github.com/BlackBeltTechnology/pandino","commit_stats":{"total_commits":450,"total_committers":5,"mean_commits":90.0,"dds":0.06444444444444442,"last_synced_commit":"711e767b811c26aacd2288d0b328090bd4b7bb00"},"previous_names":[],"tags_count":32,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BlackBeltTechnology%2Fpandino","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BlackBeltTechnology%2Fpandino/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BlackBeltTechnology%2Fpandino/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BlackBeltTechnology%2Fpandino/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/BlackBeltTechnology","download_url":"https://codeload.github.com/BlackBeltTechnology/pandino/tar.gz/refs/heads/develop","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248955464,"owners_count":21189115,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["javascript","micro-frontends","osgi","typescript"],"created_at":"2024-09-24T20:48:39.378Z","updated_at":"2026-02-14T16:27:14.329Z","avatar_url":"https://github.com/BlackBeltTechnology.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Pandino: OSGi-Style Framework for TypeScript\n\n[![npm version](https://badge.fury.io/js/@pandino%2Fpandino.svg)](https://badge.fury.io/js/@pandino%2Fpandino)\n[![TypeScript](https://img.shields.io/badge/TypeScript-007ACC?style=flat\u0026logo=typescript\u0026logoColor=white)](https://www.typescriptlang.org/)\n[![License](https://img.shields.io/badge/license-EPL2.0-blue.svg)](LICENSE.txt)\n\n\u003e A lightweight TypeScript framework that brings **modular architecture** to your applications. Build loosely-coupled, maintainable applications where different parts can communicate without knowing about each other directly.\n\n## Why Pandino?\n\n**Traditional DI vs Pandino Service Registry:**\n\n| Traditional DI | Pandino Service Registry |\n|----------------|-------------------------|\n| Static dependency injection | Dynamic service discovery |\n| Compile-time wiring | Runtime service resolution |\n| Hard-coded dependencies | LDAP-filtered service selection |\n| Single service per interface | Multiple ranked services |\n| Manual lifecycle management | Automatic service lifecycle |\n\n## Key Features\n\n| Feature | What it Solves | Benefit |\n|---------|----------------|---------|\n| 🔌 **Service Registry** | Hard-coded dependencies between modules | Services discover each other dynamically |\n| 📦 **Bundle System** | Monolithic application architecture | Modular containers with independent lifecycles |\n| 🔄 **Dynamic Dependencies** | Startup order dependencies | Bundles start in any order, dependencies resolve automatically |\n| 📡 **Event System** | Tight coupling between modules | Publish-subscribe messaging with topic-based routing |\n| ⚙️ **Configuration Management** | Static application configuration | Runtime configuration updates without restarts |\n| 🏗️ **Declarative Services** | Complex service wiring boilerplate | Decorator-based dependency injection |\n| ⚛️ **React Integration** | Framework complexity in React apps | Hook-based service discovery in components |\n| 📦 **Rollup Bundle Plugin** | Automated bundling of modules | Simplifies and automates the bundling process |\n\n## 🚀 Quick Concept Demo\n\n```typescript\nimport { Component, Service, Reference, Activate } from '@pandino/pandino';\nimport type { ComponentContext } from '@pandino/pandino';\n\n// 1. Define service interfaces\ninterface UserService {\n  findUser(id: string): User | null;\n  createUser(data: UserData): User;\n}\n\ninterface NotificationService {\n  notify(message: string): void;\n}\n\n// 2. Create service implementations with SCR decorators\n@Component({ name: 'user.service', immediate: true })\n@Service({ interfaces: ['UserService'] })\nclass UserServiceImpl implements UserService {\n  private users = new Map\u003cstring, User\u003e();\n\n  @Activate\n  activate(context: ComponentContext): void {\n    console.log('UserService activated');\n  }\n\n  findUser(id: string): User | null {\n    return this.users.get(id) || null;\n  }\n\n  createUser(data: UserData): User {\n    const user = new User(data);\n    this.users.set(user.id, user);\n    return user;\n  }\n}\n\n@Component({ name: 'notification.service', immediate: true })\n@Service({ interfaces: ['NotificationService'] })\nclass NotificationServiceImpl implements NotificationService {\n  @Activate\n  activate(): void {\n    console.log('NotificationService activated');\n  }\n\n  notify(message: string): void {\n    console.log(`📧 Notification: ${message}`);\n  }\n}\n\n@Component({ name: 'order.service' })\n@Service({ interfaces: ['OrderService'] })\nclass OrderService {\n  // Services are injected automatically when available\n  @Reference({ interface: 'UserService' })\n  private userService?: UserService;\n\n  @Reference({ interface: 'NotificationService' })\n  private notificationService?: NotificationService;\n\n  @Activate\n  activate(): void {\n    console.log('OrderService activated with dependencies');\n  }\n\n  async createOrder(userId: string, items: Item[]): Promise\u003cOrder\u003e {\n    // Dependencies resolved automatically - no imports needed!\n    const user = this.userService?.findUser(userId);\n    if (!user) throw new Error('User not found');\n\n    const order = new Order(user, items);\n    this.notificationService?.notify(`Order confirmed for ${user.email}`);\n    return order;\n  }\n}\n\n// 3. Register components with SCR\nconst scr = context.getService(context.getServiceReference('ServiceComponentRuntime')!);\nconst bundleId = context.getBundle().getBundleId();\nawait scr.registerComponent(UserServiceImpl, bundleId);\nawait scr.registerComponent(NotificationServiceImpl, bundleId);\nawait scr.registerComponent(OrderService, bundleId);\n```\n\n**The Magic:** All three services discover each other automatically. `OrderService` gets both dependencies injected without knowing how they're implemented!\n\n## Packages\n\n| Package | Purpose | Documentation |\n|---------|---------|---------------|\n| [`@pandino/pandino`](./packages/pandino) | Core framework with service registry, bundles, and built-in services | [Core Documentation](./packages/pandino/README.md) |\n| [`@pandino/react-hooks`](./packages/react-hooks) | React integration with hooks and components | [React Documentation](./packages/react-hooks/README.md) |\n\n## Architecture Concepts\n\n### Service-Oriented Architecture\nServices are registered in a central registry and discovered by interface name and properties:\n\n```typescript\n// Register with metadata\ncontext.registerService('DatabaseService', new MySQLService(), {\n  'db.type': 'mysql',\n  'service.ranking': 100\n});\n\n// Discover by capabilities\nconst dbRefs = context.getServiceReferences('DatabaseService', '(db.type=mysql)');\n```\n\n### Bundle Modularity\nBundles are self-contained modules with independent lifecycles:\n\n```typescript\n// Each bundle manages its own services\nconst databaseBundle = {\n  activator: {\n    start(context) { /* register database services */ },\n    stop(context) { /* cleanup */ }\n  }\n};\n```\n\n### Dynamic Dependencies\nOrder doesn't matter - dependencies resolve when services become available:\n\n```typescript\nawait apiBundle.start();      // ✅ Starts immediately\nawait databaseBundle.start(); // ✅ API bundle automatically gets database service\n```\n\n### Extender Pattern\nA pattern where a dedicated bundle (extender) monitors other bundles and provides functionality based on their metadata:\n\n[→ Extender Pattern Documentation](./docs/extender-pattern.md)\n\n### Whiteboard Pattern\nA service-oriented pattern that promotes loose coupling through a central service registry:\n\n[→ Whiteboard Pattern Documentation](./docs/whiteboard-pattern.md)\n\n### Fragment Pattern\nA pattern that allows a bundle (fragment) to attach to another bundle (host) and contribute its resources directly to the host:\n\n[→ Fragment Pattern Documentation](./docs/fragment-pattern.md)\n\n## Use Cases\n\n| Scenario | Traditional Approach | Pandino Approach |\n|----------|---------------------|------------------|\n| **Microservices Architecture** | Hard-coded service URLs | Dynamic service discovery |\n| **Plugin Systems** | Manual plugin loading | Bundle-based plugins with auto-discovery |\n| **Feature Flags** | Code-level toggles | Service-level feature activation |\n| **Multi-tenant Apps** | Complex configuration management | Service filtering by tenant properties |\n| **A/B Testing** | Conditional code blocks | Multiple service implementations with ranking |\n\n## Getting Started\n\nChoose your integration approach:\n\n### Core Framework\n```bash\nnpm install @pandino/pandino\n```\n[→ Core Framework Guide](./packages/pandino/README.md)\n\n### React Integration\n```bash\nnpm install @pandino/pandino @pandino/react-hooks\n```\n[→ React Integration Guide](./packages/react-hooks/README.md)\n\n### Rollup Bundle Plugin\n```bash\nnpm install -D @pandino/rollup-bundle-plugin\n```\n[→ Rollup Bundle Plugin Guide](./packages/rollup-bundle-plugin/README.md)\n\n## Contributing\n\nWe welcome contributions! Please see our [Contributing Guide](./CONTRIBUTING.md) for details.\n\n## License\n\nEclipse Public License - v 2.0\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fblackbelttechnology%2Fpandino","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fblackbelttechnology%2Fpandino","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fblackbelttechnology%2Fpandino/lists"}