npm run, with PDM, you can run arbitrary scripts or commands with local packages loaded.
It will run
flask run -p 54321 in the environment that is aware of packages in
There is a builtin shortcut making all scripts available as root commands
as long as the script does not conflict with any builtin or plugin-contributed command.
Said otherwise, if you have a
test script, you can run both
pdm run test and
But if you have an
install script, only
pdm run install will run it,
pdm install will still run the builtin
PDM also supports custom script shortcuts in the optional
[tool.pdm.scripts] section of
You can then run
pdm run <script_name> to invoke the script in the context of your PDM project. For example:
And then in your terminal:
Any following arguments will be appended to the command:
PDM supports 4 types of scripts:
Plain text scripts are regarded as normal command, or you can explicitly specify it:
In some cases, such as when wanting to add comments between parameters, it might be more convenient to specify the command as an array instead of a string:
1 2 3 4 5 6 7
Shell scripts can be used to run more shell-specific tasks, such as pipeline and output redirecting.
This is basically run via
The script can be also defined as calling a python function in the form
The function can be supplied with literal arguments:
This script kind execute other defined scripts:
1 2 3 4
pdm run all will run
lint first and then
You can also provide arguments to the called scripts:
1 2 3 4
Argument passed on the command line are given to each called task.
All environment variables set in the current shell can be seen by
pdm run and will be expanded when executed.
Besides, you can also define some fixed environment variables in your
1 2 3
Note how we use TOML's syntax to define a composite dictionary.
Environment variables specified on a composite task level will override those defined by called tasks.
You can also store all environment variables in a dotenv file and let PDM read it:
1 2 3
A dotenv file specified on a composite task level will override those defined by called tasks.
To make sure the running environment is properly isolated from the outer Python interpreter,
site-packages from the selected interpreter WON'T be loaded into
sys.path, unless any of the following conditions holds:
- The executable is from
PATHbut not inside the
-s/--site-packagesflag is following
site_packages = trueis in either the script table or the global setting key
Note that site-packages will always be loaded if running with PEP 582 enabled(without the
pdm run prefix).
If you want the options to be shared by all tasks run by
you can write them under a special key
1 2 3 4
Besides, inside the tasks,
PDM_PROJECT_ROOT environment variable will be set to the project root.
Show the List of Scripts#
pdm run --list/-l to show the list of available script shortcuts:
1 2 3 4 5 6 7 8
You can add an
help option with the description of the script, and it will be displayed in the
Description column in the above output.
Pre & Post Scripts#
npm, PDM also supports tasks composition by pre and post scripts, pre script will be run before the given task and post script will be run after.
1 2 3 4
In this example,
pdm run compress will run all these 3 scripts sequentially.
The pipeline fails fast
In a pipeline of pre - self - post scripts, a failure will cancel the subsequent execution.
Under certain situations PDM will look for some special hook scripts for execution:
post_init: Run after
pre_install: Run before installing packages
post_install: Run after packages are installed
pre_lock: Run before dependency resolution
post_lock: Run after dependency resolution
pre_build: Run before building distributions
post_build: Run after distributions are built
pre_publish: Run before publishinbg distributions
post_publish: Run after distributions are published
pre_script: Run before any script
post_script: Run after any script
pre_run: Run once before run script invocation
post_script: Run once after run script invocation
Pre & post scripts can't receive any arguments.
Avoid name conflicts
If there exists an
install scripts under
scripts can be triggered by both
pdm install and
pdm run install. So it is
recommended to not use the preserved names.
Composite tasks can also have pre and post scripts. Called tasks will run their own pre and post scripts.
Because, sometimes it is desirable to run a script but without its hooks or pre and post scripts,
there is a
--skip=:all which will disable all hooks, pre and post.
There is also
--skip=:post allowing to respectively
pre_* hooks and all
It is also possible to need a pre script but not the post one,
or to need all tasks from a composite tasks except one.
For those use cases, there is a finer grained
accepting a list of tasks or hooks name to exclude.
This command will run the
my-composite task and skip the
pre_task1 hook as well as the
task2 and its hooks.
You can also provide you skip list in
PDM_SKIP_HOOKS environment variable
but it will be overridden as soon as the
--skip parameter is provided.
There is more details on hooks and pre/post scripts behavior on the dedicated hooks page.