AI News Hub Logo

AI News Hub

Building a Plugin-Based Django Architecture with Horilla’s `AppLauncher`

DEV Community
Horilla

Modern Django applications often start small. But as the platform grows, developers begin facing the same problems: Repeated URL registrations Manual signal imports Scattered Celery configurations Frontend asset duplication Tight coupling between apps and the core project At Horilla Open Source HRMS & CRM, we wanted a more scalable approach for building modular enterprise applications in Django. Instead of treating Django apps as isolated modules, we wanted apps to behave like plugins that could automatically integrate themselves into the platform. That led to the creation of: AppLauncher — Horilla’s Plugin Architecture Layer for Django AppLauncher is a reusable extension of Django’s AppConfig that enables: Automatic URL registration Plugin-style app loading Auto-discovery of signals and menus Dynamic JavaScript asset registration Celery schedule integration Modular HRMS and CRM architecture Scalable enterprise Django development This architecture helps Horilla function not only as an HRMS platform, but also as an extensible Django ecosystem. In a standard Django project, every new app usually requires manual integration. For example: urlpatterns = [ path("crm/accounts/", include("horilla_crm.accounts.urls")), ] class AccountsConfig(AppConfig): def ready(self): import horilla_crm.accounts.signals CELERY_BEAT_SCHEDULE.update(...) This approach works for small projects. But in large-scale systems like: HRMS platforms, CRM software, ERP systems, SaaS applications, multi-module Django platforms, manual wiring creates: duplicated setup, maintenance overhead, tight coupling, onboarding complexity, scalability problems. At Horilla, we wanted new apps to behave like installable plugins. Meaning: apps should self-register, modules should auto-discover themselves, frontend assets should load dynamically, and the core platform should remain untouched. Instead of this workflow: “Add your app manually to multiple core files.” We wanted: “Install the app and it automatically integrates with the platform.” This is the foundation of scalable plugin architecture in Django. AppLauncher Horilla introduces a reusable base class: class AppLauncher(AppConfig): Every modular app extends this class instead of directly inheriting from Django’s AppConfig. Example: class AccountsConfig(AppLauncher): name = "horilla_crm.accounts" url_prefix = "crm/accounts/" url_module = "horilla_crm.accounts.urls" url_namespace = "accounts" js_files = "accounts/assets/js/accounts.js" auto_import_modules = [ "registration", "signals", "menu", "dashboard", ] That is enough to integrate the app into the Horilla platform. No: root URL modifications, manual imports, repetitive startup logic, duplicated initialization code. AppLauncher Works Internally When Django starts, it loads installed applications and calls: ready() Horilla extends this lifecycle hook: def ready(self): self._register_urls() self._register_js() self._auto_import_modules() self._register_celery_schedule() This creates automatic platform-level integration for every app. Apps define: url_prefix = "crm/accounts/" url_module = "horilla_crm.accounts.urls" Horilla dynamically injects URLs into the root URL configuration: urlpatterns.append( path( self.url_prefix, include(self.url_module), ) ) No manual urls.py edits Reduced coupling Easier app installation Better modularity Cleaner large-scale architecture This is especially useful in enterprise Django platforms with many independent modules. Apps declare modules for automatic loading: auto_import_modules = [ "signals", "menu", "dashboard", ] Horilla dynamically imports them: importlib.import_module(f"{self.name}.{module}") This enables: automatic signal registration, dynamic menu loading, dashboard widget discovery, plugin lifecycle initialization. If an app contains: signals.py menu.py dashboard.py Horilla automatically activates them. This follows the powerful software design principle: Instead of manually configuring everything, the framework follows predictable conventions. This approach is used in: Ruby on Rails Laravel VSCode extensions browser plugin systems Apps can contribute frontend assets declaratively: js_files = [ "accounts/assets/js/accounts.js" ] Internally: register_js(self.js_files) This allows Django apps to inject frontend behavior without modifying shared templates. Cleaner frontend architecture Better HTMX/JavaScript modularity Reduced template duplication Easier feature isolation Dynamic UI extensibility Large enterprise systems often require background jobs. With Horilla, apps can ship their own Celery schedules: celery_schedule_module = "celery_schedules" Horilla automatically merges: HORILLA_BEAT_SCHEDULE into: settings.CELERY_BEAT_SCHEDULE Decentralized task management Better app ownership Cleaner background job architecture Easier scaling of scheduled services AppLauncher Changes Django Architecture The biggest architectural shift is this: Core project controls apps Apps extend the platform themselves This transforms Django from: a collection of apps into: a scalable modular platform. Horilla uses this architecture to build: HRMS modules, CRM modules, attendance systems, employee management, recruitment systems, payroll integrations, enterprise workflows. Because apps are plugin-oriented, new business modules can integrate into the platform with minimal core modifications. This dramatically improves: maintainability, developer experience, scalability, onboarding, long-term architecture health. Using AppLauncher, a new app can automatically provide: URLs signals menus dashboards APIs Celery jobs frontend assets startup hooks without modifying the core platform. This creates: self-contained Django apps, reusable enterprise modules, cleaner platform architecture, extensible SaaS foundations. Many Django projects focus only on: models, views, templates. But large-scale platforms require: extension points, lifecycle hooks, auto-discovery systems, registries, plugin loaders, modular conventions. AppLauncher became one of the core abstractions that helped Horilla evolve into a modern modular HRMS platform built with Django. Django already provides excellent architectural foundations through AppConfig. But small abstractions can create massive long-term improvements. By extending Django with plugin-style architecture patterns like AppLauncher, developers can build: scalable enterprise platforms, modular SaaS systems, reusable HRMS applications, extensible CRM ecosystems, maintainable large-scale Django projects. For Horilla, AppLauncher became one of the foundational building blocks enabling platform-level scalability. Horilla Open Source is a modular Django-based HRMS & CRM and enterprise management platform focused on: scalability, extensibility, modern UI architecture, HTMX integration, plugin-based modularity, enterprise workflow management. GitHub: Horilla GitHub Repository Website: Horilla Official Website Dev Community: Horilla on Dev.to LinkedIn: Horilla LinkedIn Page If you are building large Django applications, modular HRMS systems, CRM platforms, or enterprise SaaS products, plugin-style architecture can significantly improve maintainability and scalability.