{"id":15414862,"url":"https://github.com/quiibz/sherif","last_synced_at":"2026-04-01T23:18:34.909Z","repository":{"id":195335843,"uuid":"692763838","full_name":"QuiiBz/sherif","owner":"QuiiBz","description":"Opinionated, zero-config linter for TypeScript \u0026 JavaScript monorepos","archived":false,"fork":false,"pushed_at":"2026-03-30T15:54:32.000Z","size":1581,"stargazers_count":1151,"open_issues_count":12,"forks_count":18,"subscribers_count":8,"default_branch":"main","last_synced_at":"2026-03-30T17:39:45.148Z","etag":null,"topics":["cli","javascript","linter","monorepo","typescript"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/QuiiBz.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":["QuiiBz"]}},"created_at":"2023-09-17T14:11:52.000Z","updated_at":"2026-03-30T15:54:32.000Z","dependencies_parsed_at":null,"dependency_job_id":"c4dd2d45-a275-4210-88cc-e55dcf0a5f9a","html_url":"https://github.com/QuiiBz/sherif","commit_stats":{"total_commits":95,"total_committers":6,"mean_commits":"15.833333333333334","dds":0.08421052631578951,"last_synced_commit":"19f1e345c04830ba5a93d9b6de3172b54ee2391a"},"previous_names":["quiibz/sherif"],"tags_count":39,"template":false,"template_full_name":null,"purl":"pkg:github/QuiiBz/sherif","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/QuiiBz%2Fsherif","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/QuiiBz%2Fsherif/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/QuiiBz%2Fsherif/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/QuiiBz%2Fsherif/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/QuiiBz","download_url":"https://codeload.github.com/QuiiBz/sherif/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/QuiiBz%2Fsherif/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31292871,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-01T21:15:39.731Z","status":"ssl_error","status_checked_at":"2026-04-01T21:15:34.046Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cli","javascript","linter","monorepo","typescript"],"created_at":"2024-10-01T17:05:05.190Z","updated_at":"2026-04-01T23:18:34.900Z","avatar_url":"https://github.com/QuiiBz.png","language":"JavaScript","funding_links":["https://github.com/sponsors/QuiiBz"],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cpicture\u003e\n    \u003cimg alt=\"\" height=\"200px\" src=\"https://github.com/QuiiBz/sherif/blob/main/assets/logo.png\" /\u003e\n  \u003c/picture\u003e\n  \u003cbr /\u003e\n  \u003cb\u003eSherif\u003c/b\u003e: Opinionated, zero-config linter for TypeScript \u0026 JavaScript monorepos\n\u003c/p\u003e\n\n---\n\n![Cover](https://github.com/QuiiBz/sherif/blob/main/assets/cover.png)\n\n## About\n\nSherif is an opinionated, zero-config linter for TypeScript \u0026 JavaScript monorepos. It runs fast in any monorepo and enforces rules to provide a better, standardized DX.\n\n## Features\n\n- ✨ **PNPM, Bun, NPM, Yarn...**: sherif works with all package managers\n- 🔎 **Zero-config**: it just works and prevents regressions\n- ⚡ **Fast**: doesn't need `node_modules` installed, written in 🦀 Rust\n\n## Installation\n\nRun `sherif` in the root of your monorepo to list the found issues. By default, any error will cause Sherif to [exit with a code 1](#exit-code):\n\n```bash\n# PNPM\npnpm dlx sherif@latest\n# Bun\nbunx sherif@latest\n# NPM\nnpx sherif@latest\n# Yarn\nyarn dlx sherif@latest\n```\n\nWe recommend running Sherif in your CI once [all errors are fixed](#autofix). Run it by **specifying a version instead of latest**. This is useful to prevent regressions (e.g. when adding a library to a package but forgetting to update the version in other packages of the monorepo).\n\nWhen using the GitHub Action, it will search for a `sherif` script in the root `package.json` and use the same arguments automatically to avoid repeating them twice. You can override this behaviour with the `args` parameter.\n\n\u003cdetails\u003e\n\n\u003csummary\u003eGitHub Actions example\u003c/summary\u003e\n\n```yaml\n# Using the `QuiiBz/sherif` action\nname: Sherif\non:\n  pull_request:\njobs:\n  check:\n    name: Run Sherif\n    runs-on: ubuntu-22.04\n    steps:\n      - uses: actions/checkout@v4\n      - uses: QuiiBz/sherif@v1\n        # Optionally, you can specify a version and arguments to run Sherif with:\n        # with:\n          # version: 'v1.11.1'\n          # args: '--ignore-rule root-package-manager-field'\n\n# Using `npx` to run Sherif\nname: Sherif\non:\n  pull_request:\njobs:\n  check:\n    name: Run Sherif\n    runs-on: ubuntu-22.04\n    steps:\n      - uses: actions/checkout@v4\n      - uses: actions/setup-node@v3\n        with:\n          node-version: 20\n      - run: npx sherif@1.11.1\n```\n\n\u003c/details\u003e\n\n## Autofix\n\nMost issues can be automatically fixed by using the `--fix` (or `-f`) flag. Sherif will automatically run your package manager's `install` command (see [No-install mode](#no-install-mode) to disable this behavior) to update the lockfile. Note that autofix is disabled in CI environments (when `$CI` is set):\n\n```bash\nsherif --fix\n```\n\n### Autofixing the [`multiple-dependency-versions`](#multiple-dependency-versions-) rule\n\nBy default, running `--fix` with the `multiple-dependency-versions` rule will ask you to select which version to use for each dependency with multiple versions across the monorepo. If that doesn't work for you (e.g., you are running Sherif in a non-interactive environment), you can use the `--select` (of `-s`) flag to automatically select the highest or lowest version of every dependency:\n\n```bash\n# Autofix and select the highest version for each dependency matching the `multiple-dependency-versions` rule\nsherif --fix --select highest\n```\n\n### No-install mode\n\nIf you don't want Sherif to run your packager manager's `install` command after running autofix, you can use the `--no-install` flag:\n\n```bash\n# Autofix without running the package manager's install command\nsherif --fix --no-install\n```\n\n## Exit code\n\nBy default, Sherif will exit with code `1` if any error issues are found. If you only have warning issues or no issues at all, Sherif will exit with code `0`. You can change this behavior to always exit with code `1` if any issues are found, including warnings, by using the `--fail-on-warnings` option.\n\n## Rules\n\nYou can ignore a specific rule by using `--ignore-rule \u003cname\u003e` (or `-r \u003cname\u003e`):\n\n```bash\n# Ignore both rules\nsherif -r packages-without-package-json -r root-package-manager-field\n```\n\nYou can ignore all issues in a package by using `--ignore-package \u003cpathOrName\u003e` (or `-p \u003cpathOrName\u003e`):\n\n```bash\n# Ignore all issues in the `@repo/tools` package\nsherif -p @repo/tools\n# Ignore all issues for packages inside `./integrations/*`\nsherif -p \"./integrations/*\"\n```\n\n#### `empty-dependencies` ❌\n\n`package.json` files should not have empty dependencies fields.\n\n#### `multiple-dependency-versions` ❌\n\nA given dependency should use the same version across the monorepo.\n\nYou can ignore this rule for a specific dependency and version or all versions of a dependency if it's expected in your monorepo by using `--ignore-dependency \u003cname@version\u003e` / `--ignore-dependency \u003cname\u003e` (or `-i \u003cname@version\u003e` / `-i \u003cname\u003e`):\n\n```bash\n# Ignore only the specific dependency version mismatch\nsherif -i react@17.0.2 -i next@13.2.4\n\n# Ignore all versions mismatch of dependencies that start with @next/\nsherif -i @next/*\n\n# Completely ignore all versions mismatch of these dependencies\nsherif -i react -i next\n```\n\n#### `unsync-similar-dependencies` ❌\n\nSimilar dependencies in a given `package.json` should use the same version. For example, if you use both `react` and `react-dom` dependencies in the same `package.json`, this rule will enforce that they use the same version.\n\n\u003cdetails\u003e\n\n\u003csummary\u003eList of detected similar dependencies\u003c/summary\u003e\n\n- `react`, `react-dom`\n- `eslint-config-next`, `@next/eslint-plugin-next`, `@next/font` `@next/bundle-analyzer`, `@next/third-parties`, `@next/mdx`, `next`\n- `@trpc/client`, `@trpc/server`, `@trpc/next`, `@trpc/react-query`\n- `eslint-config-turbo`, `eslint-plugin-turbo`, `@turbo/gen`, `turbo-ignore`, `turbo`\n- `sb`, `storybook`, `@storybook/codemod`, `@storybook/cli`, `@storybook/channels`, `@storybook/addon-actions`, `@storybook/addon-links`, `@storybook/react`, `@storybook/react-native`, `@storybook/components`, `@storybook/addon-backgrounds`, `@storybook/addon-viewport`, `@storybook/angular`, `@storybook/addon-a11y`, `@storybook/addon-jest`, `@storybook/client-logger`, `@storybook/node-logger`, `@storybook/core`, `@storybook/addon-storysource`, `@storybook/html`, `@storybook/core-events`, `@storybook/svelte`, `@storybook/ember`, `@storybook/addon-ondevice-backgrounds`, `@storybook/addon-ondevice-notes`, `@storybook/preact`, `@storybook/theming`, `@storybook/router`, `@storybook/addon-docs`, `@storybook/addon-ondevice-actions`, `@storybook/source-loader`, `@storybook/preset-create-react-app`, `@storybook/web-components`, `@storybook/addon-essentials`, `@storybook/server`, `@storybook/addon-toolbars`, `@storybook/addon-controls`, `@storybook/core-common`, `@storybook/builder-webpack5`, `@storybook/core-server`, `@storybook/csf-tools`, `@storybook/addon-measure`, `@storybook/addon-outline`, `@storybook/addon-ondevice-controls`, `@storybook/instrumenter`, `@storybook/addon-interactions`, `@storybook/docs-tools`, `@storybook/builder-vite`, `@storybook/telemetry`, `@storybook/core-webpack`, `@storybook/preset-html-webpack`, `@storybook/preset-preact-webpack`, `@storybook/preset-svelte-webpack`, `@storybook/preset-react-webpack`, `@storybook/html-webpack5`, `@storybook/preact-webpack5`, `@storybook/svelte-webpack5`, `@storybook/web-components-webpack5`, `@storybook/preset-server-webpack`, `@storybook/react-webpack5`, `@storybook/server-webpack5`, `@storybook/addon-highlight`, `@storybook/blocks`, `@storybook/builder-manager`, `@storybook/react-vite`, `@storybook/svelte-vite`, `@storybook/web-components-vite`, `@storybook/nextjs`, `@storybook/types`, `@storybook/manager`, `@storybook/csf-plugin`, `@storybook/preview`, `@storybook/manager-api`, `@storybook/preview-api`, `@storybook/html-vite`, `@storybook/sveltekit`, `@storybook/preact-vite`, `@storybook/addon-mdx-gfm`, `@storybook/react-dom-shim`, `create-storybook`, `@storybook/addon-onboarding`, `@storybook/react-native-theming`, `@storybook/addon-themes`, `@storybook/test`, `@storybook/react-native-ui`, `@storybook/experimental-nextjs-vite`, `@storybook/experimental-addon-test`, `@storybook/react-native-web-vite`\n- `prisma`, `@prisma/client`, `@prisma/instrumentation`\n- `typescript-eslint`, `@typescript-eslint/eslint-plugin`, `@typescript-eslint/parser`\n- `@stylistic/eslint-plugin-js`, `@stylistic/eslint-plugin-ts`, `@stylistic/eslint-plugin-migrate`, `@stylistic/eslint-plugin`, `@stylistic/eslint-plugin-jsx`, `@stylistic/eslint-plugin-plus`\n- `playwright`, `@playwright/test`\n\n\u003c/details\u003e\n\n#### `non-existant-packages` ⚠️\n\nAll paths defined in the workspace (the root `package.json`' `workspaces` field or `pnpm-workspace.yaml`) should match at least one package.\n\n#### `packages-without-package-json` ⚠️\n\nAll packages matching the workspace (the root `package.json`' `workspaces` field or `pnpm-workspace.yaml`) should have a `package.json` file.\n\n#### `root-package-dependencies` ⚠️\n\nThe root `package.json` is private, so making a distinction between `dependencies` and `devDependencies` is useless - only use `devDependencies`.\n\n#### `root-package-manager-field` ❌\n\nThe root `package.json` should specify the package manager and version to use. Useful for tools like corepack.\n\n#### `root-package-private-field` ❌\n\nThe root `package.json` should be private to prevent accidentaly publishing it to a registry.\n\n#### `types-in-dependencies` ❌\n\nPrivate packages shouldn't have `@types/*` in `dependencies`, since they don't need it at runtime. Move them to `devDependencies`.\n\n#### `unordered-dependencies` ❌\n\nDependencies should be ordered alphabetically to prevent complex diffs when installing a new dependency via a package manager.\n\n## Configuration\n\nWhen using many CLI arguments, it might be easier to move to the configuration format. In your root `package.json`, add a `sherif` field containing the same options as the CLI, but in camelCase. Default values are shown below:\n\n```jsonc\n{\n  \"sherif\": {\n    \"fix\": false,\n    \"select\": \"highest\", // \"highest\" | \"lowest\"\n    \"noInstall\": false,\n    \"failOnWarnings\": false,\n    \"ignoreDependency\": [], // string[]\n    \"ignorePackage\": [], // string[]\n    \"ignoreRule\": [] // string[]\n  }\n}\n```\n\nWhen using both the configuration in the root `package.json` and CLI arguments, the CLI arguments will take precedence.\n\n## Credits\n\n- [dedubcheck](https://github.com/innovatrics/dedubcheck) that given me the idea for Sherif\n- [Manypkg](https://github.com/Thinkmill/manypkg) for some of their rules\n- [This article](https://blog.orhun.dev/packaging-rust-for-npm/) for the Rust releases on NPM\n\n## Sponsors\n\n![Sponsors](https://github.com/QuiiBz/dotfiles/blob/main/sponsors.png?raw=true)\n\n## License\n\n[MIT](./LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fquiibz%2Fsherif","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fquiibz%2Fsherif","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fquiibz%2Fsherif/lists"}