skip to content
Khalid Abuhakmeh logo Khalid Abuhakmeh

LibMan: Manage Client-Side Libraries With libman.json

LibMan (libman.json) manages client-side JavaScript libraries in ASP.NET Core without Node. Install the CLI, run libman init/install, and restore on build.

6 min read Updated

LibMan manages client-side JavaScript and CSS libraries from a single libman.json file, with no Node or NPM required. Run libman init to create the file, libman install htmx to add a library, and libman restore to download everything listed in it. This post covers what goes into libman.json and how to use the LibMan CLI in your ASP.NET Core projects.

Updated November 2026. The libman.json file is the manifest LibMan reads to know which libraries to download and where to put them.

I’ve recently spent a lot of time with my newest obsession, HTMX, and it’s seriously great. However, a challenge I face frequently is how to manage JavaScript dependencies in my ASP.NET Core applications. There’s NPM, Yarn, Gulp, Grunt, Webpack, Parcel, Rollup, and likely a hundred more package managers. Each option comes with its strengths and frustrating headaches. Luckily for HTMX users like me (I’ve also written about HTMX boosts and ASP.NET Core anti-forgery tokens), the library ships ready to use without the need to transpile to a final form. In a sense, I could link directly to the artifacts and call it a day, with the glaring disadvantage of updating my HTML with every new release.

I decided to ask Twitter what options folks were using, and many pointed me to LibMan. LibMan works off a single libman.json file in your project, so this post will explore what LibMan is, what goes into libman.json, and how you can use the CLI in your ASP.NET Core projects to manage JavaScript dependencies.

What Is Libman?

Short for Library Manager, Libman is a lightweight tool designed explicitly for client-side library acquisition. Client-side libraries are typically ready to be used by a client, and some examples include Bootstrap.js, JQuery, Vue, d3, and HTMX. Libman also supports some of the more popular CDNs that can host JavaScript libraries: CDNJS, jsDelivr, and unpkg. LibMan will retrieve specified libraries and place them in a target location. The tool is for developers who work with final assets and don’t need a build pipeline.

To be clear, LibMan is not a package management system like NPM or Yarn, and it doesn’t have the same facilities as WebPack, Rollup, or Parcel. As a result, it cannot replace those tools but offers folks a more straightforward choice.

Installing LibMan

To get started with LibMan, you’ll first need .NET installed. Once the SDK is installed and the dotnet CLI is available, you can run the following command in a terminal. Note, you can only install LibMan globally. Local installs (without -g) will fail..

Terminal window
dotnet tool install -g Microsoft.Web.LibraryManager.Cli

Once you’ve installed the tool, you can test that it’s installed correctly and accessible by typing the following.

Terminal window
libman --version

Now you should be ready to start using LibMan in your ASP.NET Core projects.

LibMan and ASP.NET Core projects

You’ll need to start with an ASP.NET Core application with a wwwroot folder. Typically you’ll have a public content directory with folders for css, js, and lib. Where your assets go isn’t essential, but typically external assets are placed in the lib folder under wwwroot.

You’ll want to run the following command from the root of the web project to initialize LibMan.

Terminal window
libman init

You can change the DefaultProvider value from cdnjs to either unpkg or jsDelivr. We’ll also be able to specify the provider when adding libraries. After running libman init, you should see a new libman.json file.

{
"version": "1.0",
"defaultProvider": "cdnjs",
"libraries": []
}

You’ll notice the libraries array is empty. So let’s add a new asset! Type the following command into your terminal, still being at the root of your web project.

Terminal window
libman install htmx

LibMan will ask you where you’d like to place the assets; by default, it will be wwwroot/lib/<library name>. Feel free to change the target or hit enter.

Terminal window
➜ libman install htmx
Destination [wwwroot/lib/htmx]:
wwwroot/lib/htmx/htmx.js written to disk
wwwroot/lib/htmx/htmx.min.js written to disk
wwwroot/lib/htmx/htmx.esm.js written to disk
Installed library "htmx.org@2.0.4" to "wwwroot/lib/htmx"

(In htmx 1.x, this command also pulled down a large ext/ folder of bundled extensions. As of htmx 2.x, extensions ship as separate packages, so a core install writes just the main htmx files — install any extension you need as its own library.)

After the installation, LibMan will update our libman.json file with the installed library.

{
"version": "1.0",
"defaultProvider": "cdnjs",
"libraries": [
{
"library": "htmx.org@2.0.4",
"destination": "wwwroot/lib/htmx"
}
]
}

Now we can serve these assets when and where we need them. Great! When newer versions of a library are released, we can use the update command to fetch the latest version.

Terminal window
libman update htmx

Great! Most folks can stop here, but you can check out the next section if you don’t want to check-in assets into source control.

Restore Assets on Build with LibMan

I recommend checking in the JavaScript library asset files into source control, but I can see why folks wouldn’t want to do that. It can be a lot of additional noise to see all those JavaScript files in a pull request. I’m happy to tell those folks there’s a package for that for folks who would like to resolve assets at build time!

Install the following NuGet Package as part of your web project.

Terminal window
dotnet add package Microsoft.Web.LibraryManager.Build

Once installed, you should see the following message in your build output (between all the other build messages).

Terminal window
1 libraries restored in 0.2 seconds

If you’re concerned about restorations being slow, don’t be. Restores are loaded and cached on your local machine. Caching should help keep your local and remote builds feeling snappy with limited overhead.

Frequently Asked Questions

What is libman.json?

libman.json is the manifest file LibMan uses to track client-side libraries. It lives at the root of your web project and contains a version, a defaultProvider (cdnjs, jsDelivr, or unpkg), and a libraries array. Each library entry names the library and version plus the destination folder it’s written to.

Does LibMan require Node or NPM?

No. LibMan fetches ready-to-use client-side libraries from CDNs like cdnjs, jsDelivr, and unpkg, and only needs the .NET SDK. There’s no Node toolchain, package.json, or build pipeline involved.

How do I restore LibMan libraries on build?

Add the Microsoft.Web.LibraryManager.Build NuGet package to your web project with dotnet add package Microsoft.Web.LibraryManager.Build. Every build then restores the libraries listed in libman.json, and you’ll see a message like 1 libraries restored in the build output. You can also run libman restore manually.

Where does LibMan put installed files?

By default, LibMan writes files to wwwroot/lib/<library name>. You can change the location when prompted during libman install, or edit the destination value for a library in libman.json.

Conclusion

LibMan is an excellent alternative for folks trying to avoid the complexity of the Node ecosystem. You can keep all your client-side libraries up to date with a few commands. LibMan is perfect for me, and it all just works. Let me know if you use LibMan and what your experience has been. As always, thank you for reading, and I hope you learned something new.

References

Comments

Related Posts