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

Resend Sdk Laravel Package

tobiasnagel01/resend-sdk

Unofficial Laravel/PHP SDK for Resend that wraps the transactional email API in a fluent, framework-friendly client. Send emails, manage domains and API keys, and integrate with Laravel's mail system through simple configuration and typed responses.

View on GitHub
Deep Wiki
Context7

Getting Started

  • Install with composer require vendor/package. Laravel's package auto-discovery should register the service provider from extra.laravel.providers in the package's composer.json — verify with php artisan about (Laravel 9+) or by checking bootstrap/cache/packages.php after composer dump-autoload.
  • Publish assets before doing anything else:
    php artisan vendor:publish --provider="Vendor\Package\PackageServiceProvider"
    
    Run it once with --tag=config first, then --tag=migrations if the package ships schema. Publishing everything blindly tends to dump files you'll never touch and muddies later upgrades.
  • Read three files in this order: README.md, CHANGELOG.md, src/*ServiceProvider.php. The provider tells you more about the package's real surface area (bindings, singletons, commands, published tags) than the README usually does. Note whether config is merged (mergeConfigFrom) or only publishable — that determines whether you can rely on defaults in CI.
  • First use case: resolve the class out of the container rather than instantiating it, and confirm the binding works before wiring it into anything:
    php artisan tinker
    >>> app(Vendor\Package\Client::class)
    
    If the package exposes a facade, Facade::getFacadeRoot() is the fastest sanity check that the accessor is registered.
  • If the package ships migrations, run php artisan migrate on a scratch database before touching your dev DB. New packages are the most common source of surprise schema changes in local environments.

Version 1.1.0 note

The 1.1.0 release notes are empty, so there is no documented change surface to plan around. Treat this as a patch-level bump until proven otherwise: diff the installed tree against the previous tag (composer diff vendor/package or git diff v1.0.0..v1.1.0 -- vendor/package) and check specifically for changes to the published config stub, migration files, and the service provider's register()/boot() methods. Those three are what break applications on minor upgrades.

Implementation Patterns

Constructor injection over facades. Resolve the package's client/DTO through the container in constructors, and let Laravel wire it. Facades are convenient in controllers and tinker but make the dependency invisible in job and service classes, which is where they tend to bite during testing.

Bind to a contract, not the concrete class. If the package ships an interface, bind it in your own AppServiceProvider:

$this->app->bind(
    \Vendor\Package\Contracts\Client::class,
    \Vendor\Package\Client::class,
);

This gives you a single swap point for fakes in tests and for wrapping the package in a thin adapter if you later need to replace it. Adapters are cheap to write up front and expensive to retrofit.

Keep credentials in config, defaults in code. Publish the config file, but drive every environment-dependent value through env() in the published file — never edit the vendor stub. The pattern that ages well:

// config/package.php
return [
    'api_key' => env('PACKAGE_API_KEY'),
    'timeout' => env('PACKAGE_TIMEOUT', 10),
];

Wrap network calls in queued jobs. Any package that talks to an external service belongs behind a job with $tries, $backoff, and $timeout set explicitly. This isolates rate limits and outages from the request cycle and gives you retry semantics for free.

Use the manager/driver extension points instead of forking. Packages built around Laravel's Manager class usually expose Package::extend('driver', fn () => ...). If you need custom behaviour, extend the driver and register it in a service provider — that keeps you on the upgrade path.

Test with fakes, not HTTP interception, where available. Prefer the package's own fake/swap helper (Package::fake()) over Http::fake(). Fakes assert intent; HTTP fakes couple your tests to the package's internal endpoints, which will break on any minor release that touches URLs.

Lean on Laravel's scheduler and events rather than internal package loops. If the package emits events, register listeners in EventServiceProvider rather than subclassing the package's internals. If it exposes a sync command, schedule it with ->withoutOverlapping().

Gotchas and Tips

  • Config caching is the number one source of "it works in tinker but not in the app." After changing anything in config/, run php artisan config:clear. In production deploys, config:cache must run after the publish step, or your env values silently become null.
  • Published config files do not update themselves. On any version bump — including 1.1.0 — diff config/package.php against vendor/vendor/package/config/package.php. New keys added upstream will be missing from your published copy, and the package will fall back to mergeConfigFrom defaults, which may not match documented behaviour.
  • Singleton vs. scoped bindings under Octane. If the package registers a singleton holding per-request state (an HTTP client with a mutated base URL, a cached user context), it will leak between requests under Octane. Check register() for singleton() and wrap your own bindings in scoped().
  • Queue serialization of package DTOs. DTOs passed into jobs are serialized — value objects with closures, resources, or non-serializable properties will fail at dispatch time, often only in the queue worker. Test job dispatch with Queue::fake() plus a real sync driver run.
  • Auto-discovery silently disabled. If composer.json sets "dont-discover", or you're on an older Laravel, the provider must be added manually to config/app.php. A missing provider manifests as "target class does not exist" from the container, not an obvious package error.
  • register() vs boot(). Register container bindings and merge config in register(); register commands, routes, views, and event listeners in boot(). When debugging a package, the call you care about is almost always in boot() — start there.
  • Migrations collide by timestamp. Published package migrations use the package's own date prefixes. If you've published the same migration twice across upgrades (common when re-running vendor:publish without --force), you'll get duplicate-table errors. Keep the published migration list under version control and review the diff.
  • Facade aliases and IDE support. Facade class aliases in config/app.php are legacy; prefer importing the facade FQCN. For static analysis, packages shipping a _ide_helper or a @method docblock block on the facade are meaningfully easier to work with — check composer.json for barryvdh/laravel-ide-helper compatibility before assuming autocomplete.
  • Debugging strategy. dd() inside register() runs before the app is fully booted and can produce misleading output. Put breakpoints in boot() or resolve the class from tinker instead.
  • Pin the version explicitly for 1.1.0. With no release notes, "vendor/package": "^1.1" is the safer constraint than ^1.0 for a week or two — it forces a deliberate decision rather than an incidental CI bump. Watch the repo's issue tracker for a day or two after the tag before rolling to production.
  • Extension points worth knowing before you need them: container bindings ($app->bind/scoped), the manager's extend(), publishable view/translation tags for overriding package UI strings, and any Macroable trait on the package's builder classes. These four cover the large majority of "I need to change one small thing" scenarios without forking.
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.
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route