parabol/parabol-base-bundle
Core base bundle for Parabol, packaging shared configuration, services, and utilities for Symfony/PHP applications. Use it as a starting point for common platform components and consistent project setup.
Treat the name literally: parabol-base-bundle is a Symfony bundle, not a Laravel package. Before you install it, confirm what it declares in composer.json — a "type": "symfony-bundle", symfony/framework-bundle or doctrine/orm in require, and the absence of any extra.laravel block are all signals that there is no Laravel auto-discovery, no published config, no migrations, and no ServiceProvider waiting for you. If that's what you find, the "getting started" step in a Laravel app isn't composer require — it's read the source and decide what to extract.
Order of operations on day one:
composer.json — check the type, the require block, the require-dev, the PSR-4 autoload mapping, and the PHP constraint. This tells you the framework target and your compatibility gate in about sixty seconds.src/ — with zero stars and zero dependents there is no blog post, no Stack Overflow corpus, and likely a thin README. The source is the documentation. Skim for files that import nothing from Symfony\Component\* — those are the portable candidates.DependencyInjection/*Extension.php and Resources/config/services.* — this is where a Symfony bundle declares what it actually wires. Reading the load() method tells you the real service surface faster than any docblock.DependencyInjection/Configuration.php — every parameter here is a config key. If you decide to wire anything up in Laravel, this is your map of what needs a home in config/parabol.php.First useful use case: treat the package as a source of reusable plain PHP classes, not a framework integration. Find a base entity, trait, value object, or helper in src/ whose own file has no Symfony imports — copy it into a scratch Laravel project and see if it stands alone. That is the only path that pays off in under a day. If everything in src/ pulls in Symfony contracts, stop; the cost of dragging half the component tree along for a bundle nobody else uses is not worth it.
There is no ServiceProvider, no extra.laravel, and no publishable config. Every pattern below requires manual wiring, and each carries a real maintenance cost.
Pattern 1 — Cherry-pick portable classes. Copy the specific classes you need into your own namespace and autoload via your normal PSR-4 setup. Best when the bundle is a grab-bag of helpers. Leave a comment in your file recording the upstream commit hash so you can diff later, and pin the upstream to a commit, not dev-main, in whatever reference you keep. This is the lowest-coupling option and almost always the right one for a zero-signal package.
// Kept from parabol/parabol-base-bundle @ <commit-sha>, src/Base/SomeHelper.php
namespace App\Support;
class SomeHelper { /* adapted upstream body */ }
Pattern 2 — Register the services yourself in a ServiceProvider. If the bundle actually ships services you want (unlikely to be worth it, but possible), mirror the Symfony definitions in Laravel's container. Map each %parameter% the bundle references to a key in config/parabol.php.
// app/Providers/ParabolServiceProvider.php
public function register(): void
{
$this->app->singleton(\Parabol\Base\SomeService::class, function ($app) {
return new \Parabol\Base\SomeService(
$app['config']->get('parabol.option')
);
});
}
Be aware that Symfony's constructor-injection conventions, tagging, and compiler passes don't translate cleanly. If the bundle has CompilerPass implementations, you are porting bundle internals, not integrating them. That's usually the point where the cherry-pick route wins.
Pattern 3 — Adapter wrapper. Put your own interface in front of anything you consume, so product code never extends or type-hints a Parabol class directly. This is the only pattern that preserves your ability to remove the package later without a rewrite.
interface ReferenceData
{
public function lookup(string $key): ?array;
}
final class ParabolReferenceData implements ReferenceData
{
public function __construct(private \Parabol\Base\ReferenceService $inner) {}
public function lookup(string $key): ?array
{
return $this->inner->find($key);
}
}
Bind the interface in your ServiceProvider, inject the interface everywhere, and the Parabol class becomes an implementation detail you can replace in an afternoon.
Pattern 4 — Fork and own. Given 0 stars and 0 dependents, this is arguably the real pattern if you decide to use more than a few classes. Fork to your VCS, add your own tests around the parts you use, and set an upgrade reminder on the next Laravel/PHP major bump. Do not track dev-main from upstream — there's no upstream to track.
Integration sequencing that actually works: (a) audit source in a timebox of a day; (b) extract the specific classes into your namespace on a throwaway branch; (c) prove it in one bounded module, not core; (d) if the extraction was trivial, never look back at the original package. The expected outcome is that you write less glue by cherry-picking than by trying to make the bundle behave like a Laravel package.
Bundle suffix is not cosmetic. Symfony bundles rely on Symfony\Component\HttpKernel\Bundle\Bundle, the DI extension system, and the framework's bundle-registration pipeline. Laravel shares Symfony components but does not run that pipeline. There is no bridge worth writing.php artisan vendor:publish. No config file, no migrations, no routes ship into your app automatically. Anything the bundle would normally wire, you wire by hand. Watch for services that assume a Symfony ContainerInterface — you'll be adapting or reimplementing them.symfony2admingenerator, expect Doctrine ORM entities, annotations/attributes, and repository base classes. Laravel uses Eloquent. Base entities from a Doctrine tree usually do not port; base traits and value objects often do. Check each class individually.%foo%) resolve at container compile time; Laravel config resolves at runtime via config(). Any class reading %foo% needs refactoring to accept the value as a constructor argument. Don't chase this with reflection tricks — just pass it in.composer.json are the ceiling of what it was tested against. Pin exact versions and run composer why-not against your target platform before committing.require and require-dev before merging anything.src/. Budget senior-engineer time to characterize behavior before anyone builds on it — assume a full day for a first read-through if src/ is more than a few files.Configuration.php nodes (your config file's schema), and any tagged services in services.xml (these usually indicate extension hooks, but expect to translate Symfony tags into Laravel container tagging by hand).How can I help you explore Laravel packages today?