Overview
Syncpack is a tool for managing consistent dependency versions across JavaScript/TypeScript monorepos. This skill covers configuration best practices.
Configuration File Locations
Syncpack searches for configuration in these locations (in order):
syncpack.config.js/.cjs/.mjs/.tssyncpack.config.json/.yaml/.yml.syncpackrc/.syncpackrc.json/.syncpackrc.yaml/.syncpackrc.yml
Basic Configuration
js
// syncpack.config.js
export default {
// Glob patterns to find package.json files
source: [
'package.json',
'packages/*/package.json',
'apps/*/package.json',
],
};
Workspace Detection
Syncpack automatically detects workspaces:
- npm/Yarn: Reads
workspacesfrom./package.json - pnpm: Reads
packagesfrom./pnpm-workspace.yaml - Lerna: Reads
packagesfrom./lerna.json
Override with explicit source patterns when needed.
Dependency Types
Control which dependency types to check:
js
export default {
dependencyTypes: [
'dev', // devDependencies
'local', // workspace: protocol dependencies
'overrides', // npm overrides / yarn resolutions
'peer', // peerDependencies
'pnpmOverrides', // pnpm overrides
'prod', // dependencies
'resolutions', // yarn resolutions
],
};
Semver Groups
Define rules for semver range consistency:
js
export default {
semverGroups: [
{
// Require exact versions for React
dependencies: ['react', 'react-dom'],
range: '', // exact version
},
{
// Allow caret ranges for dev tools
dependencyTypes: ['dev'],
range: '^',
},
],
};
Range Options
| Range | Example | Meaning |
|---|---|---|
'' | 1.2.3 | Exact version |
^ | ^1.2.3 | Compatible with |
~ | ~1.2.3 | Approximately equivalent |
>= | >=1.2.3 | Greater than or equal |
* | * | Any version |
Version Groups
Partition dependencies into groups with separate version policies:
js
export default {
versionGroups: [
{
// Pin specific dependencies
dependencies: ['typescript'],
pinVersion: '5.3.3',
},
{
// Ban certain packages
dependencies: ['moment'],
isBanned: true,
},
{
// Use workspace version as source of truth
dependencies: ['@myorg/*'],
preferVersion: 'highestSemver',
},
],
};
Formatting Options
Control package.json formatting:
js
export default {
formatBugs: true,
formatRepository: true,
sortAz: [
'contributors',
'dependencies',
'devDependencies',
'keywords',
],
sortFirst: [
'name',
'version',
'description',
'main',
],
};
Common Patterns
Single Version Policy
Enforce one version per dependency across all packages:
js
export default {
versionGroups: [
{
label: 'Use highest version everywhere',
preferVersion: 'highestSemver',
},
],
};
Allow Development Exceptions
js
export default {
versionGroups: [
{
label: 'Ignore dev dependencies',
dependencyTypes: ['dev'],
isIgnored: true,
},
{
label: 'Consistent versions for production',
dependencyTypes: ['prod', 'peer'],
preferVersion: 'highestSemver',
},
],
};
Scoped Package Source of Truth
js
export default {
versionGroups: [
{
label: 'Internal packages use local version',
dependencies: ['@myorg/**'],
dependencyTypes: ['local'],
preferVersion: 'local',
},
],
};
Best Practices
- Start with defaults - Syncpack works well without configuration
- Add rules incrementally - Only add rules as you encounter issues
- Document exceptions - Use
labelfield to explain why rules exist - Commit config file - Keep version policy in version control
- Run in CI - Use
syncpack list-mismatches --fail-fastin CI pipelines