hammerstone/sidecar
Sidecar lets your Laravel app package, deploy, and execute AWS Lambda functions in Node, Python, Java, .NET, Ruby, or custom runtimes. Define a PHP class and files, then invoke serverless functions directly from PHP.
Architecture fit
Sidecar is a thin Laravel-native orchestration layer over AWS Lambda. Its architecture mirrors Laravel conventions closely, which is the primary reason a TPM can defend it in a design review:
LambdaFunction subclass (handler(), package(), plus overridable memory/timeout/runtime/env/layers). This keeps serverless function definitions inside the same review, lint, and test pipeline as the application, rather than in Terraform, SAM, or a separate Node repo. For a TPM this collapses a cross-team dependency into a single-repo change.php artisan sidecar:deploy --activate and Function::execute([...]) mean the TPM can scope an initiative as "one PR adds one function" — a small, estimable unit of work with a predictable rollout.Integration feasibility
Low ceremony, moderate governance. composer require hammerstone/sidecar plus a sidecar:configure flow that provisions the IAM role and S3 artifact bucket is a genuine one-sitting setup. The real TPM work is not the install — it is the entitlement and boundary work:
sidecar.env (0.2.0), which decouples the Sidecar environment name from APP_ENV. This is the single most important config decision for multi-developer teams — without it, every developer on local overwrites the same set of Lambda functions. A TPM should make this a hard convention from day one.--activate, --pre-warm, and automatic sweeping of old unused versions all exist, so the lifecycle story is credible rather than hand-rolled.Technical risk
| Risk | Severity | Mitigation |
|---|---|---|
Pre-1.0 (v0.8.0) with a documented history of breaking changes — default runtime silently moved Node 14 → Node 20 in 0.6.0; function naming algorithm changed in 0.4.0, potentially renaming live functions |
High | Pin exact versions in composer.json; always declare runtime() explicitly rather than relying on the default; read every changelog before bumping |
| Function-name algorithm changes can orphan deployed functions and their aliases | Medium | Snapshot deployed function names before upgrading; verify in a non-prod account first |
| Single-maintainer project (Aaron Francis) with 891 stars and 0 dependents | Medium-High | Treat as an owned dependency: expect to vendor or fork. Budget for a maintenance spike if upstream stalls |
| Hard AWS coupling — no abstraction layer over Lambda | Medium | Accept it; do not build an in-house portability shim. If multi-cloud is a real requirement, reject the package now |
| Sync invocation payload/response limits (~6 MB) and 15-minute max timeout | Medium | Constrain use cases to image transforms, SSR fragments, PDFs, screenshots — not bulk data pipelines |
| Cold starts and concurrency | Medium | sidecar:warm and --pre-warm exist; provisioned concurrency is not a first-class concern of the package |
| No HTTP invocation path | Low | Correctly scoped out — but it means every consumer must be the Laravel app, which constrains future architecture |
| Deployment concurrency (409 conflict handling, env-var checksum logic, wait-until-updated) has a history of race-condition fixes (0.3.4, 0.3.5, 0.3.6) | Low-Medium | Serialize deploys in CI — never allow parallel deploys of the same function |
The changelog also shows steady, responsive stewardship: Windows path fixes, Guzzle v6 support, Arrayable payload casting, macroable package, Laravel 9/12/13 compatibility PRs, and runtime deprecations tracked against AWS's own deprecation calendar. For a pre-1.0 package, the hygiene signals are strong.
Key questions to resolve before committing
Stack fit
Sidecar targets the Laravel ecosystem directly and has kept pace with it — Laravel 9 support arrives in 0.3.8, 12.x in 0.7.0, 13.x in 0.8.0. It requires Composer, an AWS account, and a Laravel app that already treats Artisan as the operational interface (which any Laravel team does). The two-file mental model — a PHP class plus a payload directory — is comprehensible to a mid-level Laravel developer in under an hour.
The natural fit is: a Laravel app that needs one to three non-PHP capabilities and already deploys to AWS. The poor fit is: a polyglot platform team that already runs Terraform/CDK, or a team needing externally callable functions.
Migration path
The realistic migration is not "replace our serverless platform" — it is "repatriate the ad-hoc serverless functions we bolted on."
resources/lambda/, create the LambdaFunction subclass declaring handler(), package(), and an explicit runtime(), then sidecar:deploy --activate.Function::execute(). Because both return a string or structured payload, the call-site diff is small.Repeat per function. There is no big-bang requirement, and each step is independently revertible — which is the property that makes this approvable.
Compatibility considerations
"hammerstone/sidecar": "0.8.0", not ^0.8) given the pre-1.0 status.runtime() explicitly. The 0.6.0 changelog demonstrates that an undeclared runtime silently changes under you on upgrade. This should be a written coding standard, not a suggestion.sidecar.env explicitly and map it to your environment tiers (production, staging, per-developer local-{name}).Sequencing
| Phase | Duration | Deliverable | Exit criterion |
|---|---|---|---|
| 0. Feasibility spike | 2–3 days | One function deployed to a sandbox AWS account | Deploy + execute succeed end-to-end |
| 1. Governance | 1 week | Dedicated CI deploy role, S3 bucket, sidecar.env convention, version-pinning policy |
Security/platform sign-off |
| 2. Pilot | 1 sprint | One production function (OG image) behind a feature flag | Error rate and p95 latency parity with the incumbent |
| 3. Expand | 1 sprint | Second and third functions (PDF, screenshot) | Two or more functions in production |
| 4. Decommission | 1 sprint | Old Vercel/Netlify functions removed | Cost and on-call surface reduced |
Maintenance
This is the dominant operational consideration and should be stated plainly to stakeholders: Sidecar is a pre-1.0 package maintained primarily by one individual, with zero Packagist dependents. The changelog is active and well-curated, releases ship with contributor credits, and the author publishes an accompanying Laracasts series and hosted docs — all good signals — but the bus-factor is one.
Practical consequence: treat the dependency as vendored in spirit. Pin exactly, review every upgrade, and maintain a documented "fork path" so that if upstream stops, a named engineer can own the fork with bounded effort. Given the package is a few thousand lines wrapping the AWS SDK, forking is genuinely viable — this is the risk mitigation that makes the risk acceptable.
Ongoing maintenance burden is low in steady state: runtime constants need periodic refreshing against AWS deprecation schedules (the project already tracks these — Node 16, Python 3.8, and .NET 7 were deprecated in 0.7.0), and Laravel major-version compatibility needs a bump roughly annually.
Support
Support is community-driven: GitHub issues (the README explicitly says "please open issues for anything you run into"), the hammerstone.dev docs site, and the Laracasts series for onboarding. There is no vendor SLA. Internal support therefore depends on at least two engineers on the team being comfortable with AWS Lambda primitives independently of Sidecar — the package is thin enough that debugging almost always lands in AWS, not in Sidecar.
Scaling
Scaling is AWS's problem, which is the honest appeal. Concurrency, memory, timeout, ephemeral storage, and architecture are all declarative per function. Warm-keeping is available via sidecar:warm and --pre-warm flags on deploy and activate, but is opt-in with zero instances by default — meaning a TPM should expect and plan for cold-start latency on low-traffic functions, and should make warm-keeping an explicit, cost-reviewed decision rather than an afterthought. Old version sweeping keeps the version count from growing unbounded.
The real scaling ceiling is the 6 MB synchronous payload/response limit and 15-minute invocation cap. Use cases should be scoped to bounded artifacts (an image, a PDF, a rendered HTML fragment, a JSON transform), not to data movement.
Failure modes
runtime() on every class, plus a lint rule.sidecar:configure AWS error fixes. Mitigation: a smoke-test deploy in CI on a schedule, not just on release.Ramp-up
Onboarding cost is genuinely low for a Laravel team and is the strongest argument for the package from a people perspective:
OgImage class plus image.js) and understand the entire model. php artisan sidecar:deploy --activate is the only new command required.Recommended ramp plan: one engineer attends the Laracasts series and runs the Phase 0 spike, then writes a one-page internal runbook covering deploy, rollback, log inspection, and the explicit-runtime rule. That runbook — not the package documentation — is the artifact that actually de-risks adoption across the team.
Bottom line for a TPM: Sidecar is a narrow, well-scoped, well-maintained tool that converts a recurring "we need one Node/Python thing" architectural decision into a routine pull request. It is not a platform bet and should not be positioned as one. Approve it for bounded auxiliary functions behind an explicit runtime, an explicit sidecar.env, an exactly-pinned version, and a named fork owner — and it will pay for itself in avoided second-service overhead within a sprint or two.
How can I help you explore Laravel packages today?