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

Psysh Laravel Package

psy/psysh

PsySH is a runtime developer console, interactive debugger, and REPL for PHP. Inspect variables, evaluate expressions, and debug live code from your terminal, with configurable themes, history, and integrations like Laravel Tinker.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

What this package actually is

PsySH is not a Laravel component; it's a standalone, framework-agnostic PHP REPL/debugger that exposes an embeddable library surface (Psy\Shell, Psy\Configuration, Psy\ExecutionLoopClosure, plus a pluggable command and matcher system). Laravel relevance comes almost entirely from the fact that laravel/tinker is a thin wrapper around PsySH — this is the engine, not the Laravel adapter.

Architecture fit

  • Strong fit for the "developer-facing introspection" use case. The library API is designed for embedding: you construct a Configuration, inject a bound scope (setBoundObject, setData), customize the startup banner, history path, and add your own Command subclasses. This is exactly the shape needed for a project-specific artisan console.
  • Poor fit as a production runtime dependency. It is a code-evaluation surface by design. It has no request/response integration, no queue or container awareness beyond what you inject, and no meaningful place in a serving path.
  • Weak fit for a domain DSL / support-console product. You would be reusing the input loop, readline, and renderer while replacing most commands — plausible, but you'd be adopting a 0.x dependency whose internals (renderer widgets, mode stack) are actively changing to support the new readline.

Integration feasibility

High. The path is well-trodden: Tinker proves the embedding model works inside Laravel's container/bootstrap. A custom Artisan command that boots Psy\Shell with a preconfigured Configuration is a few dozen lines. Custom commands and completions are supported first-class (CommandArgumentCompletionAware as of 0.12.22). No private API use is required for the standard embedding.

Technical risk

  • Security exposure is the dominant risk, and it is not hypothetical. CVE-2026-25129 (CWD configuration poisoning) affected all versions prior to 0.12.19 / 0.11.23 and explicitly named downstream consumers including Tinker. Any pin below those is unacceptable. Note the attack class — config discovery from an untrusted working directory — persists as a design surface; "Restricted Mode" / trustProject mitigates rather than removes it.
  • 0.x versioning. Minor releases have shipped behavior changes (command-vs-function resolution for bare config/copy, deprecated multiline string format, ShellOutput decoupling). Treat every minor as potentially breaking.
  • Release velocity is high and recent (five releases in the visible window, latest dated 2026-06-29). That is healthy maintenance but also churn on the terminal/readline layer, which is the hardest thing to test in CI.
  • Experimental readline. The pure-PHP readline is opt-in and explicitly seeking feedback; it becomes the intended default. Adopting it early means owning terminal-compatibility bugs across SSH, tmux, Windows, and CI pseudo-TTYs.
  • Metadata caveat: "Dependents: 0" contradicts Tinker's well-known dependency and should be read as an artifact of the scoring dataset, not as evidence of low usage. Similarly, the opportunity: 54.44 score suggests limited differentiation upside — the package is table stakes you inherit, not a lever you invest in.

Key questions for engineering

  1. Is the requirement "Tinker is present and patched" (a hygiene task) or "we are building a bespoke console on PsySH" (a product task)? These have very different owners.
  2. What is the current resolved version via laravel/tinker, and is it ≥ 0.12.19 / 0.11.23?
  3. Does any non-local environment (staging, demo, container shell) expose an artisan tinker-equivalent to more than a named admin group?
  4. Do we need persistent history, and where will it live — local developer machines only, or shared volumes/containers?
  5. Is the experimental readline on the roadmap, or do we stay on the ext-readline path until it is default?
  6. If we build custom commands, who owns them, and do they run arbitrary user queries (i.e., are they a data-exfiltration path)?

Integration Approach

Stack fit

  • Composer-installable, MIT-licensed, no service dependency, no external infrastructure. It slots into the existing Laravel dependency graph rather than extending it.
  • In most Laravel applications the correct integration is none: declare laravel/tinker as a require-dev dependency and inherit PsySH transitively. Adding psy/psysh directly as a top-level requirement is only justified if you are embedding the Shell yourself.
  • If embedding: register a single Artisan command (php artisan app:console), construct Psy\Configuration in its handle(), point setConfigDir() at storage_path() (never the project root — this is the CVE's blast radius), and set setHistoryFile() to a per-developer path.

Migration path

  1. Audit first. Run composer show psy/psysh across all applications and confirm every resolved version is at or above the patched releases. This is a one-line fix and the highest-value action in the whole assessment.
  2. Constrain explicitly. Add a caret constraint on the patched minor line rather than letting transitive resolution float, so a future Tinker bump cannot silently regress the floor.
  3. Decide in/out of production. Add an environment gate (App::environment('local') plus an explicit opt-in flag) so the console command is not registered in deployed environments. Make this a code-level control, not a documentation convention.
  4. Then, and only then, consider customization: startup banner, bound $app/tenant context, a handful of read-only helper commands.
  5. Defer readline adoption. Leave useExperimentalReadline off until it is the shipped default.

Compatibility

  • PHP and Symfony Console constraints are the practical floor. Confirm the supported PHP matrix against the app's minimum before pinning; PsySH tracks current PHP closely and drops EOL versions.
  • Laravel 10/11/12 should all be fine via Tinker, but Tinker's own constraint is what actually determines your floor — pin through Tinker where possible rather than fighting it with a direct requirement.
  • Non-interactive contexts (piped input, execute() calls, Composer proxy scripts) are a known edge-case area; expect to test --no-interaction explicitly.

Sequencing

Patch/pin (day 1) → environment gate (week 1) → optional custom console (only if a named stakeholder wants it) → revisit readline after it becomes default. Everything after step 2 is discretionary.

Operational Impact

Maintenance

  • Low code footprint, but non-zero attention: frequent minor releases, a 0.x line with no LTS, and a security history. Budget a standing quarterly review and an out-of-band process for security advisories.
  • Do not fork or vendor. The customization surface (commands, matchers, config) is sufficient for essentially all embedding needs, and forks of a 0.x terminal-heavy codebase age badly.
  • Custom Command subclasses are your maintenance liability; keep them few, read-only, and documented.

Support

  • Support load is developer-facing and self-service: the wiki, help, doc, and ls cover most questions. Expect recurring tickets about history not persisting, tab completion misbehaving, and rendering artifacts in unusual terminals — not about application behavior.
  • Establish a policy line: "the console is a local development tool; it is not a supported interface for production data access." Repeat it in onboarding.

Scaling

  • Negligible infrastructure scaling concern — it is a per-process, single-user interactive tool. No throughput, latency, or capacity planning required.
  • The only shared-state surfaces are the history file and trusted_projects.json. On shared hosts, dev containers with mounted home directories, or CI runners, these can collide or leak prior commands. Scope them to ephemeral per-run paths in CI.

Failure modes

Failure Impact Mitigation
Unpatched version + untrusted CWD (CVE-2026-25129 class) Arbitrary code execution Pin ≥ 0.12.19 / 0.11.23; set config dir to storage_path()
Command exposed in production Full DB/app access via eval Environment gate in code; no public route to the console
No TTY (CI, Docker, cron) Hangs or degrades confusingly Test --no-interaction; ensure commands are only reachable interactively
History file writable/shared Secret and query leakage Per-developer path; exclude from backups and image layers
Minor version behavior change Custom commands break silently Caret pin + changelog review on upgrade
Experimental readline enabled Rendering/input bugs across terminals Leave disabled until default

Ramp-up

  • For a developer using it as Tinker: effectively zero — php artisan tinker and existing knowledge transfer.
  • For a developer extending it: roughly half a day to a day to be productive with Configuration, Shell, and custom commands; longer to be confident with the readline/renderer internals, which are mid-refactor.
  • For the team as a whole: one short onboarding note covering the environment gate, the history/config location, and the "no production data access" rule. That note is more valuable than any amount of tooling polish.
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.
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package