Git sparse-checkout: check out only what you need in a monorepo
← Back
April 4, 2026Git6 min read

Git sparse-checkout: check out only what you need in a monorepo

Published April 4, 20266 min read

A monorepo with fifty packages means fifty directories of code you mostly never touch. Cloning it pulls 2GB of code for a 10MB change. Your editor indexes everything. Your test runner sees all of it. Git sparse-checkout solves this: you tell git which directories you care about and it only materialises those on disk. Everything else is in the object store but invisible to your working tree.

Setting up sparse-checkout

bash
# On an existing repo: enable sparse-checkout
git sparse-checkout init --cone

# Specify which directories to materialise
git sparse-checkout set packages/api packages/shared packages/types

# Or add to the existing set
git sparse-checkout add packages/dashboard

The --cone flag enables "cone mode," which restricts patterns to top-level and named directories. It is faster than the full pattern mode and handles most monorepo use cases.

Cloning with sparse-checkout from the start

For large repos, clone with sparse-checkout enabled to avoid pulling the full working tree:

bash
# Clone without checking out any files
git clone --no-checkout --filter=blob:none https://github.com/org/monorepo.git
cd monorepo

# Enable sparse-checkout
git sparse-checkout init --cone

# Specify your directories
git sparse-checkout set packages/api packages/shared

# Now check out the files for just those directories
git checkout main

The --filter=blob:none flag does a "blobless clone" — git downloads commits and trees but not file contents until you access them. Combined with sparse-checkout, this dramatically reduces initial clone time for large repos.

What the working tree looks like

bash
# Monorepo structure (full):
# packages/
#   api/        ← you want this
#   auth/
#   billing/
#   dashboard/
#   shared/     ← you want this
#   types/      ← you want this
#   [47 more packages]

git sparse-checkout set packages/api packages/shared packages/types

# Working tree after sparse-checkout:
# packages/
#   api/        ← materialised
#   shared/     ← materialised
#   types/      ← materialised
# (other 47 packages are absent from disk but present in git history)

Viewing and modifying your checkout set

bash
# See what you have checked out
git sparse-checkout list
# packages/api
# packages/shared
# packages/types

# Add a package temporarily
git sparse-checkout add packages/billing

# Remove a package (set replaces the entire list)
git sparse-checkout set packages/api packages/shared packages/types
# (billing is no longer included)

# Disable sparse-checkout — checks out everything
git sparse-checkout disable

Using it in CI for targeted builds

Sparse-checkout is especially valuable in CI where you only need to build the affected packages:

yaml
# GitHub Actions: only check out relevant packages
- name: Checkout
  uses: actions/checkout@v4
  with:
    sparse-checkout: |
      packages/api
      packages/shared
      packages/types
    sparse-checkout-cone-mode: true

Checking out files outside the sparse set temporarily

bash
# Read a file from a package you have not checked out
git show HEAD:packages/billing/src/index.ts

# Temporarily materialise a specific file
git checkout HEAD -- packages/billing/src/config.ts
# This adds the file to disk without changing your sparse set

Sparse-checkout with a partial clone vs without

Two separate features that work well together:

  • Partial clone (--filter=blob:none): Controls what git downloads from the remote. Files not in your sparse set are not fetched at all.
  • Sparse-checkout: Controls what git writes to your working tree. Files are in the local object store but not written to disk.

Using both together gives you the fastest possible setup for a large monorepo: small download, small working tree, full git history.

One thing to watch: tooling compatibility

Most tools work fine with sparse-checkout. A few things to check:

  • Some IDE features (global search, "go to definition" across packages) only see checked-out files. Adjust your checkout set if you need cross-package navigation.
  • Workspace-level package managers (pnpm workspaces, Yarn workspaces) work correctly if the root package.json and workspace config files are in your checkout set. Always include the repo root in your sparse set.
  • git status and git diff only show changes in checked-out files — expected behaviour, but worth knowing.

For teams where most engineers work in 2-3 packages of a large monorepo, sparse-checkout is one of the highest-leverage git settings to configure in your onboarding docs. It turns a frustrating 5-minute clone into a 30-second one.

Share this
← All Posts6 min read