{"id":457,"date":"2026-10-14T12:41:11","date_gmt":"2026-10-14T12:41:11","guid":{"rendered":"http:\/\/www.scmgalaxy.com\/tutorials\/2015\/11\/21\/how-to-create-a-package-in-nuget\/"},"modified":"2026-10-14T12:41:11","modified_gmt":"2026-10-14T12:41:11","slug":"how-to-create-a-package-in-nuget","status":"publish","type":"post","link":"https:\/\/www.devopsschool.com\/blog\/how-to-create-a-package-in-nuget\/","title":{"rendered":"How to Create NuGet Packages with nuget.exe (Assembly, .nuspec, and .csproj Methods)"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Creating a NuGet package is a core skill for .NET and DevOps engineers who need to distribute internal libraries, scripts, or reusable project assets. This guide explains the three packaging approaches shown in the original tutorial, when each one fits best, and the exact commands and manifest structure you need to produce a <code>.nupkg<\/code> artifact.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><em>Originally published on 2015-11-21; fully revised and updated.<\/em><\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img decoding=\"async\" src=\"https:\/\/www.devopsschool.com\/blog\/wp-content\/uploads\/2015\/11\/how-to-create-a-package-in-.png\" alt=\"create-a-package-in-nuget\"\/><\/figure>\n<\/div>\n\n\n<h2 class=\"wp-block-heading\">Choose the right packaging method<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The original tutorial presents three ways to create packages with <code>nuget.exe<\/code>. In practice, your starting point (compiled DLL, folder layout, or project file) determines which workflow is fastest.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Method<\/th><th>Best for<\/th><th>Primary command path<\/th><th>Notes<\/th><\/tr><\/thead><tbody><tr><td>From an assembly<\/td><td>You already have a compiled DLL and want a quick package<\/td><td><code>nuget spec MyAssembly.dll<\/code> then <code>nuget pack MyAssembly.nuspec<\/code><\/td><td>Simple and fast; metadata comes from assembly and edited <code>.nuspec<\/code>.<\/td><\/tr><tr><td>From a convention-based folder + nuspec<\/td><td>Packages that include content, scripts, tools, or build assets<\/td><td><code>nuget spec<\/code> then <code>nuget pack YourPackage.nuspec<\/code><\/td><td>Most flexible for non-DLL assets and custom folder structures.<\/td><\/tr><tr><td>From a Visual Studio project<\/td><td>Project-centric packaging with token replacement and optional referenced projects<\/td><td><code>nuget spec<\/code> then <code>nuget pack MyProject.csproj<\/code><\/td><td>Uses project metadata tokens like <code>$id$<\/code> and <code>$version$<\/code>.<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">NuGet packaging workflow<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">All three methods follow the same high-level flow: generate or prepare a manifest, verify package content, build the package, and then publish to your feed.<\/p>\n\n\n\n<pre class=\"mermaid\">\nflowchart TD\n    A[Start packaging] --> B{What do you have?}\n    B --> C[Compiled assembly]\n    B --> D[Folder layout and files]\n    B --> E[Project file]\n    C --> F[Generate nuspec from dll]\n    D --> G[Generate or edit nuspec]\n    E --> H[Generate tokenized nuspec]\n    F --> I[Edit metadata and dependencies]\n    G --> I\n    H --> I\n    I --> J[Run nuget pack]\n    J --> K[Validate nupkg contents]\n    K --> L[Publish to repository]\n<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Method 1: Create a package from an existing assembly<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Use this when you already have a compiled assembly and want NuGet to scaffold a <code>.nuspec<\/code> from assembly metadata.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css language-bash\"><span class=\"hljs-selector-tag\">nuget<\/span> <span class=\"hljs-selector-tag\">spec<\/span> <span class=\"hljs-selector-tag\">MyAssembly<\/span><span class=\"hljs-selector-class\">.dll<\/span>\n<span class=\"hljs-selector-tag\">nuget<\/span> <span class=\"hljs-selector-tag\">pack<\/span> <span class=\"hljs-selector-tag\">MyAssembly<\/span><span class=\"hljs-selector-class\">.nuspec<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">After generating the <code>.nuspec<\/code>, update metadata fields (ID, version, description, dependencies) before packing.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Method 2: Create a package from a convention-based directory and nuspec<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">This method is ideal when the package includes more than assemblies, such as content files, scripts, and build artifacts.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Folder<\/th><th>Purpose in package<\/th><\/tr><\/thead><tbody><tr><td><code>lib<\/code><\/td><td>Assemblies to be added as references on install.<\/td><\/tr><tr><td><code>tools<\/code><\/td><td>PowerShell scripts and executables accessible from Package Manager Console.<\/td><\/tr><tr><td><code>content<\/code><\/td><td>Files copied into the target application structure.<\/td><\/tr><tr><td><code>build<\/code><\/td><td>MSBuild targets files applied to consuming projects.<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Step 1: Generate the manifest<\/h3>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs language-bash\">nuget spec<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">This creates a <code>.nuspec<\/code> file you can edit. Example manifest from the original tutorial:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml language-xml\"><span class=\"hljs-meta\">&lt;?xml version=\"1.0\"?&gt;<\/span>\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">package<\/span> <span class=\"hljs-attr\">xmlns<\/span>=<span class=\"hljs-string\">\"http:\/\/schemas.microsoft.com\/packaging\/2010\/07\/nuspec.xsd\"<\/span>&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">metadata<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">id<\/span>&gt;<\/span>MyPackageId<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">id<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">version<\/span>&gt;<\/span>1.0<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">version<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">authors<\/span>&gt;<\/span>philha<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">authors<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">owners<\/span>&gt;<\/span>philha<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">owners<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">licenseUrl<\/span>&gt;<\/span>http:\/\/LICENSE_URL_HERE_OR_DELETE_THIS_LINE<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">licenseUrl<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">projectUrl<\/span>&gt;<\/span>http:\/\/PROJECT_URL_HERE_OR_DELETE_THIS_LINE<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">projectUrl<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">iconUrl<\/span>&gt;<\/span>http:\/\/ICON_URL_HERE_OR_DELETE_THIS_LINE<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">iconUrl<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">requireLicenseAcceptance<\/span>&gt;<\/span>false<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">requireLicenseAcceptance<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">description<\/span>&gt;<\/span>Package description<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">description<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">tags<\/span>&gt;<\/span>Tag1 Tag2<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">tags<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">dependencies<\/span>&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">dependency<\/span> <span class=\"hljs-attr\">id<\/span>=<span class=\"hljs-string\">\"SampleDependency\"<\/span> <span class=\"hljs-attr\">version<\/span>=<span class=\"hljs-string\">\"1.0\"<\/span> \/&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">dependencies<\/span>&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">metadata<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">package<\/span>&gt;<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">Step 2: Lay out package content and build<\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css language-bash\"><span class=\"hljs-selector-tag\">mkdir<\/span> <span class=\"hljs-selector-tag\">lib<\/span>\n<span class=\"hljs-selector-tag\">mkdir<\/span> <span class=\"hljs-selector-tag\">tools<\/span>\n<span class=\"hljs-selector-tag\">mkdir<\/span> <span class=\"hljs-selector-tag\">content<\/span>\n<span class=\"hljs-selector-tag\">mkdir<\/span> <span class=\"hljs-selector-tag\">content<\/span>\\<span class=\"hljs-selector-tag\">controllers<\/span>\n<span class=\"hljs-selector-tag\">copy<\/span> ..\\<span class=\"hljs-selector-tag\">src<\/span>\\<span class=\"hljs-selector-tag\">SomeController<\/span><span class=\"hljs-selector-class\">.cs<\/span> <span class=\"hljs-selector-tag\">content<\/span>\\<span class=\"hljs-selector-tag\">controllers<\/span>\n<span class=\"hljs-selector-tag\">copy<\/span> ..\\<span class=\"hljs-selector-tag\">src<\/span>\\<span class=\"hljs-selector-tag\">MyLibrary<\/span><span class=\"hljs-selector-class\">.dll<\/span> <span class=\"hljs-selector-tag\">lib<\/span>\n<span class=\"hljs-selector-tag\">copy<\/span> ..\\<span class=\"hljs-selector-tag\">src<\/span>\\<span class=\"hljs-selector-tag\">SomePowershellScript<\/span><span class=\"hljs-selector-class\">.ps1<\/span> <span class=\"hljs-selector-tag\">tools<\/span>\n<span class=\"hljs-selector-tag\">nuget<\/span> <span class=\"hljs-selector-tag\">pack<\/span> <span class=\"hljs-selector-tag\">YourPackage<\/span><span class=\"hljs-selector-class\">.nuspec<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Method 3: Create a package from a Visual Studio project<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">For simple project-based packaging, run commands in the folder containing the <code>.csproj<\/code> (or <code>.vbproj<\/code>) file. NuGet creates a tokenized <code>.nuspec<\/code> and replaces tokens during packing when you pack the project file.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css language-bash\"><span class=\"hljs-selector-tag\">nuget<\/span> <span class=\"hljs-selector-tag\">spec<\/span>\n<span class=\"hljs-selector-tag\">nuget<\/span> <span class=\"hljs-selector-tag\">pack<\/span> <span class=\"hljs-selector-tag\">MyProject<\/span><span class=\"hljs-selector-class\">.csproj<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Supported replacement tokens highlighted in the original article:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Token<\/th><th>Source<\/th><\/tr><\/thead><tbody><tr><td><code>$id$<\/code><\/td><td>Assembly name<\/td><\/tr><tr><td><code>$version$<\/code><\/td><td>Assembly version from assembly attributes<\/td><\/tr><tr><td><code>$author$<\/code><\/td><td>Company from assembly attributes<\/td><\/tr><tr><td><code>$description$<\/code><\/td><td>Description from assembly attributes<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">You can also include additional files through a <code>&lt;files&gt;<\/code> section in the <code>.nuspec<\/code>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml language-xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">files<\/span>&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">file<\/span> <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">\"..\\..\\SomeRoot\\**\\*.*\"<\/span> <span class=\"hljs-attr\">target<\/span>=<span class=\"hljs-string\">\"\"<\/span> \/&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">files<\/span>&gt;<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Referenced projects can be included recursively with <code>-IncludeReferencedProjects<\/code>, and build configuration can be selected with <code>-Prop<\/code>:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs language-bash\">nuget pack A.csproj -IncludeReferencedProjects\nnuget pack MyProject.csproj -Prop Configuration=Release<\/code><\/span><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Official references<\/h2>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"https:\/\/docs.nuget.org\/create\/creating-and-publishing-a-package\">https:\/\/docs.nuget.org\/create\/creating-and-publishing-a-package<\/a><\/li><li><a href=\"https:\/\/docs.nuget.org\/consume\/command-line-reference\">https:\/\/docs.nuget.org\/consume\/command-line-reference<\/a><\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Common pitfalls<\/h2>\n\n\n\n<ul class=\"wp-block-list\"><li>Packing the <code>.nuspec<\/code> instead of the project file when you expect token replacement from project metadata.<\/li><li>Using a folder layout that does not match NuGet conventions, causing files not to land where consumers expect.<\/li><li>Forgetting to review dependency versions in the generated <code>.nuspec<\/code> before publishing.<\/li><li>Mixing Debug and Release artifacts unintentionally; use <code>-Prop Configuration=Release<\/code> when needed.<\/li><li>Assuming package creation and repository hosting are the same step; package creation is separate from publishing to a feed.<\/li><\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Learn three practical ways to build NuGet packages using nuget.exe: from an existing assembly, from a convention-based folder layout, or directly from a Visual Studio project. This guide includes commands, folder conventions, token behavior, and common pitfalls.<\/p>\n","protected":false},"author":1,"featured_media":3092,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_joinchat":[],"footnotes":""},"categories":[2],"tags":[350,937,1122,545,1382,933,936,935,247,934,593,732,213],"class_list":["post-457","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorised","tag-create","tag-create-package-in-nuget","tag-guide","tag-how","tag-how-to-create-package-in-nuget","tag-nuget","tag-nuget-guide","tag-nuget-tutorial","tag-package","tag-package-in-nuget","tag-process","tag-steps","tag-tutorial"],"_links":{"self":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/457","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/comments?post=457"}],"version-history":[{"count":4,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/457\/revisions"}],"predecessor-version":[{"id":79332,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/457\/revisions\/79332"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/media\/3092"}],"wp:attachment":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/media?parent=457"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/categories?post=457"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/tags?post=457"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}