networkrailbusinesssystems/common
A shared Laravel/PHP common package from Network Rail Business Systems, providing reusable foundations, helpers and conventions for internal applications. It centralises common code so teams can build consistent, maintainable services faster.
This is an internal "base" package from Network Rail Business Systems — it aggregates shared functionality (base service providers, traits, helpers, conventions) used across NRBS Laravel applications. It has zero stars, zero dependents, and a single release, so treat the repository source as the only authoritative documentation.
Minimal steps to evaluate it:
src/:
git clone https://github.com/Network-Rail-Business-Systems/common.git
cd common && find src config -type f | sort
composer.json. Look at require (which Laravel/PHP versions are supported), autoload.psr-4 (the root namespace — typically NetworkRailBusinessSystems\Common\), and extra.laravel.providers (whether the service provider is auto-discovered or must be registered by hand).composer require networkrailbusinesssystems/common
If a service provider is not auto-discovered, add it to bootstrap/providers.php (Laravel 11+) or config/app.php.php artisan vendor:publish --provider="NetworkRailBusinessSystems\Common\CommonServiceProvider"
Inspect what lands in config/ and database/migrations/ before running migrate.Model, or use its base Migration/Seeder. This tells you quickly whether the abstractions fit your codebase or fight it.Where to look first, in order: src/CommonServiceProvider.php (what it binds, registers, and publishes), src/Concerns/ or src/Traits/ (the behaviours you're meant to compose in), src/Models/ (base Eloquent classes), and config/common.php if present.
Base-class inheritance for models and migrations. Common packages of this shape usually provide an abstract Model extending Illuminate\Database\Eloquent\Model with shared casts, a UUID/ULID primary key convention, timestamps, and soft-delete defaults. The pattern is to extend it once at the top of your domain:
namespace App\Models;
use NetworkRailBusinessSystems\Common\Models\Model as BaseModel;
abstract class Model extends BaseModel
{
// app-wide casts, connection, etc.
}
Then every domain model extends App\Models\Model. This gives you a single seam to override package behaviour later without touching dozens of files.
Composable traits over deep inheritance. Where the package exposes Concerns\* traits (auditing, HasReference, soft-deletes-with-reasons, etc.), use them a la carte rather than inheriting everything. This keeps the blast radius small when the package changes.
Service provider as the integration point. Register app-specific extensions in your own AppServiceProvider::boot() rather than editing the package: Model::unguard() policy, custom casts, or macro registration. Never vendor-patch a zero-dependent internal package — you'll be the only one maintaining the fork.
Config-first integration. If the package publishes a config file, commit it to config/common.php rather than relying on package defaults, so that upgrades don't silently change behaviour. Reference it via config('common.foo') and, better, wrap it in a small App\Support\CommonConfig class so string keys live in one place.
Testing pattern. Because the package is unversioned in practice, pin it exactly in composer.json ("networkrailbusinesssystems/common": "1.0.0" not "^1.0") and add a thin integration test in your own suite that asserts the base model's behaviours (UUID generation, timestamp format, cast outputs). That test is your regression alarm when you bump.
Boundary pattern. Keep package references out of your domain layer where practical — e.g. a App\Models\Concerns\UsesCommonModel wrapper — so that swapping the base class later is a one-file change rather than a codebase-wide find-and-replace.
laravel/framework or php to a narrow range. If composer require fails with a constraint conflict, composer why-not networkrailbusinesssystems/common will show exactly which dependency blocks it before you start downgrading things.php artisan migrate --pretend first, and never run package migrations against a database that already has data without reading the up() methods.extra.laravel.providers may be missing. Check bootstrap/providers.php / config/app.php and register manually.composer dump-autoload -o succeeds after install; a case-sensitivity mismatch between the psr-4 prefix and the directory name will work on macOS and fail on Linux CI.Model::unguard(), DB::prohibitDestructiveCommands(), or register global scopes inside boot(). Read the provider's boot() line by line — this is where surprising production behaviour hides.created_at format, missing soft deletes, a global scope leaking into a query), dd((new ReflectionClass(YourModel::class))->getTraits()) and checking getParentClass() quickly tells you what the package actually attached.$this->app->bind(...) in your provider) over reflection hacks. If the package has no extension points, note that as a cost in your adoption decision.app/Support/ with an attribution comment — it removes a permanent supply-chain and bus-factor risk.How can I help you explore Laravel packages today?