wingettutorialimportsetup

How to Use winget import: Set Up a New Windows Machine in 5 Minutes

Complete tutorial for winget import and export. Learn how to save your Windows app setup to a JSON file and replay it on any new machine in minutes.

· 4 min read · updated May 29, 2026
How to Use winget import: Set Up a New Windows Machine in 5 Minutes

The single most underrated winget feature is import. It turns "setting up a new Windows machine" from a half-day chore into a 5-minute command. Here's how it works.

What is winget import?

Winget can read a JSON file listing apps and install them all in one shot. Combined with winget export, you can:

  • Save your current Windows setup to a file
  • Replay it on a fresh machine (or a teammate's machine)
  • Version-control your machine config in Git
  • Share a "perfect dev setup" with your team

The 60-second version

On your existing machine:

winget export -o my-apps.json --include-versions

On the new machine:

winget import -i my-apps.json

Done. Winget reads the file, installs everything, exits when finished. Typical time: 5–15 minutes depending on apps + internet speed.

The JSON format

Open a generated file — it looks like this:

{
  "$schema": "https://aka.ms/winget-packages.schema.2.0.json",
  "CreationDate": "2026-05-27T00:00:00.000-00:00",
  "Sources": [
    {
      "Packages": [
        { "PackageIdentifier": "Microsoft.VisualStudioCode" },
        { "PackageIdentifier": "Git.Git" },
        { "PackageIdentifier": "OpenJS.NodeJS.LTS" }
      ],
      "SourceDetails": {
        "Argument":   "https://cdn.winget.microsoft.com/cache",
        "Identifier": "Microsoft.Winget.Source_8wekyb3d8bbwe",
        "Name":       "winget",
        "Type":       "Microsoft.PreIndexed.Package"
      }
    }
  ],
  "WinGetVersion": "1.10.340"
}

It's plain JSON. Each PackageIdentifier is the winget ID you'd normally pass to --id. You can:

  • Edit it by hand to add/remove apps
  • Generate it from scratch (no machine needed — see below)
  • Check it into Git

Pinning specific versions

By default import installs the latest version of each app. To force exact versions:

{
  "Packages": [
    { "PackageIdentifier": "OpenJS.NodeJS", "Version": "20.18.0" }
  ]
}

Or when exporting:

winget export -o my-apps.json --include-versions

…and the file will include the version of every app currently installed.

Generating an import file without a source machine

You can build the JSON before you even have a new machine. We made a tool for exactly this:

  1. Go to winget.tech
  2. Browse and click + to add apps to your script
  3. Click Generate script
  4. Pick the Winget Import (.json) tab
  5. Click Download

The downloaded winstall.json is a valid winget import file. Move it to the new machine and run winget import -i winstall.json.

💡 You can also use a pre-made bundle (Developer, Gaming, Designer…) and add it to your script with one click.

Useful flags

winget import -i file.json --ignore-unavailable    # skip apps not in catalog
winget import -i file.json --ignore-versions       # always use latest
winget import -i file.json --accept-package-agreements
                          --accept-source-agreements   # for unattended runs

For automated / CI use:

winget import -i file.json `
  --ignore-unavailable `
  --ignore-versions `
  --accept-package-agreements `
  --accept-source-agreements `
  --disable-interactivity

A real example: my actual machine setup

Here's a minimal dev.json I run on every new dev machine:

{
  "$schema": "https://aka.ms/winget-packages.schema.2.0.json",
  "CreationDate": "2026-05-27T00:00:00.000-00:00",
  "Sources": [{
    "Packages": [
      { "PackageIdentifier": "Microsoft.VisualStudioCode" },
      { "PackageIdentifier": "Microsoft.WindowsTerminal" },
      { "PackageIdentifier": "Microsoft.PowerShell" },
      { "PackageIdentifier": "Microsoft.PowerToys" },
      { "PackageIdentifier": "Git.Git" },
      { "PackageIdentifier": "GitHub.cli" },
      { "PackageIdentifier": "OpenJS.NodeJS.LTS" },
      { "PackageIdentifier": "Python.Python.3.13" },
      { "PackageIdentifier": "Docker.DockerDesktop" },
      { "PackageIdentifier": "BurntSushi.ripgrep.MSVC" },
      { "PackageIdentifier": "Starship.Starship" },
      { "PackageIdentifier": "voidtools.Everything" },
      { "PackageIdentifier": "Google.Chrome" },
      { "PackageIdentifier": "Discord.Discord" },
      { "PackageIdentifier": "Spotify.Spotify" }
    ],
    "SourceDetails": {
      "Argument":   "https://cdn.winget.microsoft.com/cache",
      "Identifier": "Microsoft.Winget.Source_8wekyb3d8bbwe",
      "Name":       "winget",
      "Type":       "Microsoft.PreIndexed.Package"
    }
  }],
  "WinGetVersion": "1.10.340"
}

15 essentials. Save it, push to a private repo, clone on every new machine, run winget import -i dev.json.

Version-controlling your machine

If you treat your dotfiles / scripts as code, do the same with your machine setup:

my-machine/
├── dev.json              # winget packages
├── vscode-settings.json  # editor config
├── windows-terminal.json # terminal config
├── powershell-profile.ps1
└── setup.ps1             # script that ties it all together

setup.ps1 example:

# Install all winget packages
winget import -i $PSScriptRoot\dev.json --accept-package-agreements --accept-source-agreements

# Symlink configs
$vsCodeDir = "$env:APPDATA\Code\User"
Copy-Item $PSScriptRoot\vscode-settings.json $vsCodeDir\settings.json -Force

# PowerShell profile
Copy-Item $PSScriptRoot\powershell-profile.ps1 $PROFILE -Force

Write-Host "Done. Restart shells to apply config."

Now setting up a new machine is:

git clone https://github.com/me/my-machine.git
cd my-machine
.\setup.ps1

When import fails partially

winget import is mostly all-or-nothing — if one package fails, it moves on. Common reasons:

  • Package ID was renamed upstream → edit the JSON, update ID
  • Network blip → re-run, it'll skip already-installed
  • App needs a dependency winget can't auto-resolve → install dep manually first
  • Hash mismatch → publisher updated installer, catalog stale → wait or --force

Use --ignore-unavailable to skip rather than fail on missing packages.

See also

Got a setup workflow you love? Send it in — we feature the best ones in this post.

Continue reading