psy/psysh
An interactive shell for modern PHP.
v0.12.24
606M downloads/mo
#88 most downloaded on composer
bobthecow/psysh
What this package is like to depend on
Last release 1 months ago
29 Jun 2026
Ships fairly regularly
a new release about every 4 weeks
Rarely documented
notes for 10 of 126 stable releases
Nothing withdrawn
no release was ever pulled
13 years old
126 releases · first in 2014
15 releases in the last 12 months
see the full history below
Release timeline
126 releases · Feb 2014 to Jun 2026Releases
latest 60 of 126-
v0.12.2429 Jun 2026Release notes
Open source →Experimental interactive readline
The pure-PHP experimental readline implementation now has its own built-in pager. Long output opens in an alternate-screen pager with keyboard and mouse scrolling, search, wrap-aware layout, and sensible scrollback behavior after exit.
This is specific to PsySH's experimental userland readline, and it's another reason to give it a try:
psysh --experimental-readline
Or enable it in config:
'useExperimentalReadline' => true,The built-in pager is enabled automatically with experimental readline, or explicitly with
'pager' => true.We'd love your feedback! Try it out and let us know what works, what doesn't, and what still feels weird.
Better docs
docunderstands more PHP manual targets directly, including structured manual page IDs likelanguage.types.array, language type/operator pages, and language constructs likearrayandlist. Addresses #937 (thanks @Tomirad!)Manual output also got a big upgrade: variadic signatures make more sense; structured text, tables, and code blocks now render properly; PHP snippets get syntax highlighting; and wrapping works better across styled and wide-character output.
History improvements
- Added
history --sessionto show, save, or replay only commands from the current REPL session history --clearnow rejects filters and range options instead of accepting combinations it ignores
Bug fixes
- Fix exception formatting over-matching and eating the beginning of error messages. Fixes #943 (thanks @bilboque!)
- Fix
timeitmedian calculation - Fix
sudoinstantiation for classes without constructors - Avoid deprecated reflection calls on PHP 8.4+
Under the hood
- Readline rendering now uses widgets and a shared mode stack for completion, history search, and the pager
- Release automation now creates draft releases with
gh - Removed Codecov from CI
- Added Dependabot cooldowns and updated CI dependencies. Thanks @dependabot!
- Fixed Laravel and MediaWiki smoke tests
- Added
-
v0.12.2323 May 2026Release notes
Open source →Bug fixes
- Fix interactive readline bracket matching inside interpolated strings. Fixes #930
- Avoid infinite recursion in
ShellOutputwrite tracking (e.g.print_ron anExceptionwithzend.exception_ignore_args = Off). Fixes #934 - Include
--warm-autoloadin project trust restrictions - Exclude Symfony Console DI components from the autoload warmer (they're an optional dependency and blow up when not installed)
Under the hood
- Tighter callable types throughout
- Added MediaWiki downstream smoke tests, updated to 8.3
- Fixed Drush downstream tests
-
v0.12.2222 Mar 2026Release notes
Open source →Runtime config and clipboard support
PsySH has a new
configcommand for inspecting and updating runtime-configurable settings during the current session. You can tweak things likepager,theme,verbosity,useSuggestions,useSyntaxHighlighting,clipboardCommand, andsemicolonsSuppressReturnwithout restarting the shell. Fixes #361There’s also a new
copycommand for copying the last result ($_) or any expression to your clipboard. Works with system clipboard commands, or via OSC 52 for SSH and remote terminals.Configure with
clipboardCommandoruseOsc52Clipboardin your config.Semicolon-based return suppression
Optionally suppress return values by ending a statement with
;, similar to MATLAB/Octave behavior. Supports a'double'mode requiring;;for suppression (ifrequireSemicolonsis also enabled, bothtrueand'double'require;;).'semicolonsSuppressReturn' => true, 'semicolonsSuppressReturn' => 'double', // Always require ;; to suppress
Output and exception display improvements
Strings are now valid PHP!
- PsySH now preserves backslashes and other characters it previously mangled in a few cases. Fixes #351, #568
- Multiline strings are rendered using heredoc-style output rather than triple-quoted strings
""". The old format is available viauseDeprecatedMultilineStringsuntil the next major release.
Providing an
exceptionDetailscallback via config renders additional context about exceptions (e.g. validation errors) alongside the error message. Fixes #648A few other improvements:
- More consistent compact (and non-compact) output spacing.
- Responsive
helplayout adapts to terminal width.
Better completion for everyone
Legacy readline now shares PsySH’s newer completion engine, which brings much better parity between ext-readline/libedit and experimental interactive readline. Command argument completion, better multiline buffering, and a handful of command-dispatch edge cases now work much more consistently outside experimental readline too.
Commands can now define their own argument completions via
CommandArgumentCompletionAware.Interactive readline polish
New in the experimental interactive readline:
- Live syntax highlighting — code is highlighted as you type. Can be disabled via
useSyntaxHighlightingif you don't like colors, I guess. - Allman-style indenting — opening brackets on a new line get proper indentation.
- Improved auto-dedent — closing brackets automatically reduce indentation.
psy\info()and--infoalso report more detail about readline and autocomplete state.Run psysh with
--experimental-readlineand try it out. It's getting kind of awesome!Compatibility note
Bare
configandcopyat the prompt now resolve to PsySH commands before PHP function calls. Prefix ambiguous input with;to force PHP execution.Bug fixes
- Use aliases are now tracked by import type (class vs function vs constant), fixing resolution bugs with
use functionanduse conststatements. - Fix pager pipe warnings when user quits pager early
- Fix eval error messages incorrectly suppressing PsySH file paths
- Improve terminal width check on oldest supported Symfony versions
- Fix a code cleaner bug with
throw new Exceptionin PHP 7.4
Improvements
- Added
--pager/--no-pagerCLI options - Richer
psy\info()/--infooutput with interactive completion - Added hermetic test bootstrap, PTY smoketests, and additional downstream/composer-repl coverage
- Ctrl-C now interrupts the
editcommand instead of waiting for the editor to close
-
v0.12.2106 Mar 2026Release notes
Open source →Added an experimental interactive readline: a from-scratch pure-PHP readline replacement built specifically for PsySH. Instead of delegating to
ext-readlineorext-libedit, this gives PsySH full control over input, editing, completion, and rendering.This is opt-in and experimental. Default behavior is completely unchanged. Enable it in your config or from the command line:
'useExperimentalReadline' => true,psysh --experimental-readline
See the interactive readline wiki page for more!
Completions that actually understand your code
The new completion engine is syntax-aware, type-aware, and runtime-value-aware. It parses your input, resolves types from live objects in scope, and completes based on what your code actually is, not just string matching on symbol names.
Type
$user->and see that object's actual methods and properties. Chain through$repo->find(1)->and get completions for the return type. Fuzzy matching meansasumfindsarray_sumandstlfindsstrtolower. Completions show in a navigable multi-column menu.Multi-line editing
Press Enter on an incomplete statement and the input continues on the next line with proper indentation. Closing brackets auto-dedent. Shift+Enter always inserts a newline. No more fighting the shell to write a multi-line closure.
History
- Reverse history search (Ctrl+R) with an overlay showing match highlighting, smart-case filtering, deduplication, and keyboard navigation.
- Filtered history navigation: type part of a previous command, then press Up/Down to cycle through matching history entries.
And more
- Fish-style inline autosuggestions from your history. This one's still a bit rough; enable it separately with
'useSuggestions' => true. - Bracket and quote auto-pairing with smart backspace.
- Bracketed paste mode: pastes multi-line code verbatim without executing line-by-line.
- No
ext-readlineorext-libeditrequired. Works with any terminal. - Ctrl+L to clear the screen.
This addresses a bunch of long-standing issues: #234, #254, #309, #346, #506, #561, #668, #732, #769, #869.
We'd love your feedback! Give it a try, and let us know what works and what doesn't. The goal is to make this the default. Help us get it there. 🧪
-
v0.12.2011 Feb 2026Release notes
Open source →Project trust edge case fixes
Fixed several edge cases with the Restricted Mode introduced in v0.12.19 where non-interactive contexts (piped input,
execute()calls, Composer proxy scripts) could incorrectly trigger trust prompts or restrict trusted functionality.Fixes #913
Commands work better outside the shell
Decoupled commands from
ShellOutputvia a newShellOutputAdapter, so commands degrade gracefully when used in non-interactive contexts rather than failing on missing shell features.Improvements
- Added downstream compatibility tests for local and CI workflows
- Moved internal helper scripts from
bin/toscripts/
-
v0.12.1930 Jan 2026Release notes
Open source →⚠️ Security fix
Fixed a CWD configuration poisoning vulnerability (CVE-2026-25129) where a malicious
.psysh.phpfile in an attacker-writable directory could execute arbitrary code when a victim runs PsySH from that directory. This affects all versions prior to v0.12.19 and v0.11.23, including downstream consumers like Laravel Tinker, when invoked from an attacker-writable CWD.Fixed in v0.12.19 and v0.11.23. Upgrade ASAP.
Restricted Mode
PsySH now requires explicit trust before loading project-local config (
.psysh.php), local PsySH binaries, or Composer autoloads from untrusted projects. Trust decisions are persisted per-project intrusted_projects.json.Configure with
trustProject:'trustProject' => 'prompt', // default — ask interactively 'trustProject' => 'always', // trust all projects 'trustProject' => 'never', // always run restricted
Or use
--trust-project/--no-trust-projectCLI flags, or thePSYSH_TRUST_PROJECTenv var.Non-interactive sessions automatically skip untrusted features with a warning.
Magic method and property support 🪄
Tab completion,
ls,doc, andshowcommands now recognize@methodand@propertydocblock tags. Magic members display in magenta so you can tell them apart from real methods and properties.Inheritance works as expected — magic members from parent classes, interfaces, and traits are included, with child declarations taking precedence.
Also fixes parsing of generic types (e.g.,
array<int, string>) in docblock tags, which previously broke on whitespace inside angle brackets.See #905
Improvements
- Excluded a few unnecessary files and folders from release source zips (Thanks @reedy!)
- Fixed
--cwdto actually change the working directory. Previously it only affected discovery for autoload/config, so relative paths and other directory-dependent behavior didn’t work as expected inside the shell. - Significantly improved memory usage with older php-parser versions (pre-v4.18.0)
-
v0.12.1817 Dec 2025Release notes
Open source →- Fix
exit()not working when uopz extension is loaded - Don't reopen pager if user closes it early
- Ensure stty state is restored before exiting PsySH (fixes an issue where
Ctrl-Cmight be incorrectly handled after exiting)
- Fix
-
v0.12.1715 Dec 2025Release notes
Open source →Hot code reloading!!?!?1?
Install the uopz extension (5.0+) and PsySH will automatically reload modified files during your session. Edit code, switch back to PsySH, and your changes are live—no restart needed!
What gets reloaded
- Method bodies (including private/protected)
- Function implementations (and new functions!)
- Class and global constants
What can't be reloaded
- New class methods
- Class properties, inheritance, or interfaces
- Method signatures
PsySH skips "risky" reloads by default (conditional definitions, static variables). Use the new
yolocommand to bypass safety checks:>>> my_helper() Warning: Skipped conditional: if (...) { function my_helper() ... } >>> yolo !! => "result"See the documentation for more details.
Bug fixes
- Fix "array offset on null" warning on
Ctrl-C— plays nicer with Laravel + PHP 8.5 - Work around O(n²) performance in Symfony OutputFormatter
-
v0.12.1607 Dec 2025 -
v0.12.1528 Nov 2025Nothing published for this version
-
v0.12.1427 Oct 2025Nothing published for this version
-
v0.12.1320 Oct 2025Nothing published for this version
-
v0.12.1220 Sep 2025Nothing published for this version
-
v0.12.1120 Sep 2025Nothing published for this version
-
v0.12.1004 Aug 2025Nothing published for this version
-
v0.12.923 Jun 2025Nothing published for this version
-
v0.12.816 Mar 2025Nothing published for this version
-
v0.12.710 Dec 2024Nothing published for this version
-
v0.12.607 Dec 2024Nothing published for this version
-
v0.12.529 Nov 2024Nothing published for this version
-
v0.12.410 Jun 2024Nothing published for this version
-
v0.12.302 Apr 2024Nothing published for this version
-
v0.12.217 Mar 2024Nothing published for this version
-
v0.12.115 Mar 2024Nothing published for this version
-
v0.12.020 Dec 2023Nothing published for this version
-
v0.11.2330 Jan 2026Release notes
Open source →- Fixed CWD configuration poisoning vulnerability (CVE-2026-25129). Backported Restricted Mode from v0.12. PsySH now requires explicit trust before loading local config (
.psysh.php), local PsySH binaries, or Composer autoloads from untrusted projects. Configure withtrustProjectconfig option,--trust-project/--no-trust-projectCLI flags, orPSYSH_TRUST_PROJECTenv var.
- Fixed CWD configuration poisoning vulnerability (CVE-2026-25129). Backported Restricted Mode from v0.12. PsySH now requires explicit trust before loading local config (
-
v0.11.2214 Oct 2023Nothing published for this version
-
v0.11.2117 Sep 2023Nothing published for this version
-
v0.11.2031 Jul 2023Nothing published for this version
-
v0.11.1915 Jul 2023Nothing published for this version
-
v0.11.1823 May 2023Nothing published for this version
-
v0.11.1705 May 2023Nothing published for this version
-
v0.11.1626 Apr 2023Nothing published for this version
-
v0.11.1507 Apr 2023Nothing published for this version
-
v0.11.1428 Mar 2023Nothing published for this version
-
v0.11.1321 Mar 2023Nothing published for this version
-
v0.11.1229 Jan 2023Nothing published for this version
-
v0.11.1123 Jan 2023Nothing published for this version
-
v0.11.1023 Dec 2022Nothing published for this version
-
v0.11.906 Nov 2022Nothing published for this version
-
v0.11.828 Jul 2022Nothing published for this version
-
v0.11.707 Jul 2022Nothing published for this version
-
v0.11.603 Jul 2022Nothing published for this version
-
v0.11.527 May 2022Nothing published for this version
-
v0.11.406 May 2022Nothing published for this version
-
v0.11.305 May 2022Nothing published for this version
-
v0.11.228 Feb 2022Nothing published for this version
-
v0.11.103 Jan 2022Nothing published for this version
-
v0.11.005 Dec 2021Nothing published for this version
-
v0.10.1230 Nov 2021Nothing published for this version
-
v0.10.1123 Nov 2021Nothing published for this version
-
v0.10.1023 Nov 2021Nothing published for this version
-
v0.10.910 Oct 2021Nothing published for this version
-
v0.10.810 Apr 2021Nothing published for this version
-
v0.10.714 Mar 2021Nothing published for this version
-
v0.10.618 Jan 2021Nothing published for this version
-
v0.10.504 Dec 2020Nothing published for this version
-
v0.10.403 May 2020Nothing published for this version
-
v0.10.307 Apr 2020Nothing published for this version
-
v0.10.221 Mar 2020Nothing published for this version