Including Static Files in a NuGet Package: A Developer's Guide

KUMAR BISHOJITKUMAR BISHOJIT
3 min read

Why Static Files in NuGet Packages?

When developing utility libraries, you'll often need to bundle static files like JSON configurations, text templates, or images. This guide demonstrates two professional approaches to include these files in your NuGet package:

  1. Embedded Resources (Files compiled into the assembly)

  2. Content Files (Files added to consumer projects)

Step 1: Project Setup (YourProject.csproj)

Base Configuration

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net9.0</TargetFramework>
    <PackageId>YourProject</PackageId>
    <Version>1.0.5</Version>
    <!-- Other metadata -->
  </PropertyGroup>
</Project>

Key Additions for Static Files

<ItemGroup>
  <!-- As Embedded Resource -->
  <EmbeddedResource Include="Phone/countries.json" />

  <!-- As Content File -->
  <None Include="Phone/countries.json" 
        Pack="True" 
        PackagePath="contentFiles/any/any/Phone/" />
</ItemGroup>

What These Do?

  • EmbeddedResource: Bakes the file into your DLL

  • None with Pack: Includes file in NuGet's contentFiles directory

Step 2: Accessing Embedded Resources

using System.Reflection;
using Newtonsoft.Json;

public class PhoneNumberOperation
{
    public List<CountryCode> CountryCodes { get; } = new();

    public PhoneNumberOperation()
    {
        var assembly = Assembly.GetExecutingAssembly();
        var resourceName = "YourProject.Phone.countries.json";

        using var stream = assembly.GetManifestResourceStream(resourceName) 
            ?? throw new FileNotFoundException($"Missing resource: {resourceName}");

        using var reader = new StreamReader(stream);
        CountryCodes = JsonConvert.DeserializeObject<List<CountryCode>>(reader.ReadToEnd())
            ?? new List<CountryCode>();
    }
}

Key Notes:

  • Resource naming follows Namespace.Folder.Filename.extension

  • Always validate null streams

  • Consider using System.Text.Json for modern .NET projects

Step 3: Understanding Content Files

When consumers install your package, files in contentFiles will appear in their project under:

Project/
└── Phone/
    └── countries.json

Consumer Control:

  • Files can be marked as Copy Always/Never

  • Build action can be modified

Step 4: Package Verification

  1. Build your package:

     dotnet pack --configuration Release
    
  2. Inspect using:

    • NuGet Package Explorer (GUI tool)

    • Manual inspection by renaming .nupkg.zip

Expected Structure:

├── lib
│   └── net9.0
│       └── YourProject.dll
└── contentFiles
    └── any
        └── any
            └── Phone
                └── countries.json

Pro Tips & Troubleshooting

  1. Double-Check Resource Names

     var resources = assembly.GetManifestResourceNames();
     Console.WriteLine(string.Join("\n", resources));
    
  2. ContentFiles Not Appearing?

    • Ensure the consumer's project SDK is Microsoft.NET.Sdk

    • Verify <IncludeContentInPack>true</IncludeContentInPack>

  3. When to Use Which Method

    | Embedded Resources | Content Files | | --- | --- | | Internal configs | User-editable files | | Critical data | Example templates | | Small files | Larger assets |

Complete Project File Reference

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net9.0</TargetFramework>
    <!-- Package Metadata -->
    <PackageId>YourProject</PackageId>
    <PackageReadmeFile>README.md</PackageReadmeFile>
  </PropertyGroup>

  <ItemGroup>
    <!-- Dependencies -->
    <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
  </ItemGroup>

  <ItemGroup>
    <!-- Static Files -->
    <EmbeddedResource Include="Phone/countries.json" />
    <None Include="Phone/countries.json" 
          Pack="True" 
          PackagePath="contentFiles/any/any/Phone/" />
    <None Include="README.md" Pack="True" PackagePath="/" />
  </ItemGroup>
</Project>

Conclusion:

Including static files like JSON or text resources in NuGet packages elevates your library’s utility and flexibility. By leveraging embedded resources, you ensure critical files remain secure and directly accessible within your assembly. Meanwhile, content files empower consumers to customize configurations or reference external assets in their projects.

Always verify your package structure post-build and test consumption scenarios thoroughly. Whether you’re distributing localization files, templates, or configuration data, these techniques ensure your NuGet package delivers a polished, professional experience.

Empower your libraries—static files are no longer static limitations, but dynamic tools!

CONTACT:

I’m Kumar Bishojit Paul, the Founder and CEO of BIKIRAN. If you need further assistance, please leave a comment. I’m interested in helping you.

Got questions? Drop a comment below or reach out at contact@bikiran.com. Happy packaging!

0
Subscribe to my newsletter

Read articles from KUMAR BISHOJIT directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

KUMAR BISHOJIT
KUMAR BISHOJIT