{"id":50594939,"url":"https://github.com/uphold/eslint-plugin-import-direction","last_synced_at":"2026-06-05T13:30:35.373Z","repository":{"id":361819189,"uuid":"1255936420","full_name":"uphold/eslint-plugin-import-direction","owner":"uphold","description":"An ESLint plugin to enforce alias imports except when importing siblings or child files.","archived":false,"fork":false,"pushed_at":"2026-06-01T12:00:59.000Z","size":52,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-06-01T12:27:10.885Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":false,"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/uphold.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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}},"created_at":"2026-06-01T10:02:04.000Z","updated_at":"2026-06-01T12:01:40.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/uphold/eslint-plugin-import-direction","commit_stats":null,"previous_names":["uphold/eslint-plugin-import-direction"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/uphold/eslint-plugin-import-direction","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uphold%2Feslint-plugin-import-direction","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uphold%2Feslint-plugin-import-direction/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uphold%2Feslint-plugin-import-direction/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uphold%2Feslint-plugin-import-direction/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/uphold","download_url":"https://codeload.github.com/uphold/eslint-plugin-import-direction/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uphold%2Feslint-plugin-import-direction/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33944671,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-05T02:00:06.157Z","response_time":120,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":[],"created_at":"2026-06-05T13:30:34.525Z","updated_at":"2026-06-05T13:30:35.368Z","avatar_url":"https://github.com/uphold.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# @uphold/eslint-plugin-import-direction\n\nAn ESLint plugin that enforces **import direction**:\n\n- **Ancestor** imports (anything that would traverse `../`) must use a root **alias**.\n- **Sibling and descendant** imports (same directory or below) must stay **relative** (`./`).\n\nThe alias is read straight from your `package.json` [`imports`](https://nodejs.org/api/packages.html#subpath-imports) field (e.g. `\"#/*\": \"./*\"`), so it works with Node subpath imports — no `tsconfig` paths or bundler required.\n\n## Installation\n\n```sh\nnpm install --save-dev @uphold/eslint-plugin-import-direction\n```\n\nThen declare the alias once in your `package.json`:\n\n```json\n{\n  \"imports\": {\n    \"#/*\": \"./*\"\n  }\n}\n```\n\n## Usage\n\nFlat config (`eslint.config.js`) — enable the `recommended` preset:\n\n```js\nimport importDirection from '@uphold/eslint-plugin-import-direction';\n\nexport default [importDirection.configs.recommended];\n```\n\nOr register the plugin and pick rules explicitly:\n\n```js\nimport importDirection from '@uphold/eslint-plugin-import-direction';\n\nexport default [\n  {\n    plugins: { '@uphold/import-direction': importDirection },\n    rules: {\n      '@uphold/import-direction/no-relative-parent': 'error',\n      '@uphold/import-direction/no-aliased-local': 'error'\n    }\n  }\n];\n```\n\nBoth rules are autofixable, so `eslint . --fix` migrates an existing codebase in one pass.\n\n## Configuration\n\nBy default the alias prefix and root directory are auto-detected from the nearest `package.json` `imports` field. To override (or for setups without an `imports` field), pass options to either rule:\n\n```js\n'@uphold/import-direction/no-relative-parent': ['error', { aliasPrefix: '#/', rootDir: import.meta.dirname }]\n```\n\n| Option | Type | Description |\n| --- | --- | --- |\n| `aliasPrefix` | `string` | The import alias prefix, e.g. `\"#/\"`. |\n| `rootDir` | `string` | Absolute path the alias prefix maps to. |\n| `moduleRoots` | `string[]` | Glob patterns marking module-root directories. See below. |\n\n### Module roots\n\nBy default the alias is required for _any_ import that traverses `../`, even between two\nfiles in the same cohesive sub-module. For example, with the file\n`src/repositories/processes/create.ts` importing a sibling utility:\n\n```js\n// ❌ forced by default\nimport { getDb } from '#/src/repositories/utils/db-options.ts';\n```\n\n`moduleRoots` lets you mark directories as **module roots** (glob patterns matched against\nthe directory path relative to the alias root, in posix form). Imports that stay within\nthe same module root are then treated like local imports — kept relative rather than\naliased:\n\n```js\n'@uphold/import-direction/no-relative-parent': ['error', { moduleRoots: ['src/repositories'] }]\n```\n\n```js\n// ✅ allowed, because both files live under the src/repositories module root\nimport { getDb } from '../utils/db-options.ts';\n```\n\nThe direction philosophy still holds across module boundaries: a `../` import that leaves\nits module root must use the alias. With `no-aliased-local`, an alias pointing at a file\nwithin the same module root is rewritten to the relative form.\n\n## Rules\n\n\u003c!-- begin auto-generated rules list --\u003e\n\n💼 Configurations enabled in.\\\n✅ Set in the `recommended` configuration.\\\n🔧 Automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/user-guide/command-line-interface#--fix).\n\n| Name                                                   | Description                                                                                       | 💼 | 🔧 |\n| :----------------------------------------------------- | :------------------------------------------------------------------------------------------------ | :- | :- |\n| [no-aliased-local](docs/rules/no-aliased-local.md)     | Disallow aliased imports for files within the same directory subtree in favor of relative imports | ✅  | 🔧 |\n| [no-relative-parent](docs/rules/no-relative-parent.md) | Disallow relative parent imports in favor of the configured root alias                            | ✅  | 🔧 |\n\n\u003c!-- end auto-generated rules list --\u003e\n\n## License\n\n[MIT](./LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fuphold%2Feslint-plugin-import-direction","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fuphold%2Feslint-plugin-import-direction","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fuphold%2Feslint-plugin-import-direction/lists"}