#
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.
For additional information, refer to the Turborepo documentation.
#
Configure Syncpack
A Syncpack configuration is highly specific to each project. While the following boilerplate offers a starting point for many use cases, it's important to review and tailor it to fit your project's particular needs.
Look at other project configurations as inspiration:
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:
// @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:
{
"lint": "turbo run lint --continue"
}
The //#syncpack script will lint the root of the solution's workspace:
{
"syncpack": "syncpack lint"
}
While the lint task may seem redundant for now, it's important to note that as your Turborepo configuration evolves, additional linting tasks will be added as dependencies of the main lint task.
#
Try it 🚀
To test your new Syncpack setup:
- Identify a dependency that is installed in multiple projects within the monorepo.
- 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
- In one of the projects, bump the version of that dependency, and run the script again:
pnpm lint
- Syncpack should report a version mismatch error in the terminal.