A Swift package groups modules developed together. Each target is compiled as a module or test suite, and library products expose selected targets to clients. A local package can remain in the application repository while giving Xcode and the compiler a real dependency boundary.
Modules enforce visibility and dependency direction. Keep APIs small: internal remains the default inside a module, package access can share implementation across targets in the same package, and public exposes declarations to importing modules. A public API creates compatibility and maintenance obligations even when every module lives in one repository.
Design the graph so feature modules depend on stable lower-level capabilities or feature APIs rather than one another's implementation. Avoid cycles and umbrella modules that import everything. Measure incremental build behavior, test startup, preview ergonomics, resource handling, and developer navigation before and after modularization; more modules are not automatically faster or cleaner.