Laravel Service Container vs Service Provider: What’s the Difference?

Service Container? Service Provider? If these two concepts confuse you in Laravel, this article will finally clear things up with simple examples and real use cases.
🧠 Service Container vs Service Provider — What’s the Deal?
They sound similar, right?
But they’re not the same thing.
In Laravel, Service Container is the engine, and Service Providers are the fuel. Let’s break it down.
🔌 What is the Laravel Service Container?
The **Service Container** is Laravel’s dependency injection container.
It’s what resolves classes, dependencies, singletons, and bindings.
Example:
```php
// Bind something manually
app()->bind('PaymentService', function () {
return new StripePaymentService();
});
// Resolve it
$payment = app()->make('PaymentService');
You can also use constructor injection:
public function __construct(StripePaymentService $service) {
$this->service = $service;
}
💡 Think of it as the thing that holds and resolves your dependencies.
🛠️ What is a Service Provider?
A Service Provider is the class where you register things into the service container.
It’s like the container’s config file.
Example:
// app/Providers/PaymentServiceProvider.php
public function register() {
$this->app->singleton(PaymentService::class, function () {
return new StripePaymentService();
});
}
And then register the provider in config/app.php or use package auto-discovery.
💡 It’s where you define how things get added to the container.
---
🧩 So What’s the Real Difference?
| Feature | Service Container | Service Provider |
|---|---|---|
| Role | Stores and resolves bindings | Registers bindings into container |
| Used for | Dependency injection | Bootstrapping services |
| When it runs | Every time a class is resolved | At app startup |
| Common methods | bind(), make(), singleton() | register(), boot() |
💡 You use the Service Container — but you define things in Service Providers.
---
⚙️ Real World Example: Registering a Custom Service
Let’s say you build a custom logger class.
- Create your class:
class CustomLogger {
public function log($msg) {
file_put_contents('log.txt', $msg);
}
}
- Create a provider:
class LoggerServiceProvider extends ServiceProvider {
public function register() {
$this->app->singleton(CustomLogger::class, function () {
return new CustomLogger();
});
}
}
- Use it anywhere:
use App\Services\CustomLogger;
class ReportController {
public function __construct(CustomLogger $logger) {
$logger->log("Page loaded");
}
}
Laravel will resolve CustomLogger automatically using the Service Container.
🧠 When to Use Which?
✅ Use the Service Container:
- Inside controllers or services
- When you want to manually resolve something
- In tests or dynamic logic
✅ Use a Service Provider:
- When registering services, bindings, facades, singletons
- When building packages
- When bootstrapping app-wide logic
💡 TL;DR:
- Service Provider = where you put things into the container
- Service Container = where you pull things out of the container
🔁 How They Work Together
- You bind stuff in the Service Provider.
- Laravel adds it to the Service Container.
- Later, you resolve it via injection or
app()->make().
They’re two halves of the same system.
✅ Final Tip
If you’re building Laravel apps:
- You’ll mostly use the Service Container without touching it directly
- But you’ll write bindings in a Service Provider for anything custom
Still unsure?
If you’ve ever used:
Route::get(...)
View::share(...)
Auth::guard(...)
…you’ve already used things that were registered via Service Providers and resolved from the Service Container.
💬 Need real-world examples from your Laravel project?
Check out more Laravel deep dives here:
https://mostefa-boudjema.vercel.app/blog





