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

Porter Laravel Package

anystack-sh/porter

Porter is a Laravel package for painless data import and export. Build importers and exporters with a fluent API, map columns, and process large CSV or Excel files in the background using queues and progress tracking.

View on GitHub
Deep Wiki
Context7

Getting Started

Porter is a dev-only convenience: it lets one Artisan command start every background process your app needs (Vite, queue worker, Reverb/websockets, scheduler, log tailer) instead of keeping four terminal tabs open next to php artisan serve.

Minimal path:

composer require anystack-sh/porter --dev

# find the exact command + flags in your installed version
php artisan list | grep -i porter

# publish the config (tag name varies by version — check the README,
# or just create config/porter.php if nothing is published)
php artisan vendor:publish --provider="Anystack\Porter\PorterServiceProvider"

Then declare your first process in config/porter.php — pick the one thing you currently start in a second terminal most often. For most Laravel apps that's Vite:

return [
    'processes' => [
        'vite'  => 'npm run dev',
        'queue' => 'php artisan queue:work --tries=1',
    ],
];

Run the porter command and confirm both children start and print output. That's the whole first use case: php artisan serve in one tab, everything else in another.

Where to look first, in order: the README's config example (the authoritative key names for your version), the published config/porter.php comments, then vendor/anystack-sh/porter/src — it's a small package, and reading the command class takes five minutes and answers every question about lifecycle and signal handling.

Implementation Patterns

Config as the onboarding document. Commit config/porter.php. It becomes the project's "how do I run this locally" answer, replacing a stale README section. A new hire runs composer install && composer dev and has the full stack up.

Composer script as the front door. Don't teach teammates the porter command; teach them one script:

"scripts": {
    "dev": ["@php artisan porter"]
}

Now composer dev is the contract, and you can swap Porter out later without changing anyone's muscle memory.

Group by responsibility, not by language. Three or four processes is the sweet spot:

'processes' => [
    'assets'     => 'npm run dev',
    'queue'      => 'php artisan queue:work',
    'websockets' => 'php artisan reverb:start --debug',
],

Keep php artisan serve separate — it's interactive (you want Ctrl-C to kill it), and the HTTP request log is the one stream you actually read.

Per-developer overrides via .env. Ports and package managers are machine-specific. Put PORTER_NODE_CMD / port numbers in .env and interpolate in the config so the committed file stays honest without forcing everyone onto pnpm:

'vite' => env('PORTER_ASSETS_CMD', 'npm run dev'),

Prefer queue:listen over queue:work in dev. queue:work caches your code in memory; you'll edit a job, see nothing change, and lose twenty minutes. queue:listen boots a fresh worker per job — slower, correct.

Pair with Sail instead of fighting it. If you're containerized, run Porter inside the app container (sail artisan porter) so the child processes share the container's PHP, Node, and MySQL hostnames. Running it on the host against a containerized DB is the most common silent failure.

Use it as a debugging harness for one-off processes. Anything you need to run for five minutes — a fake event stream, a socket server, a Stripe webhook forwarder — drop it in the config temporarily rather than remembering a shell incantation.

Gotchas and Tips

This package is frozen. No release since May 2023. Before adopting, verify it installs and runs cleanly on your Laravel and PHP versions (particularly Laravel 11/12 and PHP 8.3+). It's small, dev-only, and low-risk — if a constraint blocks install, fork it or fall back to composer scripts with concurrently. That's the entire value proposition; don't treat it as load-bearing infrastructure.

It is not a process supervisor. Nothing here belongs in production. Use Supervisor or systemd in prod — Porter is for laptops, where "restart on crash" means "I'll hit Ctrl-C and re-run."

Orphaned children are the #1 annoyance. If the parent is killed hard (closed terminal, kill -9), child processes can survive and squat on ports 5173, 8000, or 6001. Symptoms: "port in use" on a fresh start, or edits hitting a zombie Vite. Fix: pkill -f "queue:work" / lsof -i :5173. Prevent: always stop with Ctrl-C, and note which shell you spawned it from.

Interactive prompts get swallowed. Processes that ask questions (npm create, db:create confirmations, WP-style installers) will hang with no visible prompt because stdin isn't a TTY. Run them once standalone, then add the already-configured version to the config with non-interactive flags (--yes, --force, --no-interaction).

Interleaved output destroys stack traces. Four streams into one terminal means a queue exception is now spliced through Vite's HMR chatter. When debugging, pull the broken process out and run it alone. If everything is fine and you just want readability, lean on the per-process name prefixing/coloring if your version supports it.

Environment drift. Children inherit Porter's environment, but they may not inherit the same shell profile you have in your terminal — so nvm-managed Node versions, asdf shims, or PATH additions can resolve differently. If npm works in your shell but not under Porter, that's the cause.

Shell syntax is platform-dependent. Pipes, &&, and export FOO=bar inline prefixes behave differently across cmd/PowerShell/WSL/Git Bash. Keep commands as plain executable-plus-args where possible; if you need a pipeline, wrap it in a script file and call that.

Check the exit code on shutdown. A process that exits immediately with code 0 usually means the command ran and finished (e.g. queue:work with --stop-when-empty), not that Porter is broken. Read the first ten lines of output before assuming the config is wrong.

Isolate before you debug Porter. Reproduce by running the raw command yourself. If it fails there too, Porter is innocent and you've saved an hour of reading vendor source.

Know the off-ramp. If you outgrow this — need health checks, restart policies, or a Procfile shared with Heroku — overmind + Procfile.dev or concurrently are the mature equivalents. Because Porter's surface is one config file and one composer script, migrating is a 15-minute job, which is exactly why it's a low-risk adoption.

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.
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums
rlacerda83/query-parser
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
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