Guide

Build a template downloader

Download repository files and reuse the saved copy.

On this page

Before you start

  • Bun, Git, and the system tar, cp, and mkdir commands.
  • An empty working directory and network access to a public repository.

Write a script that downloads a repository into downloaded-template/. Run it twice to see how the cache works.

In an empty directory, initialize a package:

Install the downloader:

Create download.ts at the project root. Keeping the cache in this project makes it easy to inspect the two directories:

download.ts
import gittar from '@hulla/gittar'
import { resolve } from 'node:path'

const snapshot = await gittar({
  url: 'hulladev/gittar',
  branch: 'master',
  cacheDir: resolve('.cache/gittar/master'),
  outDir: resolve('downloaded-template'),
})

console.log(snapshot.fromCache ? 'Used cache' : 'Downloaded')
console.log(`Copied ${snapshot.files.length} files to ${snapshot.outDir}`)

url selects the repository. branch selects the ref to download. outDir keeps the editable copy separate from the cache.

Choose an empty destination

Copying uses cp -R and can replace files with matching names. Use a new directory for this tutorial. Repeated copies don’t remove files that disappeared upstream.

Run the script with Bun, even if you used another package manager to install it:

Terminal
bun download.ts

The first run prints Downloaded and a file count. Open downloaded-template/package.json: it should name @hulla/gittar. The cache directory contains the full extracted repository and its metadata.

Run the same command again. If the remote branch hasn’t changed and the cache is intact, it prints Used cache. The default policy still contacts the remote to check the commit; a cache hit doesn’t mean an offline run.

Add this property to the same config object when you want to reuse the local snapshot without a remote freshness check:

TypeScript
update: 'never',

Run bun download.ts again. It uses the existing cache. On a fresh machine, never still downloads because no snapshot exists yet.

You now have the download stage of a scaffolding tool. Next, copy one folder or handle stale snapshots. For command-line options such as --destination, add an @hulla/args parser around this script.