← Refactoring and maintenance guides

How to split modules with local specs

How-To Refactoring and maintenance Intermediate 1151004HOWTO-1151004

HOWTO-1151004Refactoring and maintenanceIntermediate

This guide shows you how to split modules with local specs in a spec-driven development workflow.

Module splits are risky because they change structure, ownership, imports, and tests at the same time. Without specs, reviewers must infer whether behavior moved safely or whether responsibilities were silently changed.

SpecDD lets you split the module by separating stable parent constraints from child responsibilities. The parent keeps module-wide architecture. Child specs own the smaller units.

Short answer

Before splitting a module, identify the responsibilities inside it. Keep shared module constraints in the parent spec. Create child specs for smaller units, move Owns and local Must rules to the right child, avoid duplicating parent rules, update paths and references, then run checks that prove behavior and boundaries were preserved.

When to use this guide

Use this guide when:

Steps

1. Identify responsibilities

Start from the current module spec:

Spec: Trips Module

Purpose:
  Provide the part of the app where people plan trips.

Owns:
  ./src/trips/*

Must:
  Trips have a destination and date range.
  Places can be added to a trip itinerary.
  Itinerary items remain grouped by day.
  Changes are saved through trip storage.

Potential child responsibilities:

2. Keep parent constraints in the parent

Module-wide boundaries should stay in the parent:

Must not:
  Purchase bookings or tickets.
  Manage destination search results.

Child specs inherit these constraints. Do not copy them into every child spec.

3. Create child specs for real owners

Child spec:

Spec: Itinerary Validation

Purpose:
  Decide whether an itinerary item can be saved.

Owns:
  ./itinerary-validation.js
  ./itinerary-validation.test.js

Must:
  Reject itinerary items without a place name.
  Preserve existing itinerary items when validation fails.

Must not:
  Save itinerary items directly.

This child has a coherent responsibility.

4. Move ownership carefully

When a file moves from parent ownership to child ownership, update both specs:

Avoid leaving both parent and child claiming the same file unless the parent is intentionally providing broad inherited context and the child is the nearest write authority.

5. Avoid duplicating parent rules

Parent:

Must not:
  Purchase bookings or tickets.

Child should not repeat that unless it adds a distinct local boundary:

Must not:
  Save itinerary items directly.

Duplication causes drift when parent rules change.

6. Move tests with behavior

If itinerary validation becomes a child owner, move or add validation tests near that child:

Owns:
  ./itinerary-validation.js
  ./itinerary-validation.test.js

Do not leave all tests in the old module-level test file if they now prove local child behavior.

7. Verify the split

Run checks that prove:

Common mistakes

How to verify the result

The module split worked when:

← Refactoring and maintenance guides