This document describes the actual architecture of degit: a single-package TypeScript CLI and library that downloads a snapshot of a remote git repository, caches tarballs locally, and falls back to SSH cloning when tarball fetching or extraction fails.
The repository is intentionally small. The source of truth for behavior lives in src/, tests live in test/, and build output is emitted to dist/.
./
├── AGENTS.md # Agent-oriented repo guidance
├── assets/
│ └── help.md # Published CLI help text
├── src/
│ ├── index.ts # Public library entrypoint
│ ├── bin.ts # CLI entrypoint, argument parsing, interactive mode
│ ├── core/
│ │ └── orchestrator.ts # Clone orchestration and mode selection
│ ├── domain/
│ │ ├── repo.ts # Source parsing and provider URL resolution
│ │ └── types.ts # Public and internal type surface
│ ├── operations/
│ │ ├── directives.ts # Post-clone directives
│ │ └── filesystem.ts # Empty-dir checks and remove helpers
│ ├── transports/
│ │ ├── git/
│ │ │ ├── client.ts # Git backend
│ │ │ └── client-utils.ts
│ │ └── tar/
│ │ ├── archive.ts # Tar snapshot clone path
│ │ └── cache.ts # Tar cache persistence
│ └── shared/
│ └── utils.ts # Fetch, exec, filesystem helpers, cache paths
├── test/
│ ├── unit/
│ │ ├── bin.test.ts # CLI behavior and interactive flow
│ │ ├── index.test.ts # Core clone flow, providers, cache, directives
│ │ ├── git-client.test.ts
│ │ ├── lazy-git.test.ts
│ │ └── utils.test.ts
│ ├── integration/
│ │ ├── public.test.ts
│ │ └── private.test.ts
│ └── helpers.ts # Test utilities and mocks
├── dist/ # Built ESM output and type declarations
├── README.md # User-facing usage and setup guide
├── docs/
│ ├── ARCHITECTURE.md # Repository overview and structure
│ ├── CHANGELOG.md # Release notes
│ ├── USAGE.md # User-facing CLI and API guide
│ ├── CODE_OF_CONDUCT.md # Community expectations
│ ├── CONTRIBUTING.md # Contributor workflow and validation commands
│ ├── SECURITY.md # Security policy and reporting process
├── tsdown.config.ts # Build configuration
├── vitest.config.ts # Test and coverage configuration
└── package.json # Scripts, package metadata, and release config
degit is a local CLI/library wrapper around remote repository snapshots:
[User/CLI] -> [src/bin.ts] -> [src/index.ts]
-> [src/core/orchestrator.ts]
-> [src/shared/utils.ts]
-> [Remote provider tarball or git remote]
-> [Local cache under the platform cache directory]
-> [Destination directory]
The important boundary is between local orchestration and remote provider access. src/core/orchestrator.ts resolves the repo, prefers tarball downloads, falls back to SSH cloning when needed, extracts contents, and then applies optional post-clone directives from degit.json.
Name: CLI runner
Description: Parses command-line arguments, renders help text, and provides an interactive repository picker when no source is supplied. It also wires the CLI to the core clone flow and prints colored status output to stderr.
Technologies: TypeScript, mri, enquirer, fuzzysearch, yoctocolors
Deployment: Built into the published degit executable and run locally via Node 20+ or Bun during development.
Name: Degit orchestrator
Description: Implements the main clone lifecycle as an EventEmitter. It parses supported source formats, resolves refs, checks and uses the local cache, downloads tarballs, falls back to SSH cloning when tarball fetches or extraction fail, and applies degit.json directives after the initial clone.
Technologies: TypeScript, tar, yoctocolors, Node standard library
Deployment: Bundled into the published library entrypoint and reused by the CLI and tests.
Name: Runtime helpers
Description: Contains filesystem and process helpers used by the core flow. This includes the HTTPS fetch wrapper with proxy support, git command execution, recursive directory creation, local cache root detection, and stash/unstash helpers for directive processing.
Technologies: Node fs, path, os, https, child_process, https-proxy-agent
Deployment: Internal implementation detail, not exposed as a separate package.
Name: Repository providers
Description: Encodes provider-specific rules for GitHub, GitLab, Bitbucket, and Sourcehut. Each provider maps a parsed repository to the correct archive URL and SSH URL shape.
Technologies: TypeScript data mapping and URL construction
Deployment: In-process logic within src/domain/repo.ts.
Name: Behavior and integration tests
Description: Validates provider parsing, tar and git modes, caching behavior, directives, CLI behavior, and optional live network clones.
Technologies: Vitest, Node test fixtures, tar archive generation, mock fetch and exec helpers
Deployment: Run locally and in CI; test/integration/public.test.ts and test/integration/private.test.ts run directly through bun run test:integration, and the private fixtures are included only when SSH_PRIVATE_KEY is provided in CI or the local shell.
The project does not use an application database or queue. Its persistent state is local and file-based.
Name: degit cache
Type: Filesystem cache under the platform-appropriate user cache directory
Purpose: Stores downloaded tarballs and provider metadata so repeated clones can avoid refetching the same commit archive.
Key Schemas/Collections: Per-provider directories such as github/<user>/<repo>/, plus cache files like <hash>.tar.gz, map.json, and access.json.
Name: Directive stash directory
Type: Temporary filesystem directory under the cache root
Purpose: Preserves existing destination files while degit.json directives run, then restores them after nested clones or removals complete.
The tool talks to a small set of external systems:
GitHub, GitLab, Bitbucket, and Sourcehut: Used to resolve repository refs and download archive tarballs over HTTPS, or to clone over SSH when tarball fetches fail.
Git backend: A native in-process git library is used for SSH ref resolution and fallback cloning.
HTTPS proxy support: https_proxy is honored through https-proxy-agent when fetching tarballs.
npm registry: Used for distribution of the published package, not by the runtime clone flow.
Cloud Provider: None for application runtime. The project is a locally executed CLI/library.
Key Services Used: GitHub Actions for CI, npm for package publishing, and the local filesystem for cache and build artifacts.
CI/CD Pipeline: GitHub Actions. quality.yml runs lint, format, duplication, and dead-code checks; verification.yml runs build and tests; security.yml runs bun audit and CodeQL; publish.yml builds, tests, and publishes tagged releases.
Monitoring & Logging: No dedicated observability stack. Errors and status messages are surfaced directly through the CLI and test output.
Build and release use tsdown to emit dist/ ESM output and type declarations. Development and CI both use Bun 1.3.14, while the published package targets Node 20+.
Authentication: No application login flow. Repository access relies on public HTTPS archives or SSH-based fallback cloning for private repositories.
Authorization: Delegated to the remote git provider and the user’s network credentials.
Data Encryption: Fetches use HTTPS, and private repository cloning uses SSH. There is no application-managed at-rest encryption because the only persisted state is the local cache.
Key Security Tools/Practices: Dependency audit in CI, CodeQL analysis, supported-version policy in docs/SECURITY.md, and a private vulnerability reporting channel via email.
The clone flow also relies on path-safe extraction via the tar library and does not expose a general-purpose file import surface beyond the documented repo snapshot behavior.
Local Setup Instructions: See ../README.md and CONTRIBUTING.md. The expected workflow is bun install, bun run build, and then the relevant tests or checks.
Testing Frameworks: Vitest for unit and integration tests. test/integration/private.test.ts runs directly under bun run test:integration, includes private SSH-backed integration repos when SSH_PRIVATE_KEY is set, and can add more when configured through CI secrets.
Code Quality Tools: Oxlint, Oxfmt, Knip, and jscpd. The repository also uses Husky and lint-staged for pre-commit checks.
The codebase contains a few visible TODO-level improvements rather than a formal roadmap:
- Add a CLI
--proxyflag instead of relying only onhttps_proxy. - Improve directive error messages by including directive indices.
- Add friendlier ref suggestions when a requested ref is invalid.
Project Name: degit
Repository URL: https://github.com/Rich-Harris/degit
Primary Contact/Team: Rich Harris / degit maintainers
Date of Last Update: 2026-05-23
Tar path: The default clone path. Degit downloads a provider archive and extracts it locally.
SSH fallback: The compatibility path that clones over SSH when tarball fetches or extraction fail.
Directive: An entry in degit.json that runs after the initial clone. Current directives are clone and remove.
Cache root: The local storage location resolved from the platform cache directory used for downloaded archives and metadata.
Provider: A supported hosting service whose repository URL format degit understands: GitHub, GitLab, Bitbucket, or Sourcehut.