Skip to content

Ecosystem, Community, Packages

08: Ecosystem, Community, Packages Intermediate

Overview

One of Rails' greatest strengths is its ecosystem—the gems, tools, and community resources. Laravel's ecosystem is equally impressive, with thousands of packages, first-party tools, and an incredibly active community.

This chapter explores Laravel's ecosystem from a Rails developer's perspective, showing you where to find packages, how to evaluate them, and which ones are essential.

Prerequisites

Before starting this chapter, you should have:

  • Completed Chapter 07: Testing, Deployment, DevOps or equivalent understanding of Laravel fundamentals
  • Familiarity with package management concepts (Bundler, RubyGems, or npm)
  • Basic understanding of Composer (covered in previous chapters)
  • Estimated Time: ~60-75 minutes

What You'll Learn

  • Composer vs Bundler/RubyGems
  • Essential Laravel packages
  • Laravel's official ecosystem (Forge, Vapor, Nova, Spark)
  • Finding and evaluating packages
  • Creating your own packages
  • Community resources and learning materials
  • Where Laravel excels compared to Rails
  • Migration strategies for common Rails gems

📦 Code Samples

Complete Laravel project with ecosystem packages:

View all code:

bash
git clone https://github.com/dalehurley/codewithphp.git
cd codewithphp/code/rails-developers-love-laravel/chapter-10

Package Management: Composer vs Bundler

Rails: Bundler & RubyGems

ruby
# Gemfile
source 'https://rubygems.org'

gem 'rails', '~> 7.0'
gem 'pg'
gem 'devise'
gem 'pundit'

group :development, :test do
  gem 'rspec-rails'
  gem 'factory_bot_rails'
end

group :development do
  gem 'rubocop', require: false
end

# Install
bundle install

# Update
bundle update

# Show outdated
bundle outdated

Laravel: Composer & Packagist

json
// composer.json
{
    "require": {
        "php": "^8.4",
        "laravel/framework": "^12.0",
        "laravel/sanctum": "^4.0",
        "spatie/laravel-permission": "^6.0"
    },
    "require-dev": {
        "phpunit/phpunit": "^11.0",
        "laravel/pint": "^1.0",
        "pestphp/pest": "^3.0"
    },
    "autoload": {
        "psr-4": {
            "App\\": "app/",
            "Database\\Seeders\\": "database/seeders/"
        }
    }
}
bash
# Install dependencies
composer install

# Add package
composer require spatie/laravel-backup

# Add dev dependency
composer require --dev barryvdh/laravel-debugbar

# Update packages
composer update

# Show outdated
composer outdated

# Remove package
composer remove vendor/package

Key Similarities:

  • Version constraints work the same (^, ~)
  • Separate dev dependencies
  • Lock files (composer.lock / Gemfile.lock)
  • Local and global installs

Key Differences:

  • Composer is faster (parallel downloads)
  • Packagist.org is centralized (like RubyGems.org)
  • Composer has better dependency resolution
  • PSR-4 autoloading (no require statements needed)

Essential Laravel Packages

Authentication & Authorization

Rails:

ruby
# Gemfile
gem 'devise'
gem 'pundit'
gem 'cancancan'

Laravel:

bash
# Laravel Sanctum (API tokens) - Built-in
composer require laravel/sanctum

# Laravel Breeze (Auth scaffolding)
composer require laravel/breeze --dev
php artisan breeze:install

# Laravel Jetstream (Advanced auth with teams)
composer require laravel/jetstream
php artisan jetstream:install livewire

# Spatie Permission (Role/Permission management)
composer require spatie/laravel-permission

Why Laravel is Better Here:

  • ✅ Multiple official auth solutions
  • ✅ API authentication built-in (Sanctum)
  • ✅ Social login easier (Laravel Socialite)
  • ✅ Two-factor authentication included (Jetstream)

File Storage & Images

Rails:

ruby
# Gemfile
gem 'carrierwave'
gem 'paperclip'
gem 'mini_magick'
gem 'aws-sdk-s3'

Laravel:

bash
# Built-in file storage (Flysystem)
# No package needed for basic storage!

# Image manipulation
composer require intervention/image

# Configuration in config/filesystems.php
'disks' => [
    'local' => [...],
    's3' => [...],
    'public' => [...]
]
php
# filename: app/Http/Controllers/FileController.php (example)
<?php

declare(strict_types=1);

// Usage - incredibly simple
use Illuminate\Support\Facades\Storage;

// Store file
$path = $request->file('avatar')->store('avatars', 's3');

// Get file
$content = Storage::disk('s3')->get('avatars/user1.jpg');

// Delete file
Storage::disk('s3')->delete('avatars/user1.jpg');

// Image manipulation
use Intervention\Image\Facades\Image;

Image::make($request->file('photo'))
    ->fit(300, 300)
    ->save(storage_path('app/public/thumbnails/photo.jpg'));

Why Laravel is Better Here:

  • ✅ File storage built into framework
  • ✅ Unified API for all storage (local, S3, FTP, etc.)
  • ✅ No configuration needed for basic use
  • ✅ Simpler API

Background Jobs & Queues

Rails:

ruby
# Gemfile
gem 'sidekiq'
gem 'redis'

Laravel:

bash
# Built-in queue system!
# Just configure .env

QUEUE_CONNECTION=redis
php
# filename: app/Jobs/ProcessPodcast.php
<?php

declare(strict_types=1);

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;

class ProcessPodcast implements ShouldQueue
{
    use Queueable;

    public function __construct(
        public Podcast $podcast
    ) {}

    public function handle(): void
    {
        // Process podcast
    }
}

// Dispatch job
ProcessPodcast::dispatch($podcast);

// Run worker
php artisan queue:work

// Monitor queues with Laravel Horizon
composer require laravel/horizon

Why Laravel is Better Here:

  • ✅ Queue system built-in
  • ✅ No additional gems needed
  • ✅ Laravel Horizon for beautiful monitoring
  • ✅ Multiple queue drivers (database, Redis, SQS, etc.)

Testing & Code Quality

Rails:

ruby
# Gemfile
gem 'rspec-rails'
gem 'factory_bot_rails'
gem 'faker'
gem 'rubocop'
gem 'simplecov'

Laravel:

bash
# PHPUnit built-in!

# Modern testing with Pest
composer require pestphp/pest --dev

# Code formatting (like Rubocop)
composer require laravel/pint --dev

# Static analysis
composer require --dev larastan/larastan

# Browser testing
composer require --dev laravel/dusk

Why Laravel is Better Here:

  • ✅ Testing tools included
  • ✅ Pest provides RSpec-like syntax
  • ✅ Pint (auto-formatter) more opinionated than Rubocop
  • ✅ Laravel Dusk for browser testing built-in

Admin Panels

Rails:

ruby
# Gemfile
gem 'activeadmin'
gem 'rails_admin'

Laravel:

bash
# Laravel Nova (Official, Paid - $199/site)
composer require laravel/nova

# Filament (Free, Open Source)
composer require filament/filament

# Backpack (Free with paid add-ons)
composer require backpack/crud

Laravel Nova Example:

php
# filename: app/Nova/User.php
<?php

declare(strict_types=1);

namespace App\Nova;

use Illuminate\Http\Request;
use Laravel\Nova\Resource;
use Laravel\Nova\Fields\ID;
use Laravel\Nova\Fields\Text;
use Laravel\Nova\Fields\HasMany;

class User extends Resource
{
    public static $model = \App\Models\User::class;

    public function fields(Request $request)
    {
        return [
            ID::make()->sortable(),
            Text::make('Name')->sortable(),
            Text::make('Email')->rules('required', 'email'),
            HasMany::make('Posts'),
        ];
    }
}

Why Laravel is Better Here:

  • ✅ Laravel Nova is more polished than ActiveAdmin
  • ✅ Multiple excellent options (Nova, Filament, Backpack)
  • ✅ Better UI/UX out of the box
  • ✅ More customization options

API Documentation

Rails:

ruby
# Gemfile
gem 'rswag'
gem 'apipie-rails'

Laravel:

bash
# Scramble (Auto-generates OpenAPI/Swagger docs)
composer require dedoc/scramble

# Laravel API Documentation Generator
composer require mpociot/laravel-apidoc-generator

# Scribe (Popular choice)
composer require knuckleswtf/scribe

Scribe Example:

php
# filename: app/Http/Controllers/PostController.php (example)
<?php

declare(strict_types=1);

namespace App\Http\Controllers;

use App\Http\Resources\PostResource;
use App\Models\Post;
use Illuminate\Http\Request;

class PostController extends Controller
{
    /**
     * List all posts
     *
     * Get a paginated list of all posts.
     *
     * @group Posts
     *
     * @queryParam page int Page number. Example: 1
     * @queryParam per_page int Items per page. Example: 15
     *
     * @response 200 {
     *  "data": [{"id": 1, "title": "Post Title"}],
     *  "meta": {"total": 50}
     * }
     */
    public function index(Request $request)
    {
        return PostResource::collection(
            Post::paginate($request->per_page ?? 15)
        );
    }
}
bash
# Generate docs
php artisan scribe:generate

Why Laravel is Better Here:

  • ✅ Scribe generates beautiful interactive docs
  • ✅ Automatic API documentation from code
  • ✅ OpenAPI/Swagger support
  • ✅ Try-it-out functionality built-in

Laravel's Official Ecosystem

Laravel has first-party paid services that make development and deployment easier:

1. Laravel Forge ($12-$39/month)

What it is: Server management and deployment

bash
# Rails equivalent: Heroku + custom scripts
# But Forge is better:

Features:

  • ✅ One-click server provisioning (AWS, DO, Linode, etc.)
  • ✅ Automatic deployments from GitHub/GitLab
  • ✅ SSL certificates (Let's Encrypt)
  • ✅ Database backups
  • ✅ Queue worker management
  • ✅ Scheduled job management
  • ✅ Server monitoring
  • ✅ Easy rollbacks

Comparison:

  • Rails: Manual server setup or Heroku ($25-$250/month)
  • Laravel: Forge ($12/month) + cheap server ($5-$20/month)

Total Cost:

  • Rails on Heroku: $25-$250/month
  • Laravel with Forge: $17-$59/month

2. Laravel Vapor (Serverless - $39/month)

What it is: Serverless deployment on AWS Lambda

bash
# No Rails equivalent this seamless

Features:

  • ✅ Auto-scaling (0 to millions of requests)
  • ✅ Pay per request (not per server)
  • ✅ Global CDN
  • ✅ Database management
  • ✅ Queue management
  • ✅ Scheduled tasks
  • ✅ Zero-downtime deployments

When to Use:

  • Unpredictable traffic
  • Startup with limited budget
  • High-scale applications
  • Multiple environments

3. Laravel Nova ($199/site)

What it is: Premium admin panel

php
# filename: app/Nova/Post.php (example)
<?php

declare(strict_types=1);

namespace App\Nova;

use Illuminate\Http\Request;
use Laravel\Nova\Resource;
use Laravel\Nova\Fields\ID;
use Laravel\Nova\Fields\Text;
use Laravel\Nova\Fields\Markdown;
use Laravel\Nova\Fields\BelongsTo;
use Laravel\Nova\Fields\DateTime;

// Create resources in minutes
class Post extends Resource
{
    public static $model = \App\Models\Post::class;

    public function fields(Request $request)
    {
        return [
            ID::make(),
            Text::make('Title'),
            Markdown::make('Body'),
            BelongsTo::make('User'),
            DateTime::make('Published At'),
        ];
    }

    public function filters(Request $request)
    {
        return [
            new PostStatus,
            new PublishedDateFilter,
        ];
    }
}

Better than ActiveAdmin:

  • ✅ Modern Vue.js interface
  • ✅ More field types
  • ✅ Better relationship handling
  • ✅ Metrics and insights
  • ✅ Custom tools/cards

4. Laravel Spark ($99)

What it is: SaaS application scaffolding

Includes:

  • ✅ Subscription billing (Stripe/Paddle)
  • ✅ Team management
  • ✅ Invoicing
  • ✅ Two-factor authentication
  • ✅ API tokens
  • ✅ Notification preferences

Rails equivalent: Multiple gems + custom code Laravel: One installation

5. Laravel Envoyer ($10/month)

What it is: Zero-downtime deployment

Features:

  • ✅ Deploy to multiple servers simultaneously
  • ✅ Health checks before switching
  • ✅ Instant rollbacks
  • ✅ Deployment notifications (Slack, Discord)
  • ✅ Custom deployment scripts

Better than Capistrano:

  • ✅ Web UI for deployments
  • ✅ Deployment history
  • ✅ Team collaboration
  • ✅ No local Ruby needed

Spatie (Belgian Company - Amazing Packages!)

Spatie maintains 200+ Laravel packages. Key ones:

bash
# Permission management
composer require spatie/laravel-permission

# Activity logging
composer require spatie/laravel-activitylog

# Backup management
composer require spatie/laravel-backup

# Media library
composer require spatie/laravel-medialibrary

# Query builder for APIs
composer require spatie/laravel-query-builder

# Data transfer objects
composer require spatie/laravel-data

# Settings management
composer require spatie/laravel-settings

# Tags
composer require spatie/laravel-tags

Example: Laravel Permission

php
# filename: app/Http/Controllers/AdminController.php (example)
<?php

declare(strict_types=1);

namespace App\Http\Controllers;

use Spatie\Permission\Models\Role;
use Spatie\Permission\Models\Permission;

// Create roles
$role = Role::create(['name' => 'writer']);
$permission = Permission::create(['name' => 'edit posts']);

// Assign permission to role
$role->givePermissionTo('edit posts');

// Assign role to user
$user->assignRole('writer');

// Check permission
if ($user->can('edit posts')) {
    // ...
}

// In Blade
@can('edit posts')
    <button>Edit</button>
@endcan

// In middleware
Route::middleware(['role:writer'])->group(function () {
    // ...
});

Rails equivalent: Multiple gems (Pundit + CanCanCan + custom code)

Livewire (Full-Stack Framework)

What it is: Build reactive interfaces without writing JavaScript

php
# filename: app/Livewire/SearchPosts.php
<?php

declare(strict_types=1);

namespace App\Livewire;

use App\Models\Post;
use Livewire\Component;

class SearchPosts extends Component
{
    public string $search = '';

    public function render()
    {
        return view('livewire.search-posts', [
            'posts' => Post::where('title', 'like', "%{$this->search}%")->get(),
        ]);
    }
}
blade
<!-- resources/views/livewire/search-posts.blade.php -->
<div>
    <input type="text" wire:model.live="search" placeholder="Search posts...">

    <ul>
        @foreach($posts as $post)
            <li>{{ $post->title }}</li>
        @endforeach
    </ul>
</div>

No JavaScript needed! Updates reactively.

Rails equivalent: Hotwire/Turbo + Stimulus (similar concept)

Laravel Excel

bash
composer require maatwebsite/excel
php
# filename: app/Http/Controllers/ExportController.php (example)
<?php

declare(strict_types=1);

namespace App\Http\Controllers;

use Maatwebsite\Excel\Facades\Excel;
use App\Exports\UsersExport;
use App\Imports\UsersImport;

// Export
return Excel::download(new UsersExport, 'users.xlsx');

// Import
Excel::import(new UsersImport, 'users.xlsx');

```php
# filename: app/Exports/UsersExport.php
<?php

declare(strict_types=1);

namespace App\Exports;

use App\Models\User;
use Maatwebsite\Excel\Concerns\FromCollection;

class UsersExport implements FromCollection
{
    public function collection(): \Illuminate\Support\Collection
    {
        return User::all();
    }
}

Rails equivalent: roo, caxlsx (Laravel Excel is more powerful)

Laravel Debugbar

bash
composer require barryvdh/laravel-debugbar --dev

Automatically shows:

  • Request/response details
  • Database queries with timing
  • View rendering time
  • Route information
  • Session data
  • Memory usage

Rails equivalent: rack-mini-profiler (Debugbar is more detailed)

Package Discovery & Evaluation

Finding Packages

Rails Resources:

  • RubyGems.org
  • The Ruby Toolbox
  • Awesome Ruby (GitHub)

Laravel Resources:

Evaluating Packages

Good Signs:

  • ✅ Regular updates (within last 6 months)
  • ✅ Good documentation
  • ✅ High download count
  • ✅ Active issues/PRs
  • ✅ Tests included
  • ✅ Laravel version compatibility
  • ✅ Sponsored by reputable company (e.g., Spatie)

Red Flags:

  • ❌ No updates in over a year
  • ❌ Many open issues
  • ❌ No tests
  • ❌ Poor documentation
  • ❌ Abandoned by maintainer

Version Compatibility

bash
# Check Laravel version support
composer show laravel/framework
composer why laravel/framework

# Check package compatibility
composer require vendor/package --dry-run

# See what would be updated
composer update --dry-run

Creating Your Own Package

Rails Gem Structure

ruby
# lib/my_gem.rb
module MyGem
  class Engine < ::Rails::Engine
  end
end

# my_gem.gemspec
Gem::Specification.new do |spec|
  spec.name        = "my_gem"
  spec.version     = "0.1.0"
  spec.authors     = ["Your Name"]
  spec.summary     = "Summary"
end

Laravel Package Structure

bash
# Create package structure
packages/
└── your-name/
    └── package-name/
        ├── src/
   ├── PackageServiceProvider.php
   └── Facades/
        ├── config/
        ├── routes/
        ├── resources/
        └── composer.json
json
// packages/your-name/package-name/composer.json
{
    "name": "your-name/package-name",
    "description": "Package description",
    "type": "library",
    "require": {
        "php": "^8.4",
        "illuminate/support": "^11.0"
    },
    "autoload": {
        "psr-4": {
            "YourName\\PackageName\\": "src/"
        }
    },
    "extra": {
        "laravel": {
            "providers": [
                "YourName\\PackageName\\PackageServiceProvider"
            ]
        }
    }
}
php
# filename: packages/your-name/package-name/src/PackageServiceProvider.php
<?php

declare(strict_types=1);

namespace YourName\PackageName;

use Illuminate\Support\ServiceProvider;

class PackageServiceProvider extends ServiceProvider
{
    public function register(): void
    {
        // Bind services
        $this->app->singleton(MyService::class, function ($app) {
            return new MyService();
        });
    }

    public function boot(): void
    {
        // Publish config
        $this->publishes([
            __DIR__.'/../config/package.php' => config_path('package.php'),
        ], 'config');

        // Load routes
        $this->loadRoutesFrom(__DIR__.'/../routes/web.php');

        // Load views
        $this->loadViewsFrom(__DIR__.'/../resources/views', 'package');

        // Load migrations
        $this->loadMigrationsFrom(__DIR__.'/../database/migrations');

        // Register commands
        if ($this->app->runningInConsole()) {
            $this->commands([
                Commands\MyCommand::class,
            ]);
        }
    }
}

Package Development:

bash
# In your app's composer.json
{
    "repositories": [
        {
            "type": "path",
            "url": "./packages/your-name/package-name"
        }
    ],
    "require": {
        "your-name/package-name": "*"
    }
}

composer update your-name/package-name

Common Rails Gems → Laravel Packages

Rails GemLaravel PackageNotes
deviselaravel/breeze, laravel/jetstreamAuth built-in
punditspatie/laravel-permissionMore powerful
sidekiqBuilt-in queuesNo package needed
carrierwaveBuilt-in storageNo package needed
kaminari/will_paginateBuilt-in paginationNo package needed
activeadminlaravel/nova, filamentBetter UI
paper_trailspatie/laravel-activitylogSimilar features
friendly_idspatie/laravel-sluggableSlug generation
ransackspatie/laravel-query-builderAPI filtering
fakerfakerphp/fakerSame package!
rubocoplaravel/pintAuto-formatting
bulletbarryvdh/laravel-debugbarShows N+1 queries
wheneverBuilt-in schedulerNo package needed

Key Insight: Many Rails gems have no Laravel equivalent because the features are built into Laravel!

Community & Learning Resources

Official Resources

Community

Conferences & Events

  • Laracon US - Annual conference (USA)
  • Laracon EU - European conference
  • Laracon Online - Free online conference
  • Local Meetups - Cities worldwide

Comparison to Rails:

  • Similar size community
  • More video content (Laracasts > RailsCasts)
  • Better official docs
  • More local meetups globally

Where Laravel Excels vs Rails

1. Built-in Features

Laravel includes out-of-the-box:

  • Queue system (Rails: needs Sidekiq)
  • Task scheduler (Rails: needs whenever)
  • File storage abstraction (Rails: needs carrierwave)
  • Broadcasting/WebSockets (Rails: needs ActionCable + Redis)
  • API authentication (Rails: needs devise + JWT gems)

2. First-Party Ecosystem

Laravel has official paid services:

  • Forge (deployment)
  • Vapor (serverless)
  • Nova (admin panel)
  • Spark (SaaS starter)
  • Envoyer (zero-downtime deployment)

Rails ecosystem is more fragmented.

3. Performance

  • PHP 8.4 JIT: 2-3x faster than Ruby
  • Lower memory usage: ~30-50% less RAM
  • Faster JSON parsing: Native C implementation
  • Better opcache: Bytecode caching built-in

Cost savings:

  • Laravel: 1 server handles traffic
  • Rails: 2-3 servers needed for same traffic

4. Deployment Simplicity

Laravel:

  • No application server needed
  • Works with Apache/Nginx directly
  • PHP-FPM handles concurrency
  • Easier to deploy

Rails:

  • Needs Puma/Unicorn
  • Reverse proxy configuration
  • More moving parts
  • More complex setup

5. Hosting Options

PHP hosting is ubiquitous:

  • Every shared host supports PHP
  • Cheaper options available
  • More providers

Ruby hosting is limited:

  • Fewer providers
  • More expensive
  • Harder to find

6. Type Safety

PHP 8.4:

  • Strict types built-in
  • Union types
  • Generics-like features
  • Better IDE support

Ruby:

  • Duck typing by default
  • Optional type checking (Sorbet/RBS)
  • Less IDE support

Practice Exercises

Exercise 1: Explore Packages

Browse Packagist and identify Laravel packages for:

  • Image processing
  • PDF generation
  • Social authentication
  • Activity logging
  • Setting management

Exercise 2: Create a Package

Build a simple Laravel package:

  • Create package structure
  • Add service provider
  • Publish configuration
  • Create a facade
  • Test in an app

Exercise 3: Compare Costs

Calculate hosting costs for:

  • Rails app on Heroku vs Laravel with Forge
  • ActiveAdmin vs Laravel Nova
  • Custom SaaS vs Laravel Spark

Wrap-up

Congratulations! You've completed a comprehensive exploration of Laravel's ecosystem, community, and packages. Here's what you've accomplished:

  • Understood package management - Compared Composer to Bundler/RubyGems
  • Explored essential packages - Authentication, storage, queues, testing, admin panels, and API documentation
  • Discovered Laravel's official ecosystem - Forge, Vapor, Nova, Spark, and Envoyer
  • Learned about community packages - Spatie packages, Livewire, Laravel Excel, and Debugbar
  • Evaluated packages - Know how to find and assess package quality
  • Created packages - Understand Laravel package structure and development
  • Mapped Rails gems to Laravel - Know the Laravel equivalents for common Rails gems
  • Explored community resources - Official docs, Laracasts, forums, and conferences
  • Identified Laravel advantages - Built-in features, performance, deployment simplicity

Key Takeaways

  1. More Built-in Features - Many Rails gems are built into Laravel (queues, storage, scheduling)
  2. Rich Official Ecosystem - Forge, Vapor, Nova, and Spark provide first-party solutions
  3. Spatie Packages - High-quality, well-maintained packages from a trusted source
  4. Better Performance - PHP 8.4 is faster and uses less memory than Ruby
  5. Simpler Deployment - No application server needed, works directly with Nginx/Apache
  6. Active Community - Vibrant, helpful community with excellent resources
  7. Package Quality - Many packages rival or exceed Rails gem quality

You now have a complete understanding of Laravel's ecosystem and can confidently find, evaluate, and use packages in your Laravel projects. The next chapter will help you make informed decisions about when to use Laravel versus Rails.

Further Reading

What's Next?

Now that you understand Laravel's ecosystem, the next chapter helps you decide when to use Laravel vs Rails for your projects.


Continue Learning

Move on to Chapter 09: When to Use Laravel vs Rails to learn decision-making frameworks.

📊 Your Progress0 / 11 chapters completed
0%