vimeo/psalm: static analysis for PHP applications
A PHP static analysis tool for finding errors and security vulnerabilities in PHP applications
At a glance
- What is it?
- Psalm is a static analysis tool that reads PHP source without running it, inferring types and tracing tainted input. This review covers what it checks, how to install it, and where it stops being the right choice.
- Who is it for?
- Psalm is worth adopting if your codebase is large enough that runtime testing misses whole classes of type and taint bugs, and if you can afford to work through a baseline of existing findings. It is the wrong tool if you want a formatter, a runtime profiler, or a checker that needs no configuration at all.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly PHP, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The problem Psalm targets in PHP codebases
PHP is dynamically typed by default, so a function that receives an array where a string was expected fails at runtime, in whichever request happens to hit that path. Unit tests cover the paths someone remembered to write. Psalm reads the source instead and reports type mismatches, undefined symbols and taint flows before the code runs. The audience is teams maintaining PHP applications large enough that no single person holds the call graph in their head, and security-conscious projects that want tainted input traced from a request parameter to a sink such as a database query or an echo. The repository topics list static-analysis, type-inference and taint-analysis, which maps directly onto those two jobs. It is not a linter for style. Running Psalm on a codebase with no annotations produces a long report, and the project ships a baseline mechanism precisely because that first run is noisy.
How Psalm infers types and traces taint
Psalm builds a model of the codebase from the source files it is told to scan, using stubs to describe PHP's own functions and extensions. Where a value's type is not written in a docblock or a native type declaration, Psalm infers it from assignments, return statements and control flow. The repository layout reflects this: src/ holds the analyser, stubs/ holds signatures for internal and third-party code, dictionaries/ holds word lists used by some checks, and config.xsd is the schema for the configuration file. The configuration file is where you declare the files to scan, the error level, and any plugins. Plugins are a documented extension point, and examples/plugins/ in the repository shows the shape of one. The psalm-language-server binary in the repository root is the language server entry point, which is how editor integrations get findings as you type rather than only in CI. Reports can be written as a baseline file, psalm-baseline.xml, which records current findings so that only new ones fail a build.
Installing Psalm and running it the first time
The README points to docs/running_psalm/installation.md for setup rather than giving the commands inline, so the exact steps live in the documentation folder. The package is published on Packagist as vimeo/psalm, and the README shows the Packagist badge pointing at packagist.org/packages/vimeo/psalm. What the repository does show is the set of binaries it ships in the root: psalm, psalter, psalm-plugin, psalm-refactor, psalm-review and psalm-language-server. The configuration file the analyser reads is psalm.xml, and psalm.xml.dist sits at the repository root as the distributed version. config.xsd describes the accepted keys. The README also links a live demo on psalm.dev, which is the documented way to try the analyser without installing anything, and the docs folder is the source for the documentation published on the website.
Where Psalm gets in the way
The first run is the obvious cost. A mature codebase produces a report large enough that teams usually adopt the baseline immediately, and a baseline is a debt record: it silences real findings as well as false ones, and nothing in the tool forces anyone to shrink it. Inference also has limits. Code that relies on dynamic features such as variable variables, heavy reflection or magic methods can produce findings that are not real bugs, and suppressing them means either annotations or configuration entries. The README names a single active maintainer, which is worth knowing when you plan to depend on the analyser in CI: response time on issues is a function of one person's availability. There is also a 7.0.0-beta release line alongside the stable 6.x line, so version choice matters. If you want formatting, dead-code removal or runtime profiling, Psalm is not that tool, and pairing it with something else is the honest answer rather than stretching it.
How Psalm differs from PHPStan
PHPStan is the other widely used static analyser for PHP, and the difference is in emphasis rather than category. PHPStan's progression is built around rule levels that you raise as you clean up a codebase, which gives a clear ladder from level 0 upward. Psalm's equivalent dial is the error level in psalm.xml, plus a baseline file for freezing current findings. Both infer types; Psalm's repository topics call out taint-analysis explicitly, which is the security-oriented path from user input to dangerous sinks. Both support extension through plugins and both ship a language server for editor integration. The practical difference for a team choosing between them is which one's configuration model and report format fits the workflow already in place, because migrating an annotated codebase from one to the other is real work either way.
Licence and the cost of keeping Psalm current
Psalm is MIT licensed, which permits commercial use, modification and redistribution provided the copyright notice and permission notice are retained. The repository includes a LICENSE file and a keys.asc.gpg file, the latter used for signing release artefacts. That is a factual note, not legal advice; if your organisation has licence policy, run the MIT terms past whoever owns it. On upgrade cost, the repository carries an UPGRADING.md file, which is the document to read before moving between major versions. The stable line is 6.x and the default branch is 6.x, while 7.0.0-beta releases are published alongside it, so a team on stable should track 6.x releases and read UPGRADING.md before any major jump. The README states that support contracts are available from the current maintainer for integration work and feature development, which is the documented commercial path if you need guaranteed attention.
Editorial conclusion
Psalm is worth adopting if your codebase is large enough that runtime testing misses whole classes of type and taint bugs, and if you can afford to work through a baseline of existing findings. It is the wrong tool if you want a formatter, a runtime profiler, or a checker that needs no configuration at all. Before committing, verify that the version you install matches your PHP runtime, that you understand what psalm.xml.dist controls, and that your team will actually read the reports rather than regenerating the baseline to silence them.
Frequently asked questions
How do I install vimeo/psalm?
The package is published on Packagist as vimeo/psalm, and the README directs readers to docs/running_psalm/installation.md for the setup steps. The live demo on psalm.dev is the documented way to try it without installing anything.
What does vimeo/psalm actually check?
The README describes it as a static analysis tool for finding errors in PHP applications, and the repository topics list static-analysis, type-inference and taint-analysis. That covers type inference from source and tracing tainted input toward dangerous sinks.
Can vimeo/psalm be used on a large existing codebase?
Yes, and the repository ships a baseline file, psalm-baseline.xml, for exactly that case. Recording current findings there means later runs can focus on newly introduced issues instead of the whole backlog.
Is vimeo/psalm actively maintained?
The repository is not archived, and the last push was on 2026-09-21. The README names Daniil Gentili as the only active maintainer, with Matt Brown as the original author and Orklah and Bruce Weirdan listed as former maintainers.
What licence does vimeo/psalm use?
The repository is MIT licensed and includes a LICENSE file. MIT permits commercial use and modification as long as the copyright and permission notices are retained.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/vimeo-psalm)