Monoweave

View GitHub Project

FAQ

Can Monoweave be used without Yarn Modern/Berry?

No. Monoweave uses Yarn Modern's public API to do most of the heavy lifting in reading and writing to your project.

Can I use monoweave for non-JavaScript projects?

Yes. The only requirement is that you organize your project using Yarn Modern (i.e. Yarn v4+). You can create a minimal Yarn project by creating a root

package.json
and then one
package.json
per package/workspace. In this scenario, you likely want to use the "No Registry" mode.

Although designed for publishing to NPM, you can disable all npm interactions by passing in a

--registry-mode manifest
flag to the CLI or setting
registryMode
to
manifest
in your config file. A registry mode of
manifest
will set the package.json of each workspace as the source of truth for versions. This means when reading package versions, the package.json is used instead of reading from NPM. Likewise, package publishing to npm is also disabled. If using the "Manifest" registry mode, you should also enable
--persistVersions
(
persistVersions
) and commit the modified package.json files to your repository, otherwise there's no proper reference for the package versions.

How can I preview changes before publishing?

You can run:

yarn monoweave --dry-run --changeset-filename=-

to implicitly disable logs and only output the changeset data. This is useful for previewing changes or determining which packages will be modified from a Pull Request.

If using GitHub Actions, also check out our release preview reusable action: monoweave/github-action-preview@main.

Packages I haven't modified are being published with a patch version bump, what's going on?

In addition to the version strategies associated with packages explicitly modified via your commits, what we call the explicit version strategies, Monoweave will also perform a patch version strategy bump to all dependent packages, what we call implicit version strategies. The idea behind this is that when you run tests and do development in your monorepo, you are always working with the latest packages. Therefore if Package-A depends on Package-B and Package-B has been modified, we also want to release a version of Package-A where Package-A's version range for Package-B has been increased. This Package-A that a downstream project consumes will then be guaranteed to be using the same version of Package-B that is used in the monorepo itself.

As an added benefit, downstream projects using systems like Renovate or Dependabot, will also receive updates for Package-A that will bring in the updated Package-B.

If there is a use case where you believe this behaviour is does not make sense, please open an issue and we'll be glad to discuss.

Note that when using package groups (equivalent of Lerna's fixed mode), the highest version strategy from among each group is chosen. In this case, you may find a dependent package with a minor or even major version bump, assuming such a strategy exists for an intentional bump within said group.

How does Monoweave handle private packages?

Private packages, i.e. packages containing a

private: true
field in their manifest, are includes as part of dependency graph traversal and in determining version strategies, but are not published to any registry. Monoweave filters out private packages from git tag creation as well.

Note that the top level workspace is a special case. It is neither published, nor considered part of the dependency graph. In other words, all dependency paths are terminated at the top level workspace rather than traverse through this workspace.

How can I manually trigger a release (i.e. ignore commits)?

If you do not want to have releases based on commit messages, use the "manual" preset:

module.exports = { preset: 'monoweave/preset-manual' }

and then commit change files generated via:

yarn monoweave version

If using automatic mode, there is currently no way to force a manual release.

How can I achieve behaviour similar to Lerna's fixed version mode?

Fixed version mode can be achieved by setting the

packageGroupManifestField
in your monoweave configuration, or via the CLI argument. This config option should be set to some field in each workspace's manifest file to indicate fixed version grouping. For example, you can add a "group" field set to "components" for some workspaces and "utils" for other workspaces. Monoweave will then ensure all workspaces with changes (or dependent changes) in the "components" group have the same version bump. To achieve fixed versioning of all workspaces, you need to specify a field that all workspaces have in common. You can also enforce this with the use of the Yarn Constraints plugin.

How does Monoweave differ from ...?

Monoweave only supports Yarn-modern projects with minimum Node version >=18.19.

ToolPackage ManagersMonorepo SupportConventional CommitsChangeset FilesChangelogspublishConfig overridesworkspace:^ protocolVersion GroupsPull Request PreviewsGitHub ReleasesPlugin Support
Monoweaveyarn
Lernayarn, npm, pnpm🟨
Lerna Liteyarn, npm, pnpm🟨
Yarn Version Pluginyarn
Atlassian Changesetsyarn*, npm, pnpm
Microsoft Beachballyarn, npm, pnpm*
Semantic Releaseyarn, npm, pnpmN/AN/A

Legend: ✅ supported, 🟨 partial support, ❌ not supported

If you notice an error or inaccuracy in the above comparison table, please open a GitHub issue. It's not possible to remove bias, however this should still be an accurate representation of how monoweave compares to other tooling.

Feature definitions/notes:

  1. Package Managers: Monoweave only supports Yarn modern. Changesets partially supports Yarn modern since they don't use Yarn internally to publish so don't natively support Yarn workspace protocols (e.g.
    workspace:^
    ).
  2. Monorepo Support: Only semantic release in the above list doesn't support monorepos. All other tools, including monoweave, also support publishing a single non-monorepo package.
  3. Conventional Commits: Monoweave, Lerna, and Semantic Release all support reading git commit messages according to conventional commits to determine the version strategy to apply. This behaviour can be disabled in monoweave, but is required for semantic release (Lerna does have a way to version from the command line to bypass commit messages).
  4. Changeset Files: This is called "manual mode" in monoweave, and is a more explicit versioning approach compared to the conventional commits parsing above. Monoweave's changeset files are called "version files" and follow a format very similar to Changesets.
  5. Changelogs: When using the conventional commits mode with Monoweave, changelogs are generated using conventional changelogs, otherwise there's a default writer that pulls changelogs from manual version files.
  6. publishConfig overrides: Monoweave uses Yarn publishing internally which will copy some fields from your package.json's publishConfig property. This enables a pattern of having "main" point to source code and "publishConfig.main" point to build artifacts.
  7. workspace:^ protocol: Yarn supports listing workspace dependencies using
    workspace:^
    and
    workspace:*
    . This instructs Yarn to resolve the dependency to a local version instead of remote. Monoweave removes the workspace protocol during publish and respects the version range specifier (
    ^
    and
    *
    ).
  8. Version Groups: Lerna offers a "fixed/locked" mode that ties all versions in a project together, however it's marked as "partial" in the table above since it doesn't offer granularity within a monorepo. Beachball calls this version groups.
  9. Pull Request Previews: Monoweave has a GitHub Action for pull request previews. It can be adapted for other CI systems if there's demand.
  10. GitHub Releases: Monoweave implements GitHub releases using the monoweave plugin system. We have some open issues tracking additional functionality for the plugin.
  11. Plugin Support: Monoweave exposes tappable hooks, this is how the GitHub releases functionality is added. Since Monoweave uses Yarn internally, Yarn plugins can also be used to extend monoweave.