intermediate
Module boundaries
Shape modules around cohesive responsibilities, stable exports, and clear ownership so callers do not depend on internals.
Modules package cohesive capabilities behind a public API—index exports, explicit entry points, and hidden internals. Callers depend on stable exports; refactor internals freely when the contract holds. Feature folders and package boundaries reduce accidental imports across domains.
Circular dependencies signal boundary smells—break cycles with interfaces or moving shared kernel up.
On interviews: propose module splits for a tangled utils folder imported everywhere.
Common pitfalls: barrel files re-exporting everything, reaching into `/internal` paths, and god `common` package.
The trade-off is strict boundaries versus convenience imports during rapid prototyping.
Checklist:
- Define public exports explicitly.
- Hide implementation files.
- Break circular imports deliberately.