Skip to main content
Documentation

Submodules & Monorepos

Organize complex projects with multiple repositories or unified monorepos. Dits supports both patterns with optimizations for large-scale projects.

Submodules
Embed external repos in your project
  • Independent versioning
  • Shared across projects
  • Pinned to specific commits
Monorepos
All code in one repository
  • Atomic changes across packages
  • Simplified dependencies
  • Single source of truth

Submodules

Adding a Submodule

# Add a submodule
$ dits submodule add https://dits.example.com/shared-lib libs/shared
Cloning into 'libs/shared'...
done.

# This creates:
# - libs/shared/ directory with the submodule content
# - .ditsmodules file tracking the submodule

$ cat .ditsmodules
[submodule "libs/shared"]
    path = libs/shared
    url = https://dits.example.com/shared-lib

Cloning with Submodules

# Clone and init submodules in one command
$ dits clone --recurse-submodules https://dits.example.com/main-project

# Or init after cloning
$ dits clone https://dits.example.com/main-project
$ cd main-project
$ dits submodule init
$ dits submodule update

Updating Submodules

# Update all submodules to their tracked commits
$ dits submodule update

# Update to latest remote commits
$ dits submodule update --remote

# Update specific submodule
$ dits submodule update --remote libs/shared

# Pull latest for all submodules
$ dits submodule foreach 'dits pull origin main'

Working Inside Submodules

# Make changes in submodule
$ cd libs/shared
$ dits checkout -b feature/update
# ... make changes ...
$ dits commit -m "Update shared lib"
$ dits push origin feature/update

# Back in main project, update reference
$ cd ../..
$ dits add libs/shared
$ dits commit -m "Update shared-lib to latest"
$ dits push origin main

Removing Submodules

# Remove submodule
$ dits submodule deinit libs/shared
$ dits rm libs/shared
$ rm -rf .dits/modules/libs/shared

$ dits commit -m "Remove shared-lib submodule"

Monorepo Structure

For projects where you want everything in one repository:

# Typical monorepo structure
my-project/
├── apps/
│   ├── web/          # Web application
│   ├── mobile/       # Mobile app
│   └── cli/          # Command-line tool
├── packages/
│   ├── core/         # Shared core library
│   ├── ui/           # UI component library
│   └── utils/        # Utility functions
├── assets/
│   ├── images/       # Shared images
│   └── videos/       # Video content
├── tools/
│   └── scripts/      # Build scripts
├── dits.toml
└── package.json

Sparse Checkout for Monorepos

Work on just the parts you need without downloading the entire repo:

# Clone metadata only
$ dits clone --filter blob:none https://dits.example.com/monorepo
$ cd monorepo

# Enable sparse checkout
$ dits sparse-checkout init --cone

# Check out only what you need
$ dits sparse-checkout set apps/web packages/core packages/ui

# Now only these directories have content
$ ls apps/
web/  # Only web is present

# Add more paths later
$ dits sparse-checkout add assets/images

# Show current sparse paths
$ dits sparse-checkout list
apps/web
packages/core
packages/ui
assets/images

Monorepo with VFS

For very large monorepos, use VFS mounting for instant access:

# Clone metadata only
$ dits clone --filter blob:none https://dits.example.com/huge-monorepo
$ cd huge-monorepo

# Mount entire repo - files load on demand
$ dits mount /mnt/project

# Access any file instantly
$ ls /mnt/project/apps/web/
# Files appear immediately, content streams when accessed

# Work normally - your editor sees regular files
$ code /mnt/project/apps/web/

Path-Based Permissions

Control access to different parts of your monorepo:

# .dits/access.toml
[permissions]
# Default: read for all authenticated users
default = "read"

# Write access by path
[permissions.write]
"apps/web" = ["web-team", "leads"]
"apps/mobile" = ["mobile-team", "leads"]
"packages/*" = ["core-team", "leads"]
"assets/videos" = ["content-team"]

# Admin access
[permissions.admin]
"*" = ["leads", "devops"]

When to Use Which

ScenarioRecommendation
Shared library across projectsSubmodule
External dependency you forkSubmodule
Tightly coupled applicationsMonorepo
Atomic refactors across packagesMonorepo
Independent release cyclesSubmodule or separate repos
Game + assets + toolsMonorepo with sparse checkout

Related Topics