Skip to content
Arxo Arxo

FSD Architecture

The fsd_architecture metric evaluates core Feature-Sliced Design signals using your import graph and architecture.layers.

fsd_architecture

  • fsd.slice_cross_import_count
  • fsd.slice_cross_import_ratio
  • fsd.public_api_bypass_count
  • fsd.shared_gravity_index
  • fsd.layer_jump_count
  • fsd.layer_jump_ratio
  • fsd.slice_cycle_count
  • fsd.slices_analyzed_count
  • fsd.edges_analyzed_count
  • fsd.granularity_ok (1 = enough graph granularity, 0 = grouping too coarse for slice checks)

It also emits detail tables:

  • fsd.slice_cross_imports_table
  • fsd.public_api_bypass_table
  • fsd.shared_hotspots_table
  • fsd.layer_jumps_table
  • fsd.slice_cycles_table

fsd_architecture reads layer definitions from architecture.layers (not from shape for legacy).

architecture:
layers:
- name: app
paths: ["src/app/**"]
allowed_effects: []
can_depend_on: ["pages", "widgets", "features", "entities", "shared"]
- name: pages
paths: ["src/pages/**"]
allowed_effects: []
can_depend_on: ["widgets", "features", "entities", "shared"]
- name: widgets
paths: ["src/widgets/**"]
allowed_effects: []
can_depend_on: ["features", "entities", "shared"]
- name: features
paths: ["src/features/**"]
allowed_effects: []
can_depend_on: ["entities", "shared"]
- name: entities
paths: ["src/entities/**"]
allowed_effects: []
can_depend_on: ["shared"]
- name: shared
paths: ["src/shared/**"]
allowed_effects: []
can_depend_on: []
metrics:
- id: fsd_architecture
enabled: true
config:
fsd:
slice_roots: ["src/features", "src/entities", "src/widgets", "src/pages"]
shared_layer_names: ["shared"]
public_api_files: ["index.ts", "index.tsx", "index.js", "index.jsx"]
internal_segment_markers: ["model", "ui", "lib", "api", "config", "internal"]
thresholds:
max_slice_cross_import_ratio: 0.05
max_public_api_bypass_count: 0
max_shared_gravity_index: 0.25
max_layer_jump_ratio: 0.10
max_slice_cycle_count: 0
policy:
invariants:
- metric: fsd.slice_cross_import_ratio
op: "<="
value: 0.05
message: "Cross-slice imports are too high"
- metric: fsd.public_api_bypass_count
op: "=="
value: 0
message: "Do not import slice internals directly"
- metric: fsd.layer_jump_ratio
op: "<="
value: 0.10
message: "Layer jumps should stay rare"
- metric: fsd.slice_cycle_count
op: "=="
value: 0
message: "Slice-level cycles are not allowed"
  • If fsd.granularity_ok = 0, increase data.import_graph.group_depth (usually >= 3) so nodes include slice segments like src/features/auth/....
  • fsd.public_api_bypass_count uses original_import when available and falls back to path-based heuristics otherwise.