Overview
This guide describes two supported project structures for building applications with Contract Kit and Next.js:- Layer-Split Architecture – optimized for clarity, strong boundaries, and architectural learning
- Feature-Split Architecture – optimized for vertical development and feature ownership
- Hexagonal architecture (domain → use-cases → ports → infrastructure)
- Thin Next.js routing
- Contract-first APIs
- Explicit dependency injection via ports and providers
Core Principles (Applies to All Structures)
Before choosing a folder layout, it helps to understand the rules that matter most.1. Dependency Direction
Dependencies always flow inward:2. Keep Next.js app/ Thin
The Next.js app/ directory should contain routing only:
- Route handlers
- Layouts
- Pages
src/.
3. Ports Define Capabilities
Ports describe what the application needs, not how it is implemented. Examples:db.projects.createcache.getai.generateSummary
Layer-Split Architecture (Recommended Starting Point)
The layer-split approach organizes code by technical responsibility. This is the clearest way to learn and enforce hexagonal architecture.Directory Structure
What Each Layer Is Responsible For
domain/ — Business Rules
Pure logic that answers questions like:
- Is this valid?
- Is this allowed?
use-cases/ — Application Logic
Each file represents a single user intent:
- create a project
- invite a member
- post a comment
- call domain rules
- orchestrate through ports
- return plain data
Contract Kit does not require a specific use-case abstraction.
You may use plain functions or helpers likecreateUseCaseFactory.
ports/ — Dependency Contracts
Ports define capabilities, not implementations.
infra/ — Infrastructure
Concrete implementations of ports.
contracts/ — HTTP Contracts
Transport-layer schemas only.
Contracts:
- define request/response shapes
- contain no business logic
- are shared by server and client
client/ — Client Transport
How the UI consumes contracts.
Includes:
- API client
- React Query hooks and options
- React Hook Form defaults and helpers
ui/ — React Components
Pure UI:
- reusable components
- feature-level screens
- layouts
server/ — Composition
Where everything is wired together:
- ports
- providers
- middleware
- context creation
lib/ — Pure Utilities
Small, framework-agnostic helpers:
- IDs
- dates
- strings
Feature-Split Architecture (Alternative)
The feature-split approach groups code by business feature, with each feature containing its own layers. This improves locality and vertical development speed while keeping the same architectural rules.Directory Structure
Rules That Keep Feature-Split Clean
- Features may depend on
shared/ shared/must never depend on features- Use-cases never import infra directly
- Contracts remain pure
Choosing Between Approaches
| Criteria | Layer-Split | Feature-Split |
|---|---|---|
| Team size | Small | Medium–Large |
| Learning hexagonal architecture | Excellent | Good |
| Feature locality | Low | High |
| Architectural enforcement | Strong | Moderate |
| Migration to microservices | Moderate | Easy |
Recommendation
- Start with Layer-Split
- Migrate to Feature-Split when feature count and team size grow
Quick Decision Guide
| If the file… | Put it in… |
|---|---|
| Contains business rules | domain/ |
| Orchestrates a workflow | use-cases/ |
| Defines HTTP schemas | contracts/ |
| Calls external systems | infra/ |
| Wires ports/providers | server/ |
| Fetches data in React | client/ |
| Renders UI | ui/ |
| Is a pure helper | lib/ |
Summary
Contract Kit supports multiple project structures. The most important things are:- clear dependency direction
- thin routing
- explicit ports and providers
- separation between business logic and infrastructure