Run

Work that outlives the request that started it.

Queues, schedules, events, and mail are one subsystem here rather than four packages with four config formats. A job dispatched in a request and a job fired by the scheduler are the same class, run by the same worker, against the same driver. Mail can mean sending through SES or Mailgun, or it can mean running the mailbox itself: a self-hostable SMTP and IMAP server for real inboxes on your own domain.

What you get.

All of it in the same install, with nothing to wire together first.

Jobs and queues

Classes in app/Jobs/ dispatched from anywhere, run by a worker, with retries, backoff, and batches. Drivers cover memory, database, and SQS.

Scheduling

app/Scheduler.ts declares recurring work in TypeScript instead of a crontab, so it ships and reviews with the code.

Events and listeners

app/Events.ts maps events to listeners in app/Listeners/. Models with the observe trait emit created, updated, and deleted for free.

Mail

Mail classes in app/Mail/ render STX templates and send through SES, SendGrid, Mailgun, or plain SMTP behind one interface.

Your own mail server

A self-hostable SMTP and IMAP mail server for real mailboxes on your own domain, opt-in and deployed alongside the app, for teams that would rather not pay for Google Workspace or Fastmail just to receive mail.

Notifications

One notification, several channels: email, SMS, push, chat, or a database row the dashboard can read.

Batches

Group jobs, track progress as a unit, and hang a completion callback off the batch rather than off the last job.

From the command line.

Buddy scaffolds, runs, and ships this the same way it does the rest of the app.

buddy make:job SendWelcomeEmail buddy queue:work buddy make:notification OrderShipped

These share the same models, config, and types, so using them together costs nothing extra.