Skip to main content
The npm module manages Node.js packages using npm (Node Package Manager).

Functions

packages

Install, remove, or update npm packages.
from pyinfra.operations import npm

npm.packages(
    name="Install Node.js packages",
    packages=["express", "lodash"],
)
packages
str | list[str]
List of packages to ensure.
present
bool
default:true
Whether the packages should be present.
latest
bool
default:false
Whether to upgrade packages without a specified version.
directory
str
Directory to manage packages for. Defaults to global installation.
Package versions can be pinned like npm: <pkg>@<version>

Examples

from pyinfra.operations import npm

# Install packages globally
npm.packages(
    name="Install global npm packages",
    packages=["typescript", "nodemon"],
)

Common Use Cases

Express.js Application Setup

from pyinfra.operations import npm

npm.packages(
    name="Install Express.js dependencies",
    packages=[
        "[email protected]",
        "body-parser",
        "cors",
        "dotenv",
        "mongoose",
    ],
    directory="/var/www/api",
)

React Application

from pyinfra.operations import npm

npm.packages(
    name="Install React dependencies",
    packages=[
        "[email protected]",
        "[email protected]",
        "react-router-dom",
        "axios",
    ],
    directory="/var/www/frontend",
)

Global Development Tools

from pyinfra.operations import npm

npm.packages(
    name="Install global development tools",
    packages=[
        "typescript",
        "nodemon",
        "pm2",
        "eslint",
        "prettier",
    ],
)

Install from package.json

from pyinfra.operations import server

# Install all dependencies from package.json
server.shell(
    name="Install npm dependencies",
    commands=["cd /app && npm install"],
)

Build Tools

from pyinfra.operations import npm

npm.packages(
    name="Install build tools",
    packages=[
        "webpack",
        "webpack-cli",
        "babel-loader",
        "@babel/core",
        "@babel/preset-env",
    ],
    directory="/var/www/myapp",
)

Testing Framework

from pyinfra.operations import npm

npm.packages(
    name="Install testing tools",
    packages=[
        "jest",
        "@testing-library/react",
        "@testing-library/jest-dom",
        "supertest",
    ],
    directory="/app",
)

npm-Specific Tips

Global packages (no directory parameter):
  • Installed system-wide
  • Typically CLI tools
  • Use npm install -g
Local packages (with directory parameter):
  • Installed in project’s node_modules
  • Project dependencies
  • Use npm install in directory
from pyinfra.operations import npm

# Global: CLI tools
npm.packages(
    name="Install global tools",
    packages=["typescript", "nodemon"],
)

# Local: Project dependencies
npm.packages(
    name="Install project dependencies",
    packages=["express", "mongoose"],
    directory="/app",
)
For full project setups, use package.json:
from pyinfra.operations import files, server

# Upload package.json
files.put(
    name="Upload package.json",
    src="local/package.json",
    dest="/app/package.json",
)

# Install all dependencies
server.shell(
    name="Install npm dependencies",
    commands=["cd /app && npm install"],
)

# For production (skip devDependencies)
server.shell(
    name="Install production dependencies",
    commands=["cd /app && npm install --production"],
)
Update packages to latest versions:
from pyinfra.operations import npm

# Update specific packages
npm.packages(
    name="Update packages",
    packages=["express", "lodash"],
    latest=True,
    directory="/app",
)

# Or use npm update directly
from pyinfra.operations import server

server.shell(
    name="Update all packages",
    commands=["cd /app && npm update"],
)
Install scoped packages (organization packages):
from pyinfra.operations import npm

npm.packages(
    name="Install scoped packages",
    packages=[
        "@babel/core",
        "@testing-library/react",
        "@types/node",
    ],
    directory="/app",
)
Perform a clean install (removes node_modules):
from pyinfra.operations import server

server.shell(
    name="Clean install dependencies",
    commands=[
        "cd /app",
        "rm -rf node_modules",
        "npm ci",  # Clean install from package-lock.json
    ],
)
Install from private npm registries:
from pyinfra.operations import server

# Set registry
server.shell(
    name="Configure private registry",
    commands=[
        "npm config set registry https://registry.company.com",
    ],
)

# Or use .npmrc file
from pyinfra.operations import files

files.put(
    name="Upload .npmrc",
    src="local/.npmrc",
    dest="/app/.npmrc",
)

Best Practices

Always commit and deploy package-lock.json for reproducible builds:
from pyinfra.operations import files, server

files.put(
    name="Upload package files",
    src="local/package.json",
    dest="/app/package.json",
)

files.put(
    name="Upload lock file",
    src="local/package-lock.json",
    dest="/app/package-lock.json",
)

server.shell(
    name="Install exact versions",
    commands=["cd /app && npm ci"],
)
from pyinfra.operations import server

# Production: skip devDependencies
server.shell(
    name="Install production dependencies",
    commands=["cd /app && npm install --production"],
)

# Development: install all
server.shell(
    name="Install all dependencies",
    commands=["cd /app && npm install"],
)
from pyinfra.operations import npm

# Pin major versions for stability
npm.packages(
    name="Install with version constraints",
    packages=[
        "[email protected]",    # Exact version
        "lodash@^4.17.21",    # Compatible version
    ],
    directory="/app",
)

Important Notes

When no directory is specified, packages are installed globally using npm install -g.
Global npm installations may require sudo/administrator privileges depending on Node.js installation.
For production deployments, use npm ci instead of npm install for faster, more reliable builds.

Build docs developers (and LLMs) love