|  | 
|  | 1 | +# public-api | 
|  | 2 | + | 
|  | 3 | +Enforce consistent public API structure in FSD slices. | 
|  | 4 | + | 
|  | 5 | +This rule ensures that each slice in Feature-Sliced Design layers has a proper public API file. It checks for the existence of the specified filename (by default `index.ts`) in each slice directory and reports violations when slices are missing their public API or have incorrect API files. | 
|  | 6 | + | 
|  | 7 | +## Rule Details | 
|  | 8 | + | 
|  | 9 | +This rule enforces FSD public API conventions by: | 
|  | 10 | + | 
|  | 11 | +- Checking that each slice has the expected public API file (e.g., `index.ts`) | 
|  | 12 | +- Reporting slices that are missing their public API files | 
|  | 13 | +- Reporting invalid public API files (e.g., `index.js` when expecting `index.ts`) | 
|  | 14 | +- Supporting custom filenames for public API files | 
|  | 15 | +- Allowing certain slices to be ignored from validation | 
|  | 16 | +- Running filesystem checks only once per lint session for performance | 
|  | 17 | + | 
|  | 18 | +**Default Behavior**: With no configuration, the rule checks for `index.ts` files in all standard FSD layers (`app`, `pages`, `widgets`, `features`, `entities`, `shared`). | 
|  | 19 | + | 
|  | 20 | +## Options | 
|  | 21 | + | 
|  | 22 | +```json | 
|  | 23 | +{ | 
|  | 24 | +  "vue-fsd/public-api": [ | 
|  | 25 | +    "error", | 
|  | 26 | +    { | 
|  | 27 | +      "src": "src", | 
|  | 28 | +      "layers": ["features", "entities", "shared"], | 
|  | 29 | +      "filename": "index.ts", | 
|  | 30 | +      "ignore": ["temp", "legacy"] | 
|  | 31 | +    } | 
|  | 32 | +  ] | 
|  | 33 | +} | 
|  | 34 | +``` | 
|  | 35 | + | 
|  | 36 | +### `src` (string) | 
|  | 37 | + | 
|  | 38 | +The source directory path to check for FSD structure. Defaults to `"src"`. | 
|  | 39 | + | 
|  | 40 | +### `layers` (array of strings) | 
|  | 41 | + | 
|  | 42 | +List of FSD layers to check for public API files. Only slices within these layers will be validated. | 
|  | 43 | + | 
|  | 44 | +Default: `["app", "pages", "widgets", "features", "entities", "shared"]` | 
|  | 45 | + | 
|  | 46 | +### `filename` (string) | 
|  | 47 | + | 
|  | 48 | +The expected filename for public API files in each slice. | 
|  | 49 | + | 
|  | 50 | +Default: `"index.ts"` | 
|  | 51 | + | 
|  | 52 | +### `ignore` (array of strings) | 
|  | 53 | + | 
|  | 54 | +List of slice names to ignore when checking for public API files. Useful for temporary slices or legacy code that doesn't follow the convention. | 
|  | 55 | + | 
|  | 56 | +Default: `[]` (no ignores) | 
|  | 57 | + | 
|  | 58 | +## Examples | 
|  | 59 | + | 
|  | 60 | +### ✅ Correct | 
|  | 61 | + | 
|  | 62 | +#### Default behavior (no configuration required) | 
|  | 63 | + | 
|  | 64 | +```json | 
|  | 65 | +{ | 
|  | 66 | +  "vue-fsd/public-api": "error" | 
|  | 67 | +} | 
|  | 68 | +``` | 
|  | 69 | + | 
|  | 70 | +```text | 
|  | 71 | +src/ | 
|  | 72 | +├── features/ | 
|  | 73 | +│   ├── auth/ | 
|  | 74 | +│   │   ├── index.ts     ✅ has public API | 
|  | 75 | +│   │   └── model.ts | 
|  | 76 | +│   └── profile/ | 
|  | 77 | +│       ├── index.ts     ✅ has public API | 
|  | 78 | +│       └── api.ts | 
|  | 79 | +└── entities/ | 
|  | 80 | +    └── user/ | 
|  | 81 | +        ├── index.ts     ✅ has public API | 
|  | 82 | +        └── model.ts | 
|  | 83 | +``` | 
|  | 84 | + | 
|  | 85 | +#### Custom filename | 
|  | 86 | + | 
|  | 87 | +```json | 
|  | 88 | +{ | 
|  | 89 | +  "vue-fsd/public-api": [ | 
|  | 90 | +    "error", | 
|  | 91 | +    { | 
|  | 92 | +      "filename": "public-api.js" | 
|  | 93 | +    } | 
|  | 94 | +  ] | 
|  | 95 | +} | 
|  | 96 | +``` | 
|  | 97 | + | 
|  | 98 | +```text | 
|  | 99 | +src/ | 
|  | 100 | +└── features/ | 
|  | 101 | +    └── auth/ | 
|  | 102 | +        ├── public-api.js  ✅ custom public API filename | 
|  | 103 | +        └── model.js | 
|  | 104 | +``` | 
|  | 105 | + | 
|  | 106 | +### ❌ Incorrect | 
|  | 107 | + | 
|  | 108 | +#### Missing public API file | 
|  | 109 | + | 
|  | 110 | +```text | 
|  | 111 | +src/ | 
|  | 112 | +└── features/ | 
|  | 113 | +    └── auth/ | 
|  | 114 | +        ├── model.ts      ❌ missing index.ts | 
|  | 115 | +        └── ui.tsx | 
|  | 116 | +``` | 
|  | 117 | + | 
|  | 118 | +```text | 
|  | 119 | +Slice "auth" in layer "features" is missing a public API file (index.ts). | 
|  | 120 | +``` | 
|  | 121 | + | 
|  | 122 | +#### Invalid public API file | 
|  | 123 | + | 
|  | 124 | +```text | 
|  | 125 | +src/ | 
|  | 126 | +└── features/ | 
|  | 127 | +    └── auth/ | 
|  | 128 | +        ├── index.ts      ✅ correct public API | 
|  | 129 | +        ├── index.js      ❌ invalid additional index file | 
|  | 130 | +        └── model.ts | 
|  | 131 | +``` | 
|  | 132 | + | 
|  | 133 | +```text | 
|  | 134 | +Slice "auth" in layer "features" has an invalid public API file "index.js". Expected index.ts. | 
|  | 135 | +``` | 
|  | 136 | + | 
|  | 137 | +## Typical FSD Configuration | 
|  | 138 | + | 
|  | 139 | +For a standard Feature-Sliced Design project: | 
|  | 140 | + | 
|  | 141 | +```json | 
|  | 142 | +{ | 
|  | 143 | +  "vue-fsd/public-api": [ | 
|  | 144 | +    "error", | 
|  | 145 | +    { | 
|  | 146 | +      "src": "src", | 
|  | 147 | +      "layers": ["features", "entities", "shared"], | 
|  | 148 | +      "filename": "index.ts", | 
|  | 149 | +      "ignore": ["__tests__", "temp"] | 
|  | 150 | +    } | 
|  | 151 | +  ] | 
|  | 152 | +} | 
|  | 153 | +``` | 
|  | 154 | + | 
|  | 155 | +This configuration: | 
|  | 156 | + | 
|  | 157 | +- Checks `features`, `entities`, and `shared` layers for public API files | 
|  | 158 | +- Expects `index.ts` as the public API filename | 
|  | 159 | +- Ignores test directories and temporary slices | 
|  | 160 | + | 
|  | 161 | +## When Not To Use | 
|  | 162 | + | 
|  | 163 | +- If your project doesn't follow Feature-Sliced Design architecture | 
|  | 164 | +- If you don't want to enforce public API conventions | 
|  | 165 | +- If your slices use different public API patterns that aren't file-based | 
|  | 166 | + | 
|  | 167 | +## Related Rules | 
|  | 168 | + | 
|  | 169 | +- [`fsd-layers`](./fsd-layers.md) - Enforces overall FSD layer structure | 
|  | 170 | +- [`no-processes-layer`](./no-processes-layer.md) - Prevents usage of deprecated processes layer | 
|  | 171 | + | 
|  | 172 | +## Performance Notes | 
|  | 173 | + | 
|  | 174 | +This rule performs filesystem operations and is designed to run only once per ESLint session using the `runOnce` utility. This prevents redundant directory scans when linting multiple files in the same project. | 
0 commit comments