Spread some Nuget love on your apps!

In this video, I take a look at the new Nuget option we have for AppSource apps and a community contribution that enables us to use it inside Visual Studio Code. Check it out:

https://youtu.be/G2n_Dp3Mc0Q

In this video, Erik explores a exciting new capability that arrived with Business Central 2024 Wave 2 (BC25): NuGet package support for AL development. Microsoft has exported the public symbols for all 6,000+ AppSource apps and published them as NuGet packages, making it dramatically easier to resolve dependencies when building AL extensions. Erik demonstrates a community-built VS Code extension called “AL NuGet Helper” by Patrick that lets you restore these symbol packages directly into your project.

What is NuGet and Why Does It Matter?

NuGet is a package manager born out of the .NET ecosystem. In Visual Studio, developers have long been able to browse and install packages — for example, searching for PDF libraries and installing them directly into a C# project. NuGet provides a standardized way to distribute code and assets that your project depends on.

For Business Central AL developers, the challenge has always been obtaining symbol files for AppSource apps. Previously, your options were limited:

  • Install apps on a sandbox, connect VS Code to it, and download symbols from there
  • Download .app symbol files manually and commit them to your repository
  • Rely on various workarounds in CI/CD pipelines (AL-Go, AL-Ops, etc.)

There was no single, centralized public library of AppSource app symbols — until now. Microsoft has exported the public symbols from all 6,000 apps currently on AppSource and published them as NuGet packages. Every time a publisher updates their app on AppSource, the symbols are automatically extracted and updated on NuGet.

The Demo Project

Erik sets up a simple AL project that depends on several third-party AppSource apps. The HelloWorld.al file declares variables from multiple different publishers:

namespace DefaultPublisher.Nuget;

using Microsoft.Sales.Customer;

pageextension 50100 CustomerListExt extends "Customer List"
{
    trigger OnOpenPage();
    var
        WooSetup: Record "Woo Webstore Connector Setup";
        SP: Codeunit "SharePoint EFQ";
        APD: Record "APD Setup Hgd";
        AVADetailPosted: Record "AVA Detail Posted";
    begin
        Message('App published: Hello world');
    end;
}

The corresponding app.json defines dependencies on several AppSource apps from different publishers:

{
  "id": "e45ee110-3d5e-4ea9-a82a-885d6b1b168c",
  "name": "Nuget",
  "publisher": "Default Publisher",
  "version": "1.0.0.0",
  "dependencies": [
    {
      "id": "decade24-c001-1eaf-cafe-cab1ea11abba",
      "name": "Advanced Portal Designer",
      "publisher": "Hougaard",
      "version": "3.0.0.0"
    },
    {
      "id": "23ebd065-b289-4a68-85e3-b8410e360157",
      "name": "SharePoint Connector",
      "publisher": "hougaard.com",
      "version": "5.0.0.8"
    },
    {
      "id": "5fedf952-2450-4bce-b578-f3b7c13cd9a9",
      "name": "Avalara AvaTax",
      "publisher": "Avalara",
      "version": "16.0.7.2"
    },
    {
      "id": "91445282-543f-41e8-825c-a1186639bb82",
      "name": "WooCommerce Connector",
      "publisher": "Synfynal",
      "version": "23.0.0.0"
    },
    {
      "id": "8d4eab29-8c7f-4b6c-be9a-b7fdfb9da196",
      "name": "Continia Expense Management",
      "publisher": "Continia Software",
      "version": "12.2.0.333892"
    }
  ],
  "platform": "1.0.0.0",
  "application": "25.0.0.0",
  "idRanges": [
    {
      "from": 50100,
      "to": 50149
    }
  ],
  "runtime": "14.0",
  "features": [
    "NoImplicitWith"
  ]
}

Without the symbol files, the project is full of squiggly lines and errors. The .alpackages folder is completely empty. In the old workflow, you’d need a sandbox environment with all of these apps installed just to download the symbols.

The AL NuGet Helper Extension

Enter the AL NuGet Helper — a VS Code extension created by Patrick, whom Erik calls one of the “unsung heroes” of the Business Central community. While still early in development, this extension provides a streamlined way to pull NuGet symbol packages directly into your AL project.

The extension uses a NuGet downloader tool called Paket under the hood. It has one primary command: Restore. When you run it, several things happen:

Generated Files and Folders

After running the restore command, the following structure appears in your project:

  • packages/ — Contains the downloaded symbol packages
  • paket-files/ — Working files for the Paket tool
  • paket.dependencies — Defines where packages come from and resolution strategy
  • paket.lock — Lock file tracking resolved dependency versions

The paket.dependencies file contains the NuGet source URL and lists all required packages, including Microsoft Application symbols, Microsoft Platform symbols, Microsoft System Application, and all the third-party app symbols. It also specifies a dependency resolution strategy (e.g., “lowest matching”).

Transitive Dependencies

One particularly useful behavior is that the tool resolves the full dependency tree. For example, Erik only specified Continia Expense Management as a dependency, but the restore pulled in Continia Business Foundation, Continia Connector, Continia Core, Continia Delivery, Continia Document Capture, and more — because those are all dependencies of dependencies. The same happened with the Advanced Portal Designer, which depends on the AL Compiler package.

Package Structure

Each downloaded package folder contains:

  • A .rels file with relationship definitions
  • A package folder with an XML metadata file
  • A signature
  • A content folder containing the actual .app symbol file

Configuration and Version Resolution

The extension has several settings accessible through VS Code’s settings panel under Extensions → AL NuGet Helper:

  • Override Paket Dependencies — When enabled (the default), the paket.dependencies file is regenerated each time you run restore. Disable this if you want to manually customize the file.
  • Country Code — Define a specific country code for localized packages
  • Different path for the Paket file — Customize where Paket stores its files

Erik experimented with the dependency resolution strategy in the paket.dependencies file. The lowest_matching: true setting controls whether the resolver picks the lowest version that satisfies the dependency constraint or the highest available version. For his use case — wanting the latest symbols — he preferred the highest matching version.

Caching Behavior

One thing Erik discovered during testing is that Paket maintains a local cache on your machine. This means subsequent restores can complete in a fraction of a second, but it also means you may need to clear the cache (by deleting the packages folder, lock file, and potentially the global Paket cache) to force a fresh download of newer versions.

Getting the AL Language Server to Recognize Packages

After restoring packages, Erik initially still saw errors in VS Code. The AL Language Server didn’t immediately pick up the newly downloaded symbol files. A window reload (Ctrl+Shift+P → “Reload Window”) solved this — after the reload, all the symbols were recognized and the errors disappeared.

Erik notes this is a known quirk of the AL Language Server: it runs in a context that doesn’t always detect file system changes, especially when files are added or modified outside of normal editing. This is the same behavior developers experience when switching Git branches — the language server can get confused until the window is reloaded.

Practical Use Cases

Erik highlights a particularly compelling use case from his own work: building “glue apps” that integrate two third-party solutions. For example, imagine an app that connects Continia Document Capture with the SharePoint Connector, allowing you to store Continia documents in SharePoint. When building such an integration app, you need symbols from both publishers constantly. With NuGet packages, you can resolve all those dependencies instantly without maintaining a sandbox with every app installed.

Summary

Microsoft’s decision to publish all AppSource app symbols as NuGet packages is a significant step forward for the AL development ecosystem. Combined with community tools like Patrick’s AL NuGet Helper extension, it dramatically simplifies the process of resolving dependencies — whether you’re working interactively in VS Code or building CI/CD pipelines. While there are still some rough edges to smooth out (caching behavior, version resolution, language server refresh), this approach brings Business Central development closer to the mature package management experience that .NET developers have enjoyed for years. Give the AL NuGet Helper extension a try and see how it can streamline your own development workflow.