monorepo-imports
npx skills add https://github.com/vertz-dev/claude-code --skill monorepo-imports
Agent 安装分布
Skill 文档
Monorepo Imports
In a monorepo, every package has a public API defined by its exports field in package.json. Cross-package imports MUST go through that API â never reach into another package’s source files.
Rules
Always import from the package name
// CORRECT â uses the public API
import { createModule } from '@scope/core';
import { Trie } from '@scope/core/internals';
// WRONG â reaches into source files
import { createModule } from '@scope/core/src/module';
import { Trie } from '@scope/core/src/router/trie';
The exports field is the contract
A package’s exports in package.json defines what other packages can import. If something isn’t exported, it’s private â don’t import it directly from source.
{
"exports": {
".": { "import": "./dist/index.js" },
"./internals": { "import": "./dist/internals.js" }
}
}
This means consumers can import from @scope/core and @scope/core/internals â nothing else.
Use subpath exports for internal APIs
When an official package (e.g., a testing library) needs internal APIs that shouldn’t be public:
- Create a subpath like
./internalswith its own entry point - Export it in
package.json - Import from
@scope/core/internals, not from source paths
No aliases that bypass the package boundary
Do NOT add vitest aliases, tsconfig paths, or bundler aliases that redirect @scope/pkg to source files. Let workspace resolution use the built dist/ output. This ensures:
- Tests run against the same code consumers get
- Missing exports are caught immediately
- Package boundaries are enforced, not just documented
When something is missing from the public API
If you need something that isn’t exported:
- Check if it belongs in the public API â if yes, export it from the package’s index
- Check if it belongs in an internal subpath â if yes, export it from
./internals - If neither, reconsider the dependency â you may need to restructure