# Setup with Turborepo

Syncpack is a developer tool designed to keep your package.json dependencies in sync in a monorepo setup. It can be used both as a linter to detect version mismatches and as a fixer to automatically resolve them.

To configure Syncpack in a monorepo managed with Turborepo, follow these steps 👇

# Install the packages

Open a terminal at the root of the solution's workspace (the root of the repository) and install the following packages:

pnpm add -D syncpack turbo

# Configure Turborepo

First, create a configuration file named turbo.json at the root of the solution's workspace:

workspace
├── packages
├──── pkg-1
├────── src
├──────── ...
├────── package.json
├── package.json
├── turbo.json

Then, open the newly created file and copy/paste the following content:

{
    "$schema": "https://turbo.build/schema.json",
    "ui": "tui",
    "tasks": {
        "lint": {
            "dependsOn": ["//#syncpack"]
        },
        "//#syncpack": {}
    }
}

The //#syncpack task will only execute the syncpack script at the root of the solution's workspace.

# Configure Syncpack

Next, let's configure Syncpack. Create a configuration file named .syncpackrc.js at the root of the solution's workspace:

workspace
├── packages
├──── pkg-1
├────── src
├──────── ...
├────── package.json
├── package.json
├── turbo.json
├── .syncpackrc.js

Then, open the newly created file and copy/paste the following boilerplate configuration:

.syncpackrc.js
// @ts-check

/** @type {import("syncpack").RcFile} */
export default {
    "lintFormatting": false,
    "semverGroups": [
        {
            "packages": ["@[YOUR_PROJECT_SCOPE]/apps/*"],
            "dependencyTypes": ["prod", "dev"],
            "range": "",
            "label": "Apps should pin dependencies and devDependencies."
        },
        {
            "packages": ["@[YOUR_PROJECT_SCOPE]/packages/*"],
            "dependencyTypes": ["peer"],
            "range": "^",
            "label": "Packages should use ^ for peerDependencies."
        },
        {
            "packages": ["workspace-root"],
            "dependencyTypes": ["dev"],
            "range": "",
            "label": "Workspace root should pin devDependencies."
        }
    ],
    "versionGroups": [
        {
            "packages": ["**"],
            "dependencyTypes": ["prod", "dev", "peer"],
            "preferVersion": "highestSemver",
            "label": "Packages and Apps should have a single version across the repository."
        }
    ]
};

Then, replace [YOUR_PROJECT_SCOPE] by your project scope.

# Add CLI scripts

Finally, add the lint and syncpack scripts to your solution's workspace package.json file.

workspace
├── packages
├──── pkg-1
├────── src
├──────── ...
├────── package.json
├── package.json    <------- (this one!)
├── turbo.json
├── .syncpackrc.js

The lint script will execute the lint task and its dependencies configured earlier in the turbo.json file:

package.json
{
    "lint": "turbo run lint --continue"
}

The //#syncpack script will lint the root of the solution's workspace:

package.json
{
    "syncpack": "syncpack lint"
}

# Try it 🚀

To test your new Syncpack setup:

  1. Identify a dependency that is installed in multiple projects within the monorepo.
  2. Open a terminal at the root of the workspace and run the CLI script added earlier. Syncpack should complete without reporting any errors:
pnpm lint
  1. In one of the projects, bump the version of that dependency, and run the script again:
pnpm lint
  1. Syncpack should report a version mismatch error in the terminal.