Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Modularizing Inertia - Laracon India 2025

Modularizing Inertia - Laracon India 2025

As your product and team grow, you might reach a point where scaling a monolithic application is challenging due to different functionalities being tightly coupled in the same codebase with no boundaries.

Microservices architecture made waves to solve such problems, however, it would bring its own sets of challenges.

A modular monolith can solve those problems without the drawbacks of microservices. A modular monolith is a system where all the functionalities reside in a single codebase, but strictly enforced boundaries exist between different domains.

This talk explains how to modularize an Inertia Laravel application, where each module contains the end-to-end code (backend and frontend) for a specific business domain. It also touches on a useful package that makes managing modules easier.

Ryuta Hamasaki

March 11, 2025
Tweet

More Decks by Ryuta Hamasaki

Other Decks in Technology

Transcript

  1. Well-de fi ned boundaries between services Teams can work on

    their services without a ff ecting each other Can be deployed and scaled independently When a service is down, you can still use other services
  2. class BookingPassengerController { public function create(Booking $booking): Response { return

    Inertia::render('passenger/create', [ 'booking' => $booking, ]); } } BookingPassengerController.php (booking module)
  3. class BookingPassengerController { public function create(Booking $booking): Response { return

    Inertia::render('booking::passenger/create', [ 'booking' => $booking, ]); } } BookingPassengerController.php (booking module)
  4. app.tsx createInertiaApp({ title: (title) => `${title} - ${appName}`, resolve: (name)

    => resolvePageComponent( `./pages/${name}.tsx`, import.meta.glob(‘./pages/**/*.tsx') ), setup({ el, App, props }) { const root = createRoot(el); root.render(<App {...props} />); }, }); app.tsx
  5. app.tsx createInertiaApp({ title: (title) => `${title} - ${appName}`, resolve: (name)

    => resolvePageComponent( `./pages/${name}.tsx`, import.meta.glob(‘./pages/**/*.tsx') ), setup({ el, App, props }) { const root = createRoot(el); root.render(<App {...props} />); }, }); app.tsx
  6. app.tsx createInertiaApp({ title: (title) => `${title} - ${appName}`, resolve: (name)

    => { // If `name` is a `module::page`, return the page from the module if (name.includes("::")) { const [module, page] = name.split("::"); return resolvePageComponent( `../../app-modules/${module}/resources/js/pages/${page}.tsx`, import.meta.glob("../../app-modules/*/resources/js/pages/**/*.tsx"), ); } else { return resolvePageComponent(`./pages/${name}.tsx`, import.meta.glob("./pages/**/*.tsx")); } }, }); app.tsx
  7. app.tsx createInertiaApp({ title: (title) => `${title} - ${appName}`, resolve: (name)

    => { // If `name` is a `module::page`, return the page from the module if (name.includes("::")) { const [module, page] = name.split("::"); return resolvePageComponent( `../../app-modules/${module}/resources/js/pages/${page}.tsx`, import.meta.glob("../../app-modules/*/resources/js/pages/**/*.tsx"), ); } else { return resolvePageComponent(`./pages/${name}.tsx`, import.meta.glob("./pages/**/*.tsx")); } }, }); app.tsx
  8. <html> <head> @routes @viteReactRefresh @if(str_contains($page['component'], '::')) @php [$module, $path] =

    explode('::', $page['component']); @endphp @vite(['resources/js/app.tsx', "app-modules/{$module}/resources/js/pages/{$path}.tsx"]) @else @vite(['resources/js/app.tsx', "resources/js/pages/{$page['component']}.tsx"]) @endif @inertiaHead </head> <body class="font-sans antialiased"> @inertia </body> </html> app.blade.php
  9. <html> <head> @routes @viteReactRefresh @if(str_contains($page['component'], '::')) @php [$module, $path] =

    explode('::', $page['component']); @endphp @vite(['resources/js/app.tsx', "app-modules/{$module}/resources/js/pages/{$path}.tsx"]) @else @vite(['resources/js/app.tsx', "resources/js/pages/{$page['component']}.tsx"]) @endif @inertiaHead </head> <body class="font-sans antialiased"> @inertia </body> </html> app.blade.php