Start Date Release Date Release Versions PR link Tracking Link Stage Teams
3/6/2023 9/21/2023
  • ember-cli: v5.3.0
Recommended
  • CLI
  • Learning

pnpm support

Summary

Enable Ember CLI users to opt into using pnpm for package management.

Motivation

pnpm is a popular alternative to both npm and yarn that prioritizes correctness, especially for peerDependencies and monorepos.

pnpm has very active maintainance, support, and financial funding. Their website states that pnpm is:

  • Fast: pnpm is up to 2x faster than the alternatives
  • Efficient: Files inside node_modules are cloned or hard linked from a single content-addressable storage
  • Supports monorepos: pnpm has built-in support for multiple packages in a repository
  • Strict: pnpm creates a non-flat node_modules by default, so code has no access to arbitrary packages.

For folks with lots of projects on their computers, pnpm is extremely space-efficient. Where npm and yarn would duplicate node_modules per-project, pnpm will only download a package (at a specific version) once across your whole machine.

Additionally, npm and yarn repeatedly have demonstrated that their strategies with peerDependencies are not correct, and it is vitally important we use and support a tool that can guide folks towards correctly creating addons. For example, @embroider/macros relies on node's resolution algorithm, so having peerDependencies resolved correctly is important for dependencySatisfies to work as expected in monorepos.

Ember CLI currently only supports npm (default) and yarn for project initialization as well as various commands. At present, projects work with pnpm, but the tooling is unaware.

Detailed design

Enabling pnpm is designed as opt-in to prevent disruptions to developer's current workflow, much the same as yarn.

There are a few integration points that we must support for pnpm (and any package manager):

  • ember install
  • ember init, ember new, ember addon
  • ember try:one, ember try:each
  • generated C.I. configs
  • Documenation

ember install

There are two mechanisms through which to opt-in. The first one is the presence of a pnpm-lock.yaml file in the project root.

The pnpm-lock.yaml file is generated by pnpm when you run pnpm install (or the shorter pnpm i), so we assume that its presence means the developer intends to use pnpm to manage their dependencies.

Alternatively you, you can force Ember CLI to use pnpm with the --pnpm flag.

To recap:

  • ember install ember-resources with pnpm-lock.yaml present will use pnpm
  • ember install ember-resources without pnpm-lock.yaml present will use npm
  • ember install ember-resources --pnpm will use pnpm

ember init, ember new, ember addon

Since this triad of commands is generally ran before a project is set up, there is no pnpm-lock.yaml file presence to check. This means we are left with the --pnpm flag, which will also be added to these commands:

  • ember new my-app will use npm
  • ember new my-app --pnpm will use pnpm

The above also applies to ember addon and ember init, noting that ember init doesn't receive any arguments.

--skip-npm

The --skip-npm flag actually means "skip installation of dependencies" when using ember addon and ember new, including skipping installation with both npm and yarn. This will need to be extended to also skip installation of dependencies when pnpm is used.

For example:

ember new my-app --pnpm --skip-npm

ember try:one, ember try:each

At the time of writing this RFC, ember-try already supports pnpm, but it is undocumented in the README. Documentation will need to be added to the README, as well as the relevant ember-cli blueprints will need to correctly configure usePnpm: true in the ember-try.js config file when the pnpm flag is present.

generated C.I. configs

At the time of writing this RFC, ember-cli supports two C.I. environments: Travis and GitHub Actions.

Both the .travis.yml and .github/workflows/ci.yml config files for relevant blueprints will need to support the pnpm option such that C.I. passes on new projects using pnpm.

for addons

Addons should be stricter than defaults, so that they are good stewards of the ecosystem and don't leak accidental uncertainty to their consumers.

In addon projects, the .npmrc will need the following defaults:

# all peer dependencies must be declared or forwarded to the consumer
auto-install-peers=false

# we want true isolation in addons -- if a dependency is not declared, we want an error
reslove-peers-from-workspace-root=false

Documentation

These pages presently mention npm / yarn and will need to be updated to include pnpm

  • https://cli.emberjs.com/release/basic-use/assets-and-dependencies/
  • https://guides.emberjs.com/release/addons-and-dependencies/

How we teach this

The Ember Guides should be updated to reflect the new flags, where applicable, as well as the new behavior of ember install in the presence of a pnpm-lock.yaml -- though most of the guides use ember as the CLI tool for managing packages.

We may want to consider updating the tutorial (and its automation) to use pnpm, as npm is very slow.

In addition, the built-in instructions for ember help should be updated to reflect the new flags.

Drawbacks

  • pnpm is very strict about peers and what dependencies are allowed in a project and will error if a project's package.json is incorrect for a given scenario. pnpm is very clear about these errors and what to do for action items, but it means that we'll need to make sure that pnpm is tested in ember-cli when generating new projects so that we can be certain that folks' "first time experience" is smooth
  • There may be other package managers in the future, but we cannot see the future. There have been talks about making ember-cli somehow generically handle package-managers, but it is unknown how that would work, and is unneeded for now.

Alternatives

  • Figure out a way to generically handle any package manager
  • Continue with the partial pnpm support we have today

Unresolved questions

  • Are there any other references in the guides to npm or yarn? The only place I could find that mentioned yarn is here: https://guides.emberjs.com/release/addons-and-dependencies/
  • Is there a --package-manager flag / option in ember-cli? for blueprint authors, that may be useful.
  • Should --skip-npm be aliased to --skip-install?