Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Core Laravel Package

coderstm/laravel-core

Core foundation package for Laravel applications by Coderstm, bundling shared helpers, base classes, traits, and common utilities. Provides reusable scaffolding so packages and apps share consistent configuration, models, and service providers.

View on GitHub
Deep Wiki
Context7

Getting Started

1. Install and publish.

composer require coderstm/laravel-core
php artisan vendor:publish --provider="Coderstm\CoderstmServiceProvider"
php artisan install

php artisan install is the package's own bootstrap (seeds payment methods, permission modules, default settings). Run it after your users/admins migrations exist, and re-read its source before running it twice — it is the single highest-risk command in the package.

2. Read these four files first, in this order.

File Why
config/coderstm.php The whole feature surface: application, currency, subscription, shop, wallet, license, theme. If a behaviour surprises you, it is almost certainly toggled here.
src/Coderstm.php The static facade — model binding, ignoreRoutes(), withoutCart(), ignoreMigrations(), gateway accessors. This is your contract with the package.
CoderstmServiceProvider Which routes, middleware, migrations, and event listeners get registered, and under what conditions.
src/Traits/ 39 traits (Billable, ManagesSubscriptions, HasWallet, HasPermission, Paymentable, …). Traits, not base classes, are how you extend models.

3. Bind your models in AppServiceProvider::boot() before touching anything else.

Coderstm::useUserModel(App\Models\User::class);
Coderstm::useAdminModel(App\Models\Admin::class);
// useSubscriptionModel, useOrderModel, etc.

4. First use case: multi-guard auth. The package ships users and admins guards on Sanctum with /auth/{guard?}/signup|login|me. Wire your SPA to those endpoints and use the helpers — user(), guard(), is_admin() — rather than auth()->user(). You get working auth for two guards in an afternoon, which is genuinely the fastest win here.

If you only need one feature (say the cart, or currency conversion), enable it and call Coderstm::ignoreRoutes() for the rest — do not adopt the whole stack on day one.

Implementation Patterns

Config-driven host app, not model-extending host app. The intended shape is: the package owns routes, controllers, models, and migrations; your app owns configuration, model bindings, front-end, and a handful of override classes. If you find yourself copying package controllers into app/Http/Controllers, you have misread the design — use ignoreRoutes() and re-expose only what you need.

Feature gating is a closed loop. Define Feature → attach to Plan → gate with $user->hasFeature('slug') → meter with $user->useFeature('slug') → reset via the scheduled reset:subscriptions-usages. Never check plan_id directly; the feature layer is what the admin UI and usage counters both read.

Payment gateways: extend, don't patch.

class AcmeProcessor extends AbstractPaymentProcessor
{
    public function charge(PayableInterface $payable, array $payload): PaymentResult { /* … */ }
    public function refund(Payment $payment, ?float $amount = null): RefundResult { /* … */ }
    public function createSubscription(...): SubscriptionResult { /* … */ }
    public function cancelSubscription(...): void { /* … */ }
}

Pair every processor with a mapper in Payment/Mappers/ that normalises the provider webhook into the package's shape. Without the mapper, downstream events (RefundProcessed, SubscriptionCancelled) fire with partial data and your listeners silently misbehave.

Currency lives at the request boundary. Resolve once in middleware with Currency::resolve($address), then format everywhere else with format_currency(). Do not call Currency::set() inside controllers — the service is request-scoped and you will leak rates between requests under Octane.

Events over model overrides. Subscribe to SubscriptionCreated, SubscriptionCancelled, RefundProcessed for side effects (email, provisioning, analytics). Overriding a package model method breaks the observer chain and the queued listeners that assume it ran.

Runtime settings via ConfigLoader/AppSetting, not env(). Anything an admin can change at runtime (mail driver, payment keys, exchange rates) belongs in the DB-backed config layer. Reading env() anywhere past config/ is a bug in this architecture — and it breaks outright once you run config:cache.

Schedule the commands yourself. They are not auto-registered. In routes/console.php:

Schedule::command('subscriptions:renew')->daily();
Schedule::command('reset:subscriptions-usages')->monthly();
Schedule::command('update:exchange-rates')->daily();
Schedule::command('check:grace-period-subscriptions')->hourly();
Schedule::command('process:abandoned-checkouts')->everyFifteenMinutes();

Reports. New report = class with getData() returning a collection + registration in ReportService::$reports + optional export class. Because getData() returns raw rows, keep aggregation in SQL; 60+ report types sharing one service means an N+1 in your report is an N+1 in everyone's admin dashboard.

Gotchas and Tips

Route collisions are the first thing that will bite you. The package registers /auth/*, /admin/*, /user/*, /shop/*, /webhooks/*, /subscriptions/*. Any overlapping host route resolves by registration order and you will get a confusing 404/405 rather than a duplicate-route error. Audit with php artisan route:list immediately after install, and call Coderstm::ignoreRoutes() if you are not using the bundled API.

Migrations order matters. Package migrations must run after your users/admins tables, and ignoreMigrations() exists precisely for teams that need to publish and edit them. If you add columns to package tables, do it in a later migration — editing a published package migration will not re-run on existing environments.

Webhooks need three things the docs do not spell out: CSRF exemption for /webhooks/*, provider signature verification inside your controller (not the mapper), and idempotency on the Payment/Order write. Payment providers retry; a non-idempotent webhook handler here produces duplicate wallets and duplicate subscription extensions.

Config cache is a landmine. ConfigLoader reads from the DB at boot. Verify the loading order survives php artisan config:cache and optimize on your deploy — a ConfigLoader that resolves before the DB connection is available will throw on every request in production and work fine locally.

Request-scoped state in queues. Currency and ApplicationState are request-scoped. A queued job or notification dispatched from a non-INR request will format money in the caller's currency unless you snapshot the currency code into the job payload. Same trap for Blog's singleton cache — call Blog::clearCaches() in observers, and remember it persists across requests under Octane.

Permission caching. HasPermission / GuardMiddleware cache per-group permissions. After seeding new Module/Permission/Group records, clear the cache or admins will see 403s on screens that visibly exist.

Debugging path. When something behaves unexpectedly, in order: (1) config('coderstm.*') for the effective value, (2) php artisan route:list --path=… to confirm which handler actually owns the route, (3) whether the relevant event fired (log the listener, don't guess), (4) whether the artisan command that maintains the state is scheduled and succeeding — most "subscription/wallet is wrong" bugs are a command that was never scheduled.

Vendor risk is the real headline. Zero stars, zero dependents, one vendor, an enormous surface area (61 models, 39 traits, 11 payment processors), and a release date that reads as future-dated relative to normal semver cadence. That is not disqualifying for an internal or narrow-scope use, but it changes how you should consume it:

  • Pin an exact version and commit composer.lock. No ^ range on a zero-adoption package.
  • Never rely on transitive behaviour. Read the source for anything on your critical path — subscriptions, refunds, wallet debits. These are the code paths where a subtle bug costs money.
  • Fork early if you plan to stay. With zero dependents there is no ecosystem pressure keeping interfaces stable; assume you may become the maintainer of your own fork and keep your customisations in app/, not in vendor/.
  • Test the money paths yourself. Do not assume the package's own tests cover refund-with-partial-amount, failed-renewal-then-retry, or concurrent checkout. Those three are where you should write your own feature tests first.

Used narrowly — as a batteries-included auth + billing + cart backend behind a custom SPA — it is a large but real head start. Used as a black box across the whole money path, it is an unhedged dependency.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console