What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
Enforce TypeScript architecture boundaries by turning imports into a directed graph, assigning every file to a project or layer, and rejecting edges that violate a written dependency policy. In an Nx workspace, @nx/enforce-module-boundaries provides an integrated rule. For a non-standard repository or custom semantics, build the graph with the TypeScript Compiler API and fail CI on forbidden edges.
Think of architecture as an import graph
Represent each source project, package, or architectural layer as a node. A resolved import from one node to another is a directed edge. The boundary policy is a set of allowed edges: for example, a billing feature may depend on billing-domain code and shared utilities, but not on identity UI code. An edge that points the wrong way is an architectural violation even when TypeScript can compile it.
The analyzer must do more than search for relative-path strings. It needs to resolve aliases and workspace packages using the same module-resolution settings as the build, attribute the importing file to its owning project, distinguish internal targets from external packages, and report the exact source and target involved. Static imports and re-exports are usually the minimum graph; decide separately whether type-only imports, dynamic imports, generated files, and test files are governed.
Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Clear out junk files and repair common Windows errors3Fix the driver behind crashes, sound loss and screen glitchesWrite the boundary policy before choosing a tool
Use a small, stable vocabulary
Give projects a few tags that describe ownership and role. A practical starting set is scope:billing, scope:identity, type:feature, type:ui, and type:util. Keep library types low in number and document what each means. A taxonomy that developers cannot apply consistently will produce noisy exceptions instead of useful enforcement.
#1 Best Overall
- Read Before You Buy — No Video Output: These adapters support charging and USB 2.0 data transfer, but cannot transmit video signals. Except for standard USB webcams (which use USB data only), they are not compatible with HDMI/DisplayPort cables, video-capable USB-C hubs, or docking stations with video output.
- Convert USB-A Ports to USB-C: Designed to connect USB-C earphones, cables, flash drives, card readers, and other USB-C accessories to standard USB-A ports. Plug-and-play with no drivers or software required.
- Aluminum Alloy Housing: Built with a sturdy aluminum alloy shell that aids in heat dissipation and protects against daily wear and scratches. Designed to maintain a stable and secure connection.
- Compact & Travel-Friendly: The ultra-compact design allows the adapter to stay plugged into your device without blocking adjacent ports or adding bulk, reducing wear and tear on your original USB ports.
- 12-Month Warranty: Backed by a 12-month manufacturer warranty for peace of mind. Designed to meet strict quality control standards for reliable everyday performance.
Turn the vocabulary into an allowed-dependency matrix
For every source category, state which target categories and external packages are permitted. The matrix is the architecture contract that your lint rule or analyzer evaluates.
| Source | Allowed internal targets | Typical external policy | Example forbidden edge |
|---|---|---|---|
| Feature | Its own scope, shared domain, approved utilities | Only packages explicitly listed for the feature | scope:billing feature importing scope:identity UI |
| UI library | UI primitives and shared types | UI framework and approved styling packages | UI importing a database adapter |
| Domain library | Shared domain contracts and pure utilities | No infrastructure packages | Domain importing an HTTP client implementation |
| Utility library | Lower-level utilities only | Small, centrally approved set | Utility importing a feature package |
Also decide whether a source may import another project in the same scope, whether buildable libraries have stricter rules, and whether tests follow production boundaries. Write these decisions down before adding tags or code; otherwise the tool merely codifies accidental structure.
Choose an enforcement approach
Compare tools by the edges they can see, how closely they match your compiler’s resolution, where rules live, and how diagnostics enter CI. No source publishes a comparable speed benchmark, so measure runtime on your own repository rather than calling one option fastest.
The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →| Approach | Best fit | Coverage and configuration | Trade-offs |
|---|---|---|---|
Nx @nx/enforce-module-boundaries |
Nx-organized JavaScript or TypeScript workspaces | Checks project imports and package dependencies; tag constraints can allow or forbid target tags and external packages. | Convenient lint integration, but project tags and workspace metadata must be correct. Oxlint support is documented as experimental. |
| Custom TypeScript Compiler API analyzer | Specialized policies, custom diagnostics, or repositories without a suitable integrated rule | You decide which AST forms to collect, how to resolve them, and how projects map to nodes. | Maximum flexibility; your team owns completeness, configuration, maintenance, and CI integration. |
| Nx Conformance | Nx Enterprise workspaces that need language-agnostic project checks | The Conformance overview describes project-boundary checks across every project dependency, not only TypeScript imports or package.json dependencies. |
Broader dependency scope, but it requires Nx Enterprise and a workspace model that fits the rule. Confirm licensing and the exact dependency model. |
| dependency-cruiser | Standalone dependency-graph rules and cycle checks | Configurable rules can express boundaries and circular-dependency checks. | Coverage depends on configured rules and analyzer behavior; verify aliases, re-exports, and package resolution against your repository. |
Configure Nx module-boundary enforcement
If your repository is already organized as Nx projects, start with the lint rule and run it in the normal lint and CI path. The rule applies constraints to projects according to their source tags. Constraints that match multiple source tags are combined with AND logic, so adding a tag can make a project subject to additional restrictions.
1. Tag projects consistently
Assign scope and type tags in each project definition. For example, a billing feature might receive scope:billing and type:feature, while a shared UI library receives scope:shared and type:ui. Check that every project has the tags required by at least one constraint; an untagged project can otherwise escape the policy.
Rank #2
- 5-in-1 USB-C Hub: Experience comprehensive connectivity featuring a Power Delivery input, two USB-A 2.0 ports, a USB-A 3.0 port, and an HDMI port. (Note: The USB-C power delivery input port is only for connecting an external wall charger to power your laptop and cannot power peripheral devices.)
- 90W Pass-Through Charging: Achieve optimal charging with 90W pass-through power to your laptop, supported by a total input of 100W, with the hub reserving 10W for operational efficiency. (Note: Wall charger not included.)
- Quick Data Transfers: Accelerate your productivity with rapid data transfers using a high-speed 5Gbps USB 3.0 port and two 480Mbps USB 2.0 ports.
- 4K HDMI Display: Enhance your visual experience with a hub capable of delivering 4K resolution at 30Hz in both mirror and extend modes. Please note that this hub is compatible with MacBook (macOS 12 and newer), Windows 10 and 11, ChromeOS, and laptops equipped with DP Alt Mode and Power Delivery. Note: This device is not compatible with Linux.
- What You Get: Anker USB-C Hub (5-in-1, 4K HDMI), welcome guide, 18-month warranty, and our friendly customer service.
2. Express the dependency matrix
Configure depConstraints in the options for @nx/enforce-module-boundaries. A minimal shape is:
{"depConstraints":[{"sourceTag":"scope:billing","onlyDependOnLibsWithTags":["scope:billing","scope:shared"]},{"sourceTag":"type:ui","notDependOnLibsWithTags":["type:feature","type:util"]}]}
The rule reference documents additional fields such as allowedExternalImports and bannedExternalImports. Use those lists to prevent a layer from quietly adding infrastructure or platform packages. Other switches cover nested external imports, buildable-library dependencies, circular dependencies, and dynamic-dependency exceptions; review the current rule reference when pinning configuration to a specific version (the page was updated September 9, 2026).
3. Run it where developers already see failures
Keep the rule in the workspace’s ESLint configuration and invoke the same lint target locally and in CI. A violation should identify the importing project, imported project or package, and the constraint that failed. Treat a newly introduced violation as a failed change rather than allowing a warning that developers learn to ignore.
4. Keep exceptions narrow
The rule exposes an allow list and options for ignored circular dependencies and dynamic-dependency exceptions. Add an exception only with a comment explaining why the edge is safe, scope it to the smallest path possible, and create a cleanup issue. Review exception entries periodically; otherwise they become an undocumented second architecture.
Build a custom analyzer with the TypeScript Compiler API
Use a custom analyzer when the policy depends on semantics that a lint rule cannot express, when diagnostics must feed another system, or when the repository is not an Nx workspace. The Compiler API documentation describes SourceFile objects as ASTs and a Program containing the configured files plus files reached through references and imports. Those structures are a foundation, not a finished architecture checker.
Rank #3
- Sleek 7-in-1 USB-C Hub: Features an HDMI port, two USB-A 3.0 ports, and a USB-C data port, each providing 5Gbps transfer speeds. It also includes a USB-C PD input port for charging up to 100W and dual SD and TF card slots, all in a compact design.
- Flawless 4K@60Hz Video with HDMI: Delivers exceptional clarity and smoothness with its 4K@60Hz HDMI port, making it ideal for high-definition presentations and entertainment. (Note: Only the HDMI port supports video projection; the USB-C port is for data transfer only.)
- Double Up on Efficiency: The two USB-A 3.0 ports and a USB-C port support a fast 5Gbps data rate, significantly boosting your transfer speeds and improving productivity.
- Fast and Reliable 85W Charging: Offers high-capacity, speedy charging for laptops up to 85W, so you spend less time tethered to an outlet and more time being productive.
- What You Get: Anker USB-C Hub (7-in-1), welcome guide, 18-month warranty, and our friendly customer service.
1. Load the repository’s real compiler configuration
Read the project or solution configuration that the build uses, including baseUrl, paths, module kind, module resolution, project references, and included file sets. Do not invent a second alias map in the analyzer. If the analyzer resolves an alias differently from the compiler, developers will see false violations or miss real ones.
Free tools Windows power users keep installed
One-click scans. No signup required.
2. Create a program and enumerate source files
Construct a TypeScript Program from the parsed configuration, then iterate its SourceFile objects. Exclude declaration output, generated directories, vendored code, and test fixtures only when that matches your policy. Record the owning project for every included file before examining imports.
3. Collect the import forms your policy governs
Visit AST nodes for static import declarations, export declarations that re-export another module, and import-equals declarations if the codebase uses them. Decide explicitly whether import type edges count; many teams include them because types still couple projects, while others permit a narrower contract-only relationship. Dynamic import() expressions need a deliberate rule: include statically analyzable string literals, report non-literal expressions separately, or allow them only through a documented exception.
4. Resolve every module specifier
Resolve each specifier with the compiler’s module-resolution settings and normalize the result to a canonical file path. Collapse path aliases and symlinks according to workspace behavior so that two spellings of the same target become one graph node. Classify unresolved specifiers as external, unresolved, or configuration errors instead of silently dropping them.
5. Map files to architectural nodes
Use project metadata, directory ownership, or an explicit configuration file to map each canonical file to a project and its tags. Fail closed when a file belongs to no project: an unowned file is a boundary blind spot. For external packages, normalize the package name to its top-level dependency and retain the original specifier for diagnostics.
Rank #4
- Dual Converters, Infinite Potential:Includes 2× USB C male to USB A female adapters and 2× USB A male to USB C female adapters. Perfect for a wide range of uses—tablets with Bluetooth keyboards, expand USB ports on macbook, and more. Two different converters for all your daily needs
- Next-Level 10Gbps & 3A Charging: No more slow 480Mbps, this usb to usb c adapter has a transfer speed of up to 10Gbps, allowing you to do more transferring in less time. This usb adapter fits both USB A and USB C charger, supporting up to 3A fast charging
- Upgraded Exquisite Craftsmanship: With an aluminum alloy housing and metal connector, the usbc to usb adapter is extremely durable and sturdy. Rigorously tested to withstand more than 10,000 times of plugging and unplugging, ensuring long-lasting performance
- Broad Compatible: The usb c to usb adapter widely supports all USB C/ USB A devices like laptops, tablets, cellphones, car chargers, and phone chargers. Such as compatible with MacBook Pro/Air 2023/2022, Thunderbolt 4/3 Devices,Apple MagSafe Watch 9/8/7/SE/Ultra, iPad Pro 2022/2021, Samsung Galaxy S23/S20/S10, and iPhone 17/16/15 Pro. Plug and play
- Please Note: To reach 10Gbps speed, keep the cable under 3.3 ft. For USB A Male to USB C adapters, try flipping the USB C connector. USB C Male to USB A adapters support bidirectional 10Gbps transfer within 3.3 ft
6. Evaluate the matrix and emit actionable diagnostics
For every edge, evaluate source tags against allowed and forbidden target tags and external-package lists. Report the importing file and project, the imported specifier and resolved target, and the rule that rejected the edge. A useful message looks like: apps/portal/src/routes.ts (scope:portal) imports libs/identity-ui (scope:identity); allowed targets are scope:portal and scope:shared. Include a stable error code so CI annotations and suppression reviews do not depend on prose.
7. Test resolution and policy separately
Create fixtures for relative imports, path aliases, workspace package names, re-exports, type-only imports, circular references, missing files, and generated output. Add a test for every dynamic-import behavior you support. Keep policy tests small enough to show which edge should pass or fail; then run the analyzer against a representative project graph to catch configuration mistakes.
Use project references for structure, not as the whole policy
TypeScript project references organize related compiler projects, can improve build times, and help enforce logical separation during builds. They do not describe every architectural rule a team may need. A referenced project can still expose an import path that violates a scope rule, and a non-referenced package may still be an unwanted dependency. Keep references aligned with ownership, then apply explicit boundary checks for direction, external packages, and exceptions.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Handle the edges that make graphs inaccurate
Aliases and package exports
Resolve paths, package exports, and workspace links with the same configuration used by compilation and bundling. Test both alias and relative spellings if both are allowed; otherwise developers may bypass a rule by changing syntax.
Re-exports and barrel files
Count re-exports as edges because a barrel can leak a forbidden dependency even when consumers import only the barrel. Decide whether the policy checks the direct re-export edge, the transitive exposure, or both, and document that choice.
Best Value
- 5-in-1 Connectivity: Equipped with a 4K HDMI port, a 5 Gbps USB-C data port, two 5 Gbps USB-A ports, and a USB C 100W PD-IN port. Note: The USB C 100W PD-IN port supports only charging and does not support data transfer devices such as headphones or speakers.
- Powerful Pass-Through Charging: Supports up to 85W pass-through charging so you can power up your laptop while you use the hub. Note: Pass-through charging requires a charger (not included). Note: To achieve full power for iPad, we recommend using a 45W wall charger.
- Transfer Files in Seconds: Move files to and from your laptop at speeds of up to 5 Gbps via the USB-C and USB-A data ports. Note: The USB C 5Gbps Data port does not support video output.
- HD Display: Connect to the HDMI port to stream or mirror content to an external monitor in resolutions of up to 4K@30Hz. Note: The USB-C ports do not support video output.
- What You Get: Anker 332 USB-C Hub (5-in-1), welcome guide, our worry-free 18-month warranty, and friendly customer service.
Type-only imports
Type-only imports disappear from emitted JavaScript but remain compile-time dependencies. Include them when the boundary protects ownership or API design; permit them selectively only when the architecture intentionally separates runtime and type coupling.
Dynamic imports
Literal dynamic imports can often be resolved, while computed expressions may not be statically knowable. Choose one behavior for non-literal forms: fail with a dedicated diagnostic, require an annotation, or route them through an approved loader. Do not silently omit them.
Generated and test code
Generated files should normally be checked at their source templates or excluded with a documented ownership rule. Test code may need broader access for integration tests, but grant that access through a separate tag or project type rather than a global bypass.
Circular dependencies
A cycle is a graph property independent of whether each individual edge is allowed. Enable cycle checks where they support the architecture, and distinguish an intentional cycle from an accidental one with a reviewed exception. The dependency-cruiser rules reference documents configurable circular-dependency checks.
Quick Recap
Roll out enforcement without freezing development
- Inventory first. Generate the current graph and group violations by source team, target layer, and repeated pattern.
- Fix ownership metadata. Add missing project tags, map orphaned files, and remove generated output from the analyzed set where appropriate.
- Separate legacy debt from new debt. Record existing violations in a temporary baseline, but make every new forbidden edge fail immediately.
- Improve diagnostics. Include canonical paths, project names, tags, and a remediation hint such as the approved shared API.
- Run locally and in CI. Developers should be able to invoke the same command before pushing; CI should run it on every affected project and on full-graph changes.
- Review exceptions. Require an owner, reason, scope, and removal condition for each allow-list entry or dynamic-dependency exemption.
- Delete the baseline. Remove legacy suppressions as teams repair the graph so the policy becomes a real invariant rather than a report.
Diagnose common failures
- An allowed import is reported as forbidden: compare the analyzer’s resolved path with the build’s resolution, then check project tags and AND-combined constraints.
- A forbidden import is missed: verify that the file is included in the program, that its project mapping exists, and that re-exports or type-only imports are collected.
- Only CI fails: pin the TypeScript and workspace configuration used by CI; differing compiler versions or generated files often produce different graphs.
- External packages bypass restrictions: configure explicit allowed and banned external-import lists and normalize subpath imports to their package root where the policy requires it.
- Developers add broad exceptions: replace the exception with an approved façade or shared contract, and require a narrowly scoped path if a temporary bypass is unavoidable.
A practical decision checklist
- Choose the integrated Nx rule when projects, tags, and lint targets already define your workspace.
- Choose a Compiler API analyzer when policy semantics, output format, or repository structure are specialized enough to justify ownership of the tooling.
- Evaluate Nx Conformance when an Nx Enterprise workspace needs dependency checks beyond import-derived edges and the licensing model fits.
- Evaluate dependency-cruiser when a standalone graph and cycle-rule workflow is preferable, after validating its resolver against your aliases and package layout.
- Regardless of tool, write the matrix first, resolve imports with build-equivalent settings, test edge cases, and make diagnostics identify both ends of every forbidden edge.
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

