Skip to main content

Guide

giget vs degit vs tiged (2026)

Compare giget, degit, and tiged for downloading Git repository templates in Node.js. Project scaffolding, template cloning without git history, and more.

·PkgPulse Team·
0

TL;DR

giget is the UnJS template downloader — downloads Git repos and tar archives without git history, supports GitHub, GitLab, Bitbucket, and custom registries, used by Nuxt's nuxi init. degit is Rich Harris's project scaffolding tool — downloads repos without git history, simple CLI, created by the Svelte author. tiged is the community fork of degit — fixes bugs and adds features degit hasn't merged, drop-in replacement. In 2026: giget for programmatic template downloading, degit/tiged for CLI project scaffolding.

Key Takeaways

  • giget: ~3M weekly downloads — UnJS, programmatic API, registry support, powers Nuxt CLI
  • degit: ~500K weekly downloads — Rich Harris, CLI-first, simple but unmaintained
  • tiged: ~100K weekly downloads — community fork of degit, maintained, bug fixes
  • All three download repos without .git history — clean project scaffolding
  • giget supports custom template registries (like Nuxt starters)
  • degit and tiged are CLI tools; giget has both CLI and programmatic API

The Problem

# git clone downloads the ENTIRE history:
git clone https://github.com/nuxt/starter
# → Downloads all commits, branches, tags
# → .git directory is ~50MB for large repos
# → You just wanted the latest files

# What you actually want:
# → Download just the latest files
# → No .git directory
# → No commit history
# → Ready to start a new project

giget

giget — universal template downloader:

CLI usage

# Download from GitHub:
npx giget gh:nuxt/starter my-app
npx giget github:vitejs/vite/packages/create-vite/template-react-ts my-react-app

# Short syntax:
npx giget nuxt/starter my-app

# GitLab:
npx giget gitlab:user/repo my-project

# Bitbucket:
npx giget bitbucket:user/repo my-project

# Specific branch/tag:
npx giget gh:nuxt/starter#v3 my-app
npx giget gh:vuejs/create-vue#main my-vue-app

# Subdirectory:
npx giget gh:unjs/template/ts my-ts-project

Programmatic API

import { downloadTemplate } from "giget"

// Download a template:
const { source, dir } = await downloadTemplate("gh:nuxt/starter", {
  dir: "./my-app",
  force: true,     // Overwrite existing directory
  install: false,  // Don't run npm install
})

console.log(`Downloaded from ${source} to ${dir}`)

// With options:
await downloadTemplate("gh:vitejs/vite", {
  dir: "./my-project",
  preferOffline: true,   // Use cache if available
  offline: false,         // Allow network requests
  cwd: process.cwd(),
  auth: process.env.GITHUB_TOKEN,  // For private repos
})

Custom registries

import { downloadTemplate } from "giget"

// Nuxt uses a custom registry for starters:
await downloadTemplate("nuxt", {
  registry: "https://raw.githubusercontent.com/nuxt/starter/templates/templates",
})

// Custom registry for your organization:
await downloadTemplate("my-template", {
  registry: "https://templates.mycompany.com",
})

How Nuxt uses giget

// nuxi init uses giget to scaffold projects:
// npx nuxi init my-app

// Internally:
import { downloadTemplate } from "giget"

async function initProject(name: string, template: string = "v3") {
  await downloadTemplate(`nuxt/starter#${template}`, {
    dir: name,
    force: false,
  })

  console.log(`✅ Nuxt project created in ./${name}`)
  console.log(`   cd ${name} && npm install`)
}

degit

degit — project scaffolding:

CLI usage

# Download from GitHub:
npx degit user/repo my-project
npx degit sveltejs/template my-svelte-app

# Specific branch:
npx degit user/repo#dev my-project

# Specific tag:
npx degit user/repo#v1.0.0 my-project

# Subdirectory:
npx degit user/repo/path/to/subdir my-project

# GitLab / Bitbucket:
npx degit gitlab:user/repo my-project
npx degit bitbucket:user/repo my-project

# With verbose output:
npx degit -v user/repo my-project

Programmatic usage

import degit from "degit"

const emitter = degit("user/repo", {
  cache: true,
  force: true,
  verbose: true,
})

emitter.on("info", (info) => {
  console.log(info.message)
})

await emitter.clone("./my-project")

degit.json actions

// degit.json — post-clone actions:
[
  {
    "action": "clone",
    "src": "user/another-repo"
  },
  {
    "action": "remove",
    "files": ["LICENSE", ".github"]
  }
]

degit limitations

degit:
  ✅ Simple CLI — npx degit user/repo dir
  ✅ Caching — downloads faster on repeat
  ✅ Post-clone actions (degit.json)
  ✅ Created by Rich Harris (Svelte author)

  ❌ Not actively maintained (last release 2020)
  ❌ GitHub API issues unfixed
  ❌ No private repo support (without workarounds)
  ❌ Limited programmatic API
  ❌ No TypeScript types

→ Use tiged (maintained fork) or giget instead

tiged

tiged — maintained degit fork:

CLI usage (same as degit)

# Drop-in replacement for degit:
npx tiged user/repo my-project
npx tiged sveltejs/template my-svelte-app

# All degit syntax works:
npx tiged user/repo#branch my-project
npx tiged gitlab:user/repo my-project
npx tiged user/repo/subdir my-project

Fixes over degit

tiged improvements over degit:
  ✅ Fixed GitHub API rate limiting issues
  ✅ Fixed private repo downloading
  ✅ Fixed subdirectory extraction bugs
  ✅ Active maintenance (regular releases)
  ✅ TypeScript support
  ✅ Better error messages

Same API — just replace "degit" with "tiged":
  npx degit user/repo dir  →  npx tiged user/repo dir

Programmatic usage

import tiged from "tiged"

const emitter = tiged("user/repo", {
  cache: true,
  force: true,
  verbose: true,
})

emitter.on("info", (info) => {
  console.log(info.message)
})

emitter.on("warn", (warning) => {
  console.warn(warning.message)
})

await emitter.clone("./my-project")

Feature Comparison

Featuregigetdegittiged
CLI
Programmatic API✅ (full)⚠️ (basic)⚠️ (basic)
GitHub
GitLab
Bitbucket
Custom registries
Private repos✅ (auth token)
Subdirectories
Branch/tag
Caching
Post-clone actions✅ (degit.json)✅ (degit.json)
TypeScript
Maintained✅ (UnJS)❌ (2020)
Weekly downloads~3M~500K~100K

When to Use Each

Use giget if:

  • Need a programmatic API for template downloading
  • Building a CLI tool that scaffolds projects (like nuxi, create-*)
  • Want custom template registries
  • In the UnJS ecosystem

Use tiged if:

  • Want a CLI-first scaffolding tool (npx tiged user/repo dir)
  • Currently using degit and need bug fixes
  • Need post-clone actions (degit.json)
  • Want a maintained drop-in degit replacement

Use degit if:

  • Already using it and it works for your use case
  • Note: consider switching to tiged for bug fixes

Building Your Own create-* CLI with giget

The most common production use of giget is building scaffolding CLIs — the create-myapp experience that sets up a project from a template with a single command. giget's programmatic API makes this straightforward:

// create-myapp — a minimal scaffolding CLI using giget
import { downloadTemplate } from "giget"
import { defineCommand, runMain } from "citty"

const main = defineCommand({
  meta: {
    name: "create-myapp",
    description: "Scaffold a new MyApp project",
  },
  args: {
    name: {
      type: "positional",
      description: "Project directory name",
      required: true,
    },
    template: {
      type: "string",
      description: "Template to use (default, typescript, minimal)",
      default: "default",
    },
  },
  async run({ args }) {
    const { name, template } = args

    console.log(`Scaffolding ${name} with ${template} template...`)

    const { source, dir } = await downloadTemplate(
      `gh:myorg/myapp-templates/${template}`,
      {
        dir: `./${name}`,
        force: false,
        install: false,
      }
    )

    console.log(`✅ Project created at ${dir}`)
    console.log(`   cd ${name} && npm install && npm run dev`)
  },
})

runMain(main)
// package.json for the create-* CLI:
{
  "name": "create-myapp",
  "bin": {
    "create-myapp": "./dist/index.mjs"
  },
  "dependencies": {
    "citty": "^0.1.6",
    "giget": "^1.2.3"
  }
}

This pattern powers nuxi init, create-h3, create-nitro, and dozens of other UnJS-ecosystem scaffolding tools.


Private Repository Support

Downloading templates from private repositories requires authentication. The approaches differ by tool:

giget (recommended):

# Via environment variable (recommended for CI):
GITHUB_TOKEN=ghp_your_token npx giget gh:myorg/private-template my-project

# Via CLI flag:
npx giget gh:myorg/private-template my-project --auth=ghp_your_token
// Programmatic with token:
await downloadTemplate("gh:myorg/private-template", {
  dir: "./my-project",
  auth: process.env.GITHUB_TOKEN,
})

tiged:

# tiged can use GITHUB_TOKEN via environment variable
GITHUB_TOKEN=ghp_your_token npx tiged myorg/private-repo my-project

degit: Has known issues with private repositories. GitHub's API changes in 2021-2022 broke degit's private repo support in some configurations — this is one of the main reasons tiged exists.

For enterprise setups with GitHub Enterprise Server or self-hosted GitLab:

// giget — custom source providers:
import { downloadTemplate } from "giget"

// Self-hosted GitLab:
await downloadTemplate("gitlab:myorg/template", {
  dir: "./my-project",
  auth: process.env.GITLAB_TOKEN,
  // Custom GitLab instance:
  // registry: "https://gitlab.mycompany.com/api/v4"
})

giget vs git clone + rm -rf .git

The common question: why not just git clone and delete the .git directory?

# Manual approach:
git clone https://github.com/user/template my-project
rm -rf my-project/.git
cd my-project && npm install

# Problems:
# 1. Downloads entire git history (may be hundreds of MB for large repos)
# 2. Requires git to be installed (not always true in container environments)
# 3. No subdirectory support (git sparse checkout is complex)
# 4. No registry abstraction (can't use "nuxt/starter" shorthand)
# giget approach:
npx giget nuxt/starter my-project

# Advantages:
# 1. Downloads only latest commit (tarball — much faster)
# 2. Works in environments without git
# 3. Supports subdirectories: npx giget user/repo/path/to/subdir
# 4. Shorthand registry support

For most template use cases, giget is 5-10x faster than git clone because it downloads a tarball of the latest commit rather than the entire git history.


Weekly npm downloads tell a clear adoption story (early 2026 estimates):

PackageWeekly DownloadsGitHub StarsLast Release
giget~3M1,200+Active (UnJS)
degit~500K5,400+2020 (unmaintained)
tiged~100K500+Active

degit's 5,400 GitHub stars versus tiged's 500 says something interesting: stars are vanity metrics. degit accumulated stars over years of being the go-to scaffolding tool, but the download numbers show the actual trajectory. giget is pulling 6x more downloads than degit — the ecosystem has moved on.

The stars-to-downloads ratio for degit is inverted compared to what you would expect from an active package. People starred it, moved on, and either switched to giget (for programmatic use) or tiged (for CLI-first use). degit's maintainer Rich Harris is focused on Svelte and SvelteKit — which now includes its own scaffolding in sv create, reducing the need for degit even in the Svelte community.

giget's download growth tracks almost exactly with Nuxt 3 adoption. The Nuxt team built nuxi init on giget, and every Nuxt project creation is a giget install. This gives giget a massive baseline of downloads that are not at all related to direct user choice — they are transitive.

Performance Comparison

All three tools solve the same speed problem relative to git clone, but their implementation details differ:

ToolMethodSpeed (typical)Caching
gigetGitHub tarball download2-5 secondsLocal cache dir
degitGitHub tarball download3-8 seconds~/.degit dir
tigedGitHub tarball download3-8 seconds~/.degit dir
git cloneFull git history15-60+ secondsNone

All three download GitHub's auto-generated tarball for the target ref — the same .tar.gz that GitHub generates for "Download ZIP." The speed difference relative to git clone is dramatic: instead of fetching every commit in the history, you get only the files at the target commit.

giget tends to be slightly faster than degit/tiged in practice because its codebase was written more recently with modern async patterns and it handles the Cloudflare/GitHub CDN responses more efficiently. The difference is measured in seconds at most — not a deciding factor for most users.

Migration Guide: degit to tiged or giget

If you are currently using degit and hitting bugs (the most common being GitHub API rate limiting and private repo issues), here is the migration path:

degit to tiged (drop-in):

# Before:
npx degit user/repo my-project
npx degit user/repo#branch my-project

# After (identical syntax):
npx tiged user/repo my-project
npx tiged user/repo#branch my-project

# Programmatic — change only the import:
# Before:
import degit from "degit"
const emitter = degit("user/repo", { cache: true })

# After:
import tiged from "tiged"
const emitter = tiged("user/repo", { cache: true })

degit to giget (API change):

# CLI — syntax differs slightly:
# Before:
npx degit user/repo my-project
npx degit user/repo#branch my-project

# After:
npx giget gh:user/repo my-project
npx giget gh:user/repo#branch my-project

# Programmatic:
# Before:
import degit from "degit"
const emitter = degit("user/repo")
await emitter.clone("./my-project")

# After:
import { downloadTemplate } from "giget"
await downloadTemplate("gh:user/repo", { dir: "./my-project" })

The giget migration requires updating both the CLI syntax (adding the gh: prefix) and the programmatic API (from event-emitter pattern to promise-based downloadTemplate). For teams with simple usage, this is a 10-minute change. For teams with complex degit.json post-clone actions, note that giget does not support degit.json — you would need to replicate that logic in your scaffolding script.

Real-World Who Uses What in 2026

Understanding which tools power which projects helps clarify the intended use case for each:

giget powers the Nuxt ecosystem. nuxi init, nuxi add, and template-based project creation in Nuxt 3 all use giget. The UnJS template registry at unjs/template uses giget. create-h3, create-nitro, and other UnJS scaffolding CLIs are built on giget's programmatic API. If you are building a create-* package for your own framework or toolchain, giget is the standard choice in 2026.

tiged is the tool for developers who want npx tiged user/repo dir and nothing more. It is popular in the Svelte community (since degit is the original Svelte scaffolding tool and tiged is the maintained version), and among developers who want a simple CLI without the UnJS ecosystem dependency.

degit remains in use only in projects that haven't updated their scaffolding docs. It still works for public repositories on GitHub that haven't changed their API behavior. The Svelte official docs pointed to degit for years, and many tutorials still reference it — but the recommended path is now npx sv create for SvelteKit or tiged for custom templates.

Template Caching and Offline Workflows

All three tools support local caching of downloaded templates, which matters for developers working on planes or in environments with unreliable network access. giget caches tarballs to ~/.giget by default, and the { cache: true } option in the programmatic API tells it to use the cached version if the template has been downloaded before. degit and tiged cache similarly to ~/.degit. The cache key is the resolved ref (commit hash), not just the branch name — so gh:user/repo#main will re-download when the main branch gets new commits, but gh:user/repo#abc123 (a pinned commit) will always use the cache after the first download. For create-* CLIs that need to work offline, explicitly pinning a commit hash in the default template URL ensures the cache is always valid. Clearing the cache is manual (delete the directory), which is a minor pain point all three share. giget's { force: true } option bypasses the cache for a fresh download regardless of what is stored.

Methodology

Download data from npm registry (weekly average, February 2026). Feature comparison based on giget v1.x, degit v2.x, and tiged v3.x.

Compare project scaffolding tool health on PkgPulse. Also see cac vs meow vs arg 2026 for CLI argument parsing and cosmiconfig vs lilconfig vs c12 for config loading.

Related: archiver vs adm-zip vs JSZip (2026).

The 2026 JavaScript Stack Cheatsheet

One PDF: the best package for every category (ORMs, bundlers, auth, testing, state management). Used by 500+ devs. Free, updated monthly.