Search icon CANCEL
Cart icon
Close icon
You have no products in your basket yet
Save more on your purchases!
Savings automatically calculated. No voucher code required
Arrow left icon
All Products
Best Sellers
New Releases
Learning Hub
Free Learning
Arrow right icon
Mastering Microsoft Dynamics 365 Business Central - Second Edition
Mastering Microsoft Dynamics 365 Business Central - Second Edition

Mastering Microsoft Dynamics 365 Business Central: The complete guide for designing and integrating advanced Business Central solutions, Second Edition

$39.99 $27.98
Free Trial
Renews at $15.99p/m

What do you get with eBook?

Product feature icon Instant access to your Digital eBook purchase
Product feature icon Download this book in EPUB and PDF formats
Product feature icon AI Assistant (beta) to help accelerate your learning
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
Table of content icon View table of contents Preview book icon Preview Book

Mastering Microsoft Dynamics 365 Business Central - Second Edition

Mastering a Modern Development Environment

In the previous chapter, we introduced Dynamics 365 Business Central and the amazing momentum that its online version is enjoying.

In this chapter, we will take a close look at the development environment. We will discuss the main shortcuts, tips, and tricks related to Visual Studio Code, the official development platform, and the AL Language extension, the development language extension. The union between Visual Studio Code and AL defines the so-called modern development environment.

AL Language is the official Visual Studio Code extension provided by Microsoft, free of charge, through the online marketplace. AL stands for Application Language, although it’s typically referred to as AL Language. Officially released for the first time back in 2017 to extend what was then called Dynamics 365 for Financials (formerly Project Madeira), it is now a solid, fully fledged development language that extends Dynamics 365 Business Central. It comes equipped with a lot of features that greatly enhance developers’ productivity and coding quality.

The main goal of this chapter is to help Dynamics 365 Business Central developers understand what the development platform offers, unleash their potential, and become proficient in their daily coding activities.

In this chapter, you will learn about the following:

  • What the Visual Studio Code user interface is composed of, and the purpose of each section
  • How to be proficient in using the most powerful Visual Studio Code editing features
  • What the AL Language extension is and what it consists of
  • Turning on code analyzers to check and enforce encoding rules
  • Enabling GitHub Copilot to accelerate the writing of code

The Visual Studio Code user interface

Visual Studio Code is one of the most widely used development environments worldwide. It is engineered to make it easy and quick to design cloud- and web-based applications, using a vast plethora of extensible languages. The application is focused on maximizing code editing and unleashing the developer’s potential by providing useful shortcuts to provide quick access to all that is needed in a specific development context.

Visual Studio Code can be downloaded officially at and, like most Integrated Development Environments (IDEs) nowadays, it has two different branches or deployment channels for its build: stable and insider. Together with these, it could also be used as a web application ( or deployed on different platforms than Microsoft Windows, like iOS or Linux.

When you start Visual Studio Code, freshly installed locally, it will show you the typical Welcome page:

A screenshot of a computer

Description automatically generated

Figure 2.1: Visual Studio Code Welcome page

The Welcome page contains the following:

  • Start: Shortcuts for creating and opening files and folders
  • Recent: A list of recently opened files and folders
  • Walkthroughs: A series of sliders that would help you tailor Visual Studio Code through your favorite settings such as background color themes, useful features enablement, and so on

The Welcome page is loaded whenever you run Visual Studio Code as a new window (Ctrl + Shift + N). It is possible to change this behavior by unchecking Show welcome page on startup or clicking File | Preferences | Settings and searching for Welcome page.

The Visual Studio Code environment is divided into five main areas:

  • Code editor
  • Status bar
  • Activity bar
  • Sidebar
  • Panels area

Let’s look at each of them in the following sections, but if you want to check the documentation reference first, please visit

Code editor

The code editor is where you write your code and where you spend most of your time. It is activated when creating a new file, or when opening an existing file or folder.

You can edit just one single file, or you can even load and work with multiple files at the same time, side by side, in editor groups:

A screenshot of a computer

Description automatically generated with medium confidence

Figure 2.2: Working on multiple files with editor groups

There are different ways to have multiple file views; three are mentioned here:

  • Select a filename in the EXPLORER bar, then right-click and select Open to the Side (Ctrl + Enter).
  • Press Ctrl + click on a filename in the EXPLORER bar.
  • Press Ctrl + \ to split the editor into two parts.

Editor groups will accommodate several files, dividing the space equally between them. You can move through the different file editors by simply pressing Ctrl + 1, Ctrl + 2, Ctrl + 3, …, Ctrl + N.

Editor windows can be resized, reordered, and zoomed in/out according to your needs. To zoom in/out, press Ctrl + +/Ctrl + -, or View | Zoom in/Zoom out.

Zooming applies to all Visual Studio Code areas, not only to the code editor.

Visual Studio Code also provides an easy way of navigating between files with shortcuts. The quickest way is to press Ctrl + Tab. This will open the list of files that have been opened since Visual Studio Code started.

Last but not least, Ctrl + R could be considered the most used one. This will open a list of the recent files opened in the Command Palette.

Status bar

The status bar typically contains information about the currently selected file or folder. It also provides some actionable shortcuts:

Figure 2.3: Status bar shortcuts

From left to right, the status bar contains the following information:

  • If Git is enabled, it will report version control information, such as, for example, the current branch.
  • Number of errors and/or warnings detected in the current code.
  • Cursor position (line position and column position).
  • Indentation size and type (spaces or tabs).
  • Encoding of the currently selected file.
  • Line terminator: Carriage return (CR) and/or line feed (LF).
  • Language used to process the code in the selected file. If you click on the language, a menu list will appear, and you should be able to change the processing programming language.
  • Feedback button, which you can use to share your feedback about Visual Studio Code on Twitter/X or open a bug or feature implementation request.
  • Notification icon: This shows the number of new notifications, which are typically related to product updates.

The status bar has a conventional colorization, and it changes depending on what’s processing. For example, it is purple when opening a new window or a new file, blue when opening a folder, orange when debugging, and so on.

Activity bar

This is on the left side of the workspace and contains shortcuts to the sidebar. If a shortcut is clicked, the sidebar that belongs to the tool that has been chosen becomes visible. Clicking again, or – for the shortcut lovers – pressing Ctrl + B, makes it disappear.


The Manage button is shown with a gear icon at the very bottom of the activity bar. If you click on it, a pop-up menu with a list of commands appears. These commands are used to tailor and customize Visual Studio Code at will, or to search for updates.

Command Palette

The Command Palette is one of the most important tools in Visual Studio Code. Its purpose is to give quick access to standard and extended commands. There are different ways to run the Command Palette:

  • F1 (most used by all developers)
  • Keyboard shortcut: Ctrl + Shift + P
  • View | Command Palette
  • The Manage button (the gear icon) | Command Palette

The Command Palette is not only good for showing menu commands but it can also perform other actions, such as installing extensions. You can browse through it to review the huge list of available commands. Commands are indexed and searchable. Just type a few letters to get a filtered list. It’s worth mentioning the long list of keyboard shortcuts that are available for most of these commands.

One very important thing to know about the Command Palette is the use of the > sign. When you press Ctrl + Shift + P, the Command Palette pops up with the > sign and shows the list of commands available. Take a look at the following screenshot:

Figure 2.4: Commands suggested by the Command Palette

If you remove the > symbol, Visual Studio Code uses the Command Palette to show a list of the recently opened files. The following screenshot shows this:

Figure 2.5: Recent files in the Command Palette

The power of this feature is that, without using the mouse, you can open the Command Palette, run a command, remove the > character, and select a file to edit (which is equivalent to using the shortcut Ctrl + P). That’s fantastic for development productivity.


The sidebar is the place where you will interact the most with the code editor. It is context-sensitive, and you will find five standard activities, each enabled by the corresponding icon in the view bar.

EXPLORER (Ctrl + Shift + E)

EXPLORER provides a structured and organized view of the folder and files that you are currently working with. The OPEN EDITORS sub-view contains the list of active files in the code editor. Below this section, there is another sub-view with the name of the folder that is open:

Figure 2.6: OPEN EDITORS sub-view

If you hover over the OPEN EDITORS sub-view, four action buttons will be shown: New (Ctrl + N), Toggle Vertical/Horizontal Editor Layout (Shift + Alt + O), Save All (Ctrl + K + S), and Close All Files (Ctrl + K or Ctrl + W):

Figure 2.7: OPEN EDITORS actions

Hovering over the folder name or any part of the sidebar (in this example, PACKTDEMOEXTENSION) will make four action buttons visible:

Figure 2.8: Example folder action buttons

From left to right, these are New File, New Folder, Refresh, and Collapse All.

Right-clicking on a folder or filename will open a context menu that shows common commands such as Reveal in Explorer (Shift + Alt + R), which opens the folder that contains the selected file. You can also copy the file path via Copy Path (Shift + Alt + C).

When you start working with it, you might not like the OPEN EDITORS area, especially when you are in the middle of heavy development, since this takes up quite a lot of your screen when you have lots of files open at the same time. You can easily disable Open Editors to get that space back by clicking on the EXPLORER bar ellipsis and unchecking Open Editors.

Further down in the EXPLORER bar, there is another section called OUTLINE. It gives a very useful tree view of members and types for a specific file, based on its language extension. If you have AL Language already installed, you might have this enabled. Take a look at the following screenshot:

Figure 2.9: OUTLINE tree view

This is a proficient option when you are developing complex objects and you want to jump into a specific area with just one click.

SEARCH (Ctrl + Shift + F)

This is a powerful tool for searching for and replacing text in files. It is possible to opt for a simple search with one or more keywords, and you can use wildcards such as * and ?. Alternatively, you can opt for creating a complex search based on regular expressions (regexes). There are also advanced options to include and/or exclude files or file types.

If you would like to learn more about regexes in Visual Studio Code, the following video is a must-watch, 20230320 - RegEx - basic and advanced scenarios:

The SEARCH action bar is helpful for developers when searching the Where used field or variables in all files within an extension folder. Take a look at the following screenshot:

Figure 2.10: Searching extension files

Search outputs are listed in a tree view that lists all files containing the search keyword and shows a small piece of code related to the line that they belong to in the file. The keyword match is highlighted in the tree-view, as well as within the code editor. These can all be collapsed by clicking the Collapse All button.

It is possible to reset the search results by clicking the Clear Search Results button. It is also possible to turn sensitivity on/off and switch to regex view.

SOURCE CONTROL (Ctrl + Shift + G)

Visual Studio Code provides native integration with one of the most widely known source control management systems: Git. The basics and integration of Git will be discussed in Chapter 15, DevOps for Business Central.

DEBUG (Ctrl + Shift + D)

Visual Studio Code is not just a code editor for editing flat files. It also ships with an out-of-the-box integrated debugger framework that can be extended to debug different platforms and languages.

Visual Studio Code does not provide any debugging capability for Dynamics 365 Business Central per se. This comes embedded in the AL Language extension for Visual Studio Code, which extends the existing .NET core debugger. In Chapter 10, Debugging, we will discuss this argument in great detail.

EXTENSIONS (Ctrl + Shift + X)

The EXTENSIONS sidebar is used to browse the online marketplace for extensions for Visual Studio Code, which includes an ever-growing number of additional languages, debuggers, tools, helpers, and much more. AL Language is an extension for Visual Studio Code developed, maintained, and published by Microsoft. In the Visual Studio Code marketplace, you can also download several helpful extensions that extend (extensions for an extension) the AL Language extension and help Dynamics 365 Business Central developers be more efficient and productive and write code professionally and more proficiently. Take a look at the following screenshot, which shows typical Visual Studio Code extensions installed for Dynamics 365 Business Central:

Figure 2.11: Extensions in Business Central

In the EXTENSIONS bar, it is possible to search the online marketplace or install an extension manually. You can also see the list of installed, outdated, recommended, and disabled extensions and sort them according to different criteria.

Some extension packages are meant to download and install a set of extensions. With Dynamics 365 Business Central, you might think of downloading and installing AL Extension Pack from or SD Extension Pack for Dynamics 365 Business Central from

It is also possible to perform actions on a single extension by right-clicking on it. An extension can be enabled, disabled, disabled per workspace (a workspace could be a project or a folder), and so on. There are also a couple of cool features related to Visual Studio Code extension deployments that are worth mentioning. The first is the ability to install another version of the extension (for example, click on the gear icon in the AL Language extension and choose Install Another Version…):

Figure 2.12: Installing extension versions

The second is the ability to deploy a pre-release instead of the official version. See below the button to deploy the pre-release for the AL Language extension:

Figure 2.13: Deploying a pre-release

This is very useful for Dynamics 365 Business Central developers, in case there are regression behaviors or bugs in higher-AL Language extension versions or the official release version. This is also useful when developments target a specific platform version.

Panels area

Visual Studio Code not only shows detailed analysis and information related to your code but also has access and display information coming from other sources such as Git, installed extensions, and debuggers. These outputs are logged into the Panels area, which, by default, is at the bottom, but could be easily moved to one side of the workspace using the Move Panel Right button, enabled by right-clicking on the panel’s title bar. It is possible to restore the original layout with the Move Panel to Bottom button, or even Hide Panel (Ctrl + J).

The Panels area is not visible by default. It is typically enabled and shown when the information needed is requested, such as when the debugger is enabled.

In the Panels area, there are four different windows (even though some extensions might add their own panels, such as GitLens): PROBLEMS, OUTPUT, DEBUG CONSOLE, and TERMINAL. Let’s examine them in the following sections.


With extension languages that have advanced editing features, such as AL, Visual Studio Code is able to identify code problems while typing. Problem lines have a specific colorization. There are three types of notifications: errors, warnings, and info. All of them can be shown in the PROBLEMS window. The following screenshot shows an example of the PROBLEMS window showing 4 errors and 3 warnings:

Figure 2.14: PROBLEMS window warnings

Typically, blocking errors are shown in red, while warnings are marked in yellow. Clicking any problem will open the file where the problem occurs, and the code that causes the problem will then be marked with a squiggly line in the problem color.


The OUTPUT panel is the place where Visual Studio Code typically displays messages during or after command execution.

Because built-in tool actions and multiple extension commands can run concurrently, it is possible to make use of a drop-down box in the OUTPUT panel to change the view and see the output for each standard or extension-based command.

The following screenshot shows the OUTPUT window in the Panels area:

Figure 2.15: OUTPUT window messages

When working with Dynamics 365 Business Central extensions, the AL Language output window is selected automatically.


This is a special window used by native and extension-based debuggers, such as the AL language debugger, to display information about code execution. This window and its output will be analyzed in detail in Chapter 10, Debugging.


Visual Studio Code allows us to execute commands in the same way as Command Prompt, directly from within the development environment. The Terminal session is based on PowerShell by default.

Now that we have all the elements that are related to Visual Studio Code in place, we can move on to the next section and deep-dive into the powerful editing features that it offers.

Visual Studio Code – the editing features

Visual Studio Code provides many of the features that you would expect from the best-in-class code editor. If you are familiar with Visual Studio, you might have noticed that some features have been engineered in a similar way.

Developed by developers for developers, Visual Studio Code has keyboard shortcuts for almost every editing command, giving you the option to edit code faster and completely forget about the mouse. Let’s study the most used features in the following sections.

Comment lines

Visual Studio Code provides out-of-the-box commands for text selection and professional editing in the Edit menu. The Edit menu also includes Toggle Line Comment, which adds a line comment for the selected line. This means that if you select 10 lines of code, Visual Studio Code will comment out the selected lines. The beauty of this command is that it works in reverse as well. If you select the 10 commented lines and press Toggle Line Comment, the comments will be magically removed. It is also possible to select Toggle Block Comment and revert this back (Shift + Alt + A).

For developers working with CSIDE, the old legacy language for on-premises Dynamics 365 Business Central, this command is the equivalent of Comment Selection (Shift + Ctrl + K) and Uncomment Selection (Shift + Ctrl + O).

Delimiter matching

Visual Studio Code can detect pairs of delimiters, such as brackets and parentheses. This feature is helpful if you want to delimit code blocks, and it kicks in when the mouse is placed near one of the delimiter pairs:

Figure 2.16: Delimiter brackets

Thanks to this feature, we can easily see that the brackets on lines 9 and 11 are matching. This is a simple example, but when working with code that uses multiple parentheses, it can be a helpful quality-of-life feature to quickly see which bracket corresponds to which.

Text selection

The Selection menu also has commands that relate to text selection, but most of them are used to move or duplicate lines of code above and below the selected line.

If you position the cursor near an AL function, variable, or constant, you can use Add Next Occurrence (Ctrl+ D), Add Previous Occurrence, or Select All Occurrences (Shift+ Ctrl+ D) to select occurrences of the selected item, and occurrences will be highlighted in a different color.

Code block folding

If you hover over line numbers in the code editor, a downward-pointing arrow will appear close to the initial part of a code block. Click on it to fold it, and a right arrow will appear. Click on this, and the code block unfolds:

Figure 2.17: Folded code on lines 5 and 18

The preceding screenshot shows two folded code blocks, depicted with right arrows.

Multiple cursors (or multi-cursors)

Each cursor operates independently. Alt + click will generate a secondary cursor at the desired position.

The most common development situation in which you want to go for multiple cursors is when you need to add or replace the same text in different positions but within the same source file. The following screenshot shows three cursors in action when editing the AL Language DataClassification property:

Figure 2.18: Multi-cursors on lines 10, 15, and 20

This is a great feature for AL language developers, especially when they have to write down the same sentence many times in the same place (for example, Caption or DataClassification in a table object and for each table field).


Sometimes, when working with very long files such as report definition language (RDL) files or codeunits, it is difficult to know where the pointer should be positioned – or is positioned – within a source file. Visual Studio Code has a fully fledged mini-map feature: a small preview of the source code file. The following is an example of an RDL:

Figure 2.19: Mini-map for an RDL file

The mini-map feature can be disabled/enabled through View | Appearance | Minimap, or by running the Command Palette (F1) and selecting View: Toggle Minimap.


The Show Breadcrumbs command is available by clicking View | Appearance | Breadcrumbs or via the Command Palette (F1) and selecting View: Toggle Breadcrumbs. With AL files, you can click each element of the breadcrumb to inspect and explore the levels in the current object. There is a bit of text in the top-left corner of the code editor that can be expanded to easily double-check the definitions of properties, functions, fields, keys, and so on. If you click on an element in the expanded list, the cursor will jump to its primary definition, making code navigation quite fast and productive.

Figure 2.20: Viewing breadcrurmb elements


In visual editors, IntelliSense is a word completion tool that appears as a pop-up list while you type. Visual Studio Code IntelliSense can provide smart suggestions, showing the definition and purpose – like online help – related to a specific element. The following screenshot shows IntelliSense in action:

Figure 2.21: IntelliSense word completion

IntelliSense is context-sensitive, and if you need to enable it directly without typing anything, just press Ctrl + spacebar. Depending on the context where the cursor is placed, IntelliSense will show all the items that can be used in that context. For example, inside a Table Field declaration, it will list all the specific field properties, such as Caption and CaptionML, while in an empty codeunit definition, it will show all the properties that are exposed by a codeunit object.

Word completion

Through the IntelliSense feature, the code editor in Visual Studio Code implements word completion for all native (such as JSON) and extension-based supported languages (such as AL). Just press Enter or Tab to insert the suggested word.

Go to definition

This is a super-cool, must-know feature. You can hover over a variable, constant, function, or whatever code element you want with the mouse, and if you press Ctrl, the word or identifier (known also as a symbol) will magically switch into a hyperlink.

If you click on the word while pressing Ctrl, you will be automatically redirected to the code that defines that word. Pressing Ctrl + hovering over a code element also enables the Go To Definition feature.

Other possible ways to enable this feature are as follows:

  • Select a code element and press F12.
  • Right-click on a code element and then select Go To Definition from the context menu.

Find all references

Find All References makes it very easy to parse how many times and where an object, a function, or any code element has been used across source code. You can simply right-click on any variable, function, or element name and then select Find All References, or use the keyboard shortcut Shift + Alt + F12.

When it’s enabled, the code editor will create a result list in the activity bar showing how many times it has been referenced, and in which object files and position(s). A shortcut icon is created in the sidebar called References. The following screenshot shows how to find all references in AL files for a specific variable:

Figure 2.22: Finding multiple referenes in source code

If you expand an occurrence in the references list on the left and click on a record, the code editor will open the file where it is referenced and position the cursor in editing mode, selecting the element searched in that file.

The references list can be cleared and refreshed, and you can collapse all the elements in it. If you clear the list, you can always run the previous search again, since the history is maintained for you.

Peek definition

Imagine that you have a large number of code files, and you need to edit the definition of a variable or field that you are currently using. With many other editors – or development environments – you most likely have to save all the files in text format, then search through all these code files and be sure to replace that variable name. This task not only can be annoying but can also distract you from the original code you were writing.

Visual Studio Code brilliantly solves this problem by providing the Peek feature, which can be enabled in different ways:

  • Right-click a variable, field, or function name and select Peek Definition.
  • Use the Alt + F12 keyboard shortcut.

An interactive pop-up window should appear, showing the source code that defines the selected element.

Figure 2.23: Using the Peek feature to locate a definition

The above screenshot shows the Peek Definition for a table source, bound to a dataitem element in a report. You can then see what has been written and directly edit it.

Renaming symbols

For a developer, it is very common to rename a variable, constant, field, or function. These coding elements are technically called symbols. Visual Studio Code provides a very powerful feature to rename symbols.

If you press F2 on the coding element that you wish to rename, or right-click and then select Rename Symbol, a small interactive popup appears in edit mode. There, you can write the new element name without using a distracting dialog window, allowing you to concentrate on your coding. All references to that code element will be renamed accordingly. The following screenshot shows renaming a procedure symbol reference:

Figure 2.24: Renaming a symbol

All the features shown so far are the most useful features provided by Visual Studio Code that support proficient code editing for AL developers. At this stage, then, it is important to take a closer look at the AL Language extension and see how to configure it to achieve more from the development environment.

Understanding the AL Language extension

AL is now a cross-platform language that is deployed through an extension for Visual Studio Code. This extension not only supports deployment on Windows OSs but is also supported for the macOS version of Visual Studio Code, and recently, it is also supported on Linux.

The free AL Language extension is available for download from the Visual Studio Code marketplace ( This provides an optimized experience for Dynamics 365 Business Central extension development and includes all the support and tools that you need to build apps, including the debugger.

You might also want to install other extensions that add more languages (such as PowerShell), tools (such as Docker), or enhanced editing features to the AL Language extension. A list of the most useful marketplace extensions used by Dynamics 365 Business Central in combination with AL Language will be provided in Chapter 17, Useful and Proficient Tools for AL Developers.

AL Language

Created by the Dynamics 365 Business Central modern development team, AL Language is the official Visual Studio Code extension for developing apps for small, single-tenant personalization and complex add-on vertical solutions that are deployed through the online Dynamics 365 Business Central AppSource marketplace.

The AL Language extension can be deployed in two different ways:

  • Directly, as a downloadable package from the Visual Studio Code marketplace
  • Manually, as an installable package (a file with a .vsix extension)

The manual way is only used when a specific version for a specific implementation is needed.

To start directly with AL Language, download it from the marketplace by following these simple steps:

  1. Run Visual Studio Code.
  2. Click on the Extensions view bar.
  3. In the search field, type Dynamics 365 Business Central.
  4. Select AL Language extension for Microsoft Dynamics 365 Business Central.
  5. Click on Install, and when the installation finishes, reload Visual Studio Code as requested. It shows the following AL Language extension:

Figure 2.25: AL Language extension

By hovering over the extension, a more verbose pop-up pane should appear with more info:

Figure 2.26: AL Language extension description

The AL Language build number, also known as the development build, is shown close to the title. In the preceding screenshot, the AL Language development build (or runtime) version is 12.1.887908.

The development build is very important because new language features and enhancements are typically not backported to older builds, so they could be outdated and not compatible with the more recent Dynamics 365 Business Central platform updates.

AL developers should always select the latest AL Language development build to benefit from the latest enhancements and stability features.

Right after installing the AL Language extension from scratch, the AL Home page is displayed. This page contains tips for getting started with AL development and, most importantly, feeds from the Microsoft product group on what’s new, announcements, or development best practices. See below for what it might look like:

Figure 2.27: AL Home page

Unchecking Show at startup will turn off popping up the AL Home page every time you start a new instance of Visual Studio Code or reload Windows. It is possible to completely turn this off or simply have it shown only when there are updates in the feed section. We will see how to configure it later in this chapter. In any case, you could always run AL Home from the Command Palette (F1) by using the command AL: Home.

The AL Language development model relates to creating, editing, and organizing flat text files with the typical .al extension. In short, AL Language development is simply folder- and file-based.

It’s worth mentioning that the Visual Studio Code terminology calls a root folder a workspace. The AL Language root folder represents the source code container for an extension. Therefore, the AL Language root folder is also called the Visual Studio Code development workspace. Keep in mind that this is completely different from a code-workspace file.

When creating whatever kind of AL extension, the workspace consists of the following items:

  • A launch.json file
  • An app.json file
  • Symbol files
  • .al object files (such as table, page, report, and codeunit)
  • Complementary files (such as the extension logo in .bmp format, translation .xlf files, and so on)

We will analyze AL Language objects and complementary files in more depth in later chapters. We will focus now on the backbone of the app development: launch.json, app.json, and symbol files.


This file is stored in the extension’s workspace in a subfolder called .vscode and mainly determines the specific parameter settings – a sort of connection string – for downloading and uploading AL Language commands.

The following table shows the download and upload AL commands:

Download commands

Upload commands

AL: Download symbols

AL: Publish (F5)

AL: Download source code (F7)

AL: Publish and open in the designer (F6)

AL: Publish without debugging (Ctrl + F5)

AL: Rapid application publish (Alt + F5)

AL: Rapid application publish without debugging (Ctrl + Alt + F5)

Table 2.1: AL commands for downloading and uploading

It is also used just to establish a connection and download symbols at will, as in the case of the AL: Debug without publishing (Ctrl + Shift + F5) command, or to launch a specific debugging feature such as, for example, AL: Open Events Recorder.

The launch.json file is a JSON object, and one of its elements is a JSON array that might have different JSON values, each representing a set of attributes targeting different deployments: on-premises or SaaS. Attributes could be mandatory or optional, depending on the target deployment.

The following table shows the launch.json attributes:

Attribute: Description

Deployment type

name: Shown also in the debugger window, this is used to identify the set of launch parameters. Default values: "Your own server" (on-premises), "Microsoft cloud sandbox" (SaaS).


type: Constant value: al.


request: Default value: "launch". For debugging purposes, it could also be "attach" (to a specific session) or "initializeSnapshot" (when initializing a snapshot debugger session). Both will be covered in detail in Chapter 10, Debugging.


startupObjectType: Object type to run after publishing: "Page", "Query", "Report", or "Table".


startupObjectId: Used together with StartupObjectType. Defines the object ID to run.


tenant: AAD tenant (SaaS) or tenant name (on-premises) to connect to extract symbols and/or publish the extension package.


environmentType: "OnPrem", "Production", or "Sandbox".


environmentName: Name of the environment to which to connect.


startupCompany: This is the company that should be accessed right after publishing.


breakOnError: Specifies whether the debugger should stop when an error occurs. It is also possible to exclude try functions ("ExcludeTry").


breakOnErrorWrite: Specifies whether the debugger should stop on record changes (insert, modify, and delete). It is also possible to exclude temporary records ("ExcludeTemporary").


schemaUpdateMode: Determines the data synchronization mode. Possible values are:

  • "Synchronize": This is the default value. If there is already data deployed for this extension, it will be preserved and not removed. The extension metadata will be synchronized with the existing one, if any.
  • "Recreate": Wipes out previous metadata (tables and table extensions, typically) and uses the new metadata from scratch.
  • "ForceSync": Forces the schema synchronization. This should be used with extreme caution since it might lead to data loss scenarios.


dependencyPublishingOption: This applies in complex scenarios where multiple dependent apps are loaded from the same root folder. Possible values are:

  • "Default": Enables rebuilding and publishing all dependent apps.
  • "Ignore": Does not apply dependency publishing. This option should be used quite carefully since it risks breaking existing interdependent apps.
  • "Strict": Publishing will fail if there are any installed extensions that have a dependency on the root folder.


server: Dynamics 365 Business Central Server URL.


serverInstance: Dynamics 365 Business Central Server service name.


authentication: "Windows", "UserPassword", or "AAD".


primaryTenantDomain: This is mandatory only with AAD authentication for on-premises deployments. It is the URL of the AAD.


port: Dynamics 365 Business Central development port number.


applicationFamily: Used to develop an embedded extension for AppSource. This is a tag for Microsoft to determine the targeted upgrade operation if specific AppSource extensions have been deployed in the tenant.


launchBrowser: Specifies whether to launch a browser when publishing extensions.


enableLongRunningSqlStatements: Enables the capability of displaying long-running T-SQL statements while debugging.


longRunningSqlStatementsThreshold: The minimum value to consider as a long-running statement for a SQL query. Default value: 500 msec.


numberOfSqlStatements: Sets the number of SQL statements to be shown while debugging. Default value: 10.


enableSqlInformationDebugger: Enables the capability of retrieving T-SQL query information.


disableHttpRequestTimeout: Used to avoid timeouts when debugging web service calls.


forceUpgrade: Forces codeunits to re-run upgrades.


usePublicUrlFromServer: If set to false, it will use the value specified in the server parameter instead of the one set server side as PublicWebBaseURL in the customsettings.config file.


useSystemSessionForDeployment: To prevent debugging, installs and upgrades codeunits (since they will run in another session).


Table 2.2: launch.json attributes

If you have set up more than one value in the JSON array, when you upload or download AL Language commands, you will be prompted to choose one of the parameter set names defined in the JSON array. Below is an example of a launch.json file with multiple elements:

    "version": "0.2.0",
    "configurations": [
            "name": "Docker Sandbox US 23.1",
            "request": "launch",
            "type": "al",
            "environmentType": "OnPrem",
            "server": "http://BC-23-1-US",
            "serverInstance": "BC",
            "authentication": "UserPassword",
            "startupObjectId": 22,
            "startupObjectType": "Page",
            "breakOnError": "All",
            "name": "PACKT Cloud Sandbox",
            "request": "launch",
            "type": "al",
            "environmentType": "Sandbox",
            "environmentName": "SandboxUS",
            "startupObjectId": 22,
            "startupObjectType": "Page",
            "launchBrowser": true,


Typically stored in the extension workspace root folder, app.json represents the extension manifest, written in JSON. Inside the JSON file, there are parameters referencing base and system application dependencies, the application parameter, the platform property, and runtime definitions. These terms need to be well understood when developing for Dynamics 365 Business Central, so we will briefly go over them next.

Base/system application dependencies

With the October 2019 major release (version 15.x), Microsoft converted all legacy C/AL code into AL objects. Currently, the old application monolith has been split into two main extensions:

  • System application: With approximately 1,500 objects, it is growing release after release thanks to the open-source community contribution.
  • Base application: Depending on the localized version, it spans from 7,000 to 9,000 objects, approximately.

To be extended, these need to be referenced as dependencies in the app.json file, and their symbols pulled from an on-premises or an online sandbox through the AL: Download symbols AL Language command.

Defining dependencies to the system and base application is super simple: just set the "application" parameter with the value of the major (or major.minor) version that your extension is targeting like, for example, "application": "". This will instruct Visual Studio Code, when downloading symbols, to check and request the system and base application version to have a value equal to or higher than the one specified in the parameter.

Application parameter and platform property

When pulled in the .alpackages folder, symbols are typically referenced through a version number in the major, minor, build, and revision notations, and this is shown in the name of the symbols that are downloaded (for example, Microsoft_System Application_23.0.36560.0 and Microsoft_Base Application_23.0.36626.36918).

The major version digit typically corresponds to the Dynamics 365 Business Central major update release. The 2023 Wave 2 release update is major version 23. The 2024 Wave 1 update release will be major version 24, and so on.

The minor version typically corresponds to minor updates. The November 2023 Update 1 is minor version 23.1, the December 2023 Update 2 will be minor version 23.2, and so on.

The build number is a progressive number that is incremented by Microsoft as soon as there are changes committed to the branch that are related to feature enhancements or bug fixing.

When developing an extension, you must be aware of what system and application object level is needed as a minimum requirement, as defined in the application parameter of the app.json file.

When targeting a platform for development, you must be aware of the minimum requirements held by files, AL Language statements, and APIs in order to use their features, properties, and functions. If the minimum requirements are not met, these files, statements, and APIs could be exposed to avoid unpredictable behaviors from the application. To help with this, the platform property represents the results of the final compilation of the Dynamics 365 Business Central platform components (client, server, web server, and so on). This property is shown with the same notation as the application.

The application parameter and platform property typically have a different value, since platform code changes and application code changes follow different compilation paths and are merged in the end, right before performing classic and regression tests.


Runtime represents the results of the final compilation of the Dynamics 365 Business Central AL Language extension file.

The notation is simpler and consists of a major, minor, and build version. For example, the Spring 2018 update (or the April 2018 update) is named major version 1, and it increases every year. The current runtime version that targets the 2023 Wave 2 platform and application has version number 12. It is worth noting that the runtime version does not correspond with the application version, so it is important to use the right combination of application and runtime together.

When developing extensions, within the app.json file, you can define what runtime version the application is targeting. This enables or disables different sets of features that can or cannot be part of the target platform deployment, and the AL Language extension’s runtime will detect that. For example, by specifying "runtime": "12.0", we are targeting all modern development features included with the 2023 Wave 2 release and upward. The following table shows the main app.json attributes:




Global Unique Identifier (GUID) of the extension.


Extension name.


Publisher name.


Version of the extension package with major, minor, build, and revision.


Short description of the extension.


Long and verbose description of the extension.


URL to the privacy statement.


URL to the license terms and conditions for the app.


URL to app helpdesk support.


URL to the extension package’s home page.


Relative or full path to the app logo from the root directory of the extension.


List of dependencies from other extensions.


Relative or absolute path to app screenshots.


Minimum platform version supported.


Range of application object IDs or an array of object ID ranges.


It substitutes the now obsolete showMyCode parameter and is used to granularly set the accessibility of the source code and symbols. It will be discussed later in this chapter.


Default value: Cloud. Set this value to OnPrem if you need to target the extension to on-premises deployment. Be well aware that the Universal Code initiative will apply higher fees year over year if you choose to target on-premises deployments.


URL for the extension’s online help.


URL for the context-sensitive help for an AppSource extension.


Comma-separated list of the local languages supported by the extension.


Optional features that could be enabled by the compiler. It will be discussed later in this chapter. An example is TranslationFile.


Minimum runtime version targeted by the extension.


Optional. It might contain source DevOps information such as the URL address of the source repo and the Git commit ID that triggered the extension build.


Optional. Build DevOps info such as the agent’s name and the URL at which to find the resulting build.

Table 2.3: app.json attributes

The following is an example of a condensed app.json file:

  "id": "dd03d28e-4dfe-48d9-9520-c875595362b6",
  "name": "Packt Demo Extension",
  "publisher": "PACKT",
  "brief": "Customer Category, Gift Campaigns and Vendor Quality Management",
  "description": "Customer Category, Gift Campaigns and Vendor Quality Management",
  "version": "",
  "privacyStatement": "",
  "EULA": "",
  "help": "",
  "url": "",
  "logo": "./Logo/ExtLogo.png",
  "dependencies": [],
  "screenshots": [],
  "platform": "",
  "application": "",
  "features": [
  "idRanges": [
      "from": 50100,
      "to": 50149
  "contextSensitiveHelpUrl": "",
  "resourceExposurePolicy": {
    "allowDebugging": true,
    "allowDownloadingSource": true,
    "includeSourceInSymbolFile": true,
    "applyToDevExtension": false
  "runtime": "12.0"

Two of the main app.json parameters need a deeper analysis: features and resourceExposurePolicy.

The features parameter currently admits specifying the following placeholders:

  • TranslationFile: Adding this parameter flag in features enables the generation of a directory called Translations in the extension folder and an .xlf translation file containing all the labels used in all extension objects. Translation files will be handled in deep detail in Chapter 4, Developing a Customized Solution for Dynamics 365 Business Central.
  • GenerateCaption: If TranslationFile is set, it will automatically generate translation placeholders for all objects that do not have a Caption or CaptionML property explicitly specified.
  • GenerateLockedTranslations: This will generate the appropriate elements for locked labels in the translation file when building the extension.
  • AllTranslationItems: This will generate translation placeholders for all possible object elements in the extension.
  • ExcludeGeneratedTranslations: This excludes the generated translation files from the extension.
  • NoImplicitWith: By adding this flag, you instruct the compiler to switch off the use of the With AL statement and all implicit field definitions (e.g., within pages, you should always reference Rec.<fieldname>).
  • NoPromotedActionProperties: This will not admit any old promoted property definition in the extension and will switch on the new modern action reference syntax.
  • UseLegacyAnalyzerStrategy: This reverts to the previous – and quite expansive in terms of resources – code analysis where every change in the code will trigger code analysis within the entire project.

The resourceExposurePolicy parameter is an array of values and it is very important in defining if, when, and how to surface the code written in the extension. Currently, it supports the following Boolean elements:

  • allowDebugging: Capability of debugging the code. It will download locally the source code of the files needed to debug in .dal (non-editable) format.
  • allowDownloadingSource: Capability of switching on/off the download source button on the Extension Management page for that specific extension.
  • includeSourceInSymbolFile: Determines whether the source code should be included or not in the symbols package when publishing the extension through PowerShell cmdlets.
  • applyToDevExtension: By default, extensions published directly through Visual Studio Code (so-called dev extensions) always include the source code in the symbols package. Turning this flag on will perform the same action specified for includeSourceInSymbolFile and also for extensions that are going to be published with dev scope. It is worth noting that this will enable the ability to debug apps that have allowDownloadingSource turned off, if the app is deployed to a sandbox using Visual Studio Code.

This is not over. The app.json file is enriched with new parameters, release after release. Some of them could be considered of minor importance, considering a per-tenant extension development, but they could turn out to be vital for the clean development of ISV or AppSource extensions:

  • internalsVisibleTo: This is an array of apps that have been granted access to the objects that are defined with Access = Internal in the current extension.
  • propagateDependencies: This is used typically in large projects with a discrete dependency tree. If extension 1 depends on extension 2 and that depends on extension 3, by default, the primary extension will not be able to declare anything defined in extension 3. If extension 2 has this parameter set to true, then extension 1 will be able to see and declare methods defined in extension 3, without the need to explicitly add the extension manifest in the dependencies parameter of its app.json file.
  • applicationInsightsConnectionString: This is used to send telemetry logs in a specific ingestion endpoint. Please note that there is no need to specify any connection string in the Dynamics 365 Business Central Tenant Admin Center (TAC) to have these sent. It is used with AppSource apps by ISVs that could gather information from different deployment sources to improve the extension experience or for troubleshooting purposes.
  • keyVaultUrls: Within an AppSource app, it is typical to keep all the resource exposure policies as false and override them by specifying an Azure key vault that stores the AAD tenant ID(s) where some of these policies are different. Setting all resource exposure policies to false and implementing the override strategy is the highest level of private IP protection that could be reached for AppSource extensions.

    To learn more about Azure Key Vault, please read Dynamics 365 Business Central: Using Azure Key Vault for your secrets:

  • suppressWarnings: Code analyzers, which we will learn about later in this chapter, obey several error and warning rules identified by a rule ID. This parameter is a collection of warning rule IDs that should not be shown (skipped) in the Visual Studio Code Output window.
  • preprocessorSymbols: This is a list of names (symbols) used by preprocessor directives. Preprocessor elements or directives are used to set regions of code that could be expanded or collapsed, to suppress warnings in a more capillary way than suppressWarnings does and, overall, to instruct the compiler to include or exclude specified code blocks based on the existence of specific symbols. This is a very useful technique when working with obsolete objects or fields.

    To learn more about obsoleting code, please read Best Practices for Deprecation of AL Code:

With this information, you should now be able to master both the launch.json and app.json extension configuration files and tweak them according to the runtime version. In the next section, we will introduce symbols and explain their vital importance in extension development.

Understanding symbols

Like in many other languages, symbols represent references to a collection of standard objects, properties, and functions. They are a special extension file themselves with the typical .app naming convention and are used to maintain object reference consistency while compiling, and they also populate valid IntelliSense entries.

With Dynamics 365 Business Central, symbols are already loaded inside the application database, and these can be grouped into two classes:

  • System symbols: Symbols for system tables in the 2000000004 to 2000000199 ID range, and also virtual table definitions, plus some system codeunits. All these structures cannot be modified through extensions. Typically, these are downloaded from any environment as a file and rarely are changed within a major version.
  • Extension symbols: All other symbols are typically generated when compiling (Ctrl + Shift + B) any extension and are part of the app package.

Whenever you extend an application, you always need to have the appropriate symbols downloaded and in place. You can achieve this in two ways:

  • Connect to an online sandbox environment, run the Command Palette (F1), and type and select AL: Download Symbols.
  • Copy the required symbols manually from another place (such as the product DVD, for on-premises deployment) and store them in the defined symbol storage directory.

If you have a multiuser environment with developers that are working on the same staging tenant, you might think of downloading symbols through the Command Palette once and then setting a common path for storing the symbols for all users. In this way, it is possible to avoid downloading the same set of symbols every time, thereby increasing development productivity.

The default symbol-storing path can be changed using one of the following shortcuts:

  • From the Menu bar, go to File (Alt + F) | Preferences (P) | Settings (S), and then select AL Language extension settings.
  • Use the settings shortcuts (Ctrl + ,) and then select AL Language extension settings.

The parameter to change is Package Cache Path, the default value of which is set to the relative path, ./.alpackages.

Alternatively, you could run the Command Palette (F1), type and select Preferences: Configure language-specific settings…, then choose AL. The settings.json file will open, and you can then add or change the values of the al.packageCachePath parameter. Later in this chapter, we will also discuss other AL Language configuration settings.

Together with the system application extension, base application extension, and system symbols, your extension might also depend on other custom or third-party extensions. These extensions, then, should emit symbols that you should be able to download from the application database when invoking AL: Download Symbols from the Command Palette.

To specify that your extension has a dependency on another extension(s), you must populate the dependencies parameter in the app.json file. This is what the app.json file parameter looks like for an extension that depends on another app:

  "dependencies": [
      "id": "dd03d28e-4dfe-48d9-9520-c875595362b6",
      "name": "Packt Demo Extension",
      "publisher": "PACKT",
      "version": ""

If you have installed waldo’s CRS AL Language Extension (, you could type tdependencywaldo to enable the code snippet to easily edit each JSON array element for this parameter. This will make your coding faster and prevent syntax errors. We will discuss the standard and custom code snippet features in the last section of this chapter and more on productive extensions in Chapter 17, Useful Visual Studio Code Extensions for Dynamics 365 Business Central Developers.

The version parameter of the dependent extension(s) represents the lower bound for the compiler to accept the symbols. In other words, symbol versions of the dependent extension lower than the one reported are not considered valid for download or compile operations.

Inside symbols

Symbols are the result of a compression operation of several files that are used by the AL Language extension. To demonstrate what is under the hood, use a decompression tool (for example, 7-Zip) to extract their content after renaming the .app package with the .zip extension.

To give a practical example, the following tables show the standard symbol components (files and directories) for a standard base application extension:




Specifies the content of the package. For example: .xml, AL, .json, .rdlc files, and so on.


Specifies the extension logo filename and its ID.


Contains entries for the Role Explorer.


Reports the manifest for the standard symbol or extension. In other words, it is a translation into XML of the app.json file.


Contains all documentation comments for tables, fields, functions, and so on. Below is a simple snippet for an AL function:

<member name="M:.Line With Price.GetPriceType:Enum::Price Type">
   Returns the price type that was set by the SetLine() method:
   <returns>The price type</returns>


Contains all references in JSON notation to AL objects. It could also be quite a big JSON file (for example, in a standard base application, it is 60+ MB). These JSON files are heavily used by the AL Language extension to maintain reference integrity while compiling/building the app package and to enable all IntelliSense-related features. Basically, it is structured as an array containing a list of valid AL object parameters, as shown in the following snippet:

"Tables": [],
"Codeunits": [],
"Pages": [],
"PageExtensions": [],

For each of these object elements, there are specified fields, properties, functions, and so on.

Table 2.4: Symbol components

Symbol JSON files cannot be hacked/changed to manually generate or modify a symbol file.

Next, let’s also have a look at what the various symbols directories do:

Directory name

Content description


Contains an XML file that stores entitlement entries for every object.


Report layouts.


Extension logo.


Symbols for profiles and related page customizations.


AL files. Their content is used typically to show the code while debugging.


Translation files in the XLF format.

Table 2.5: Symbol directiories

Symbols are the beating heart of the extension validation mechanism and, as shown in the previous tables, they also could carry out the code, depending on how resource exposure policies have been set up in the app.json file.

To deeply analyze AL symbols, the Microsoft AL Language extension provides a useful tool with a few functionalities to analyze symbols, AL Explorer (Ctrl + Shift + F12):

Figure 2.28: AL Explorer

This tool is currently divided into four self-explanatory tabs: OBJECTS, EVENTS, APIS, and EXTENSIBLE ENUMS. For each tab, a list of entities taken by symbols is provided and it is possible to search for names, IDs, and so on, group them by specific properties or namespaces, filter them by modules or sources, or simply choose the ones bookmarked.

There are also very useful extensions in the Visual Studio Code marketplace. The most used, with currently more than 160,000 downloads, is AZ AL Dev Tools/AL Code Outline by Andrzej Zwierzchowski ( This extension is very easy to use and is super powerful for inspecting symbols and their content. More on this extension, and others, will be discussed in Chapter 17, Useful and Proficient Tools for AL Developers.

Once you have identified the entity that you were looking for, you could even perform some actions. For almost all of the entities listed in the tab, you could always click on the Source button and inspect the code, while for runnable objects you could select the entry and click the Run button. Within events, you could select the publisher that you were looking for and easily click on the Subscribe button, to automatically add the prototype of a subscriber to your clipboard:

Figure 2.29: Copying a subscriber prototype to your clipboard

You could then paste the content of the clipboard in your custom Codeunit object, without the need to type all the signature elements.

As with the AL Home page, it is possible to completely turn this page off so it doesn’t pop up and we will see how to configure it later in this chapter. In any case, you could always run the AL Explorer page from the Command Palette (F1) by using the command AL: Explorer or by using the Ctrl + Shift + F12 shortcut.

After learning about symbols and the tools to analyze them, we have completed an overview of the main items that are needed to build an app. Let us have a look now at AL Language extension configuration, and how to set it up to have a more productive development environment.

AL Language extension settings

Per-user and per-workspace settings can be easily shown through the shortcut Ctrl + , (comma). An intuitive menu will be displayed, and by selecting Extension | AL Language extension configuration, a set of configuration parameters is listed. The following screenshot shows the AL Language extension configuration parameters:

Figure 2.30: Extension configuration parameters

Basically, these configuration values are saved into a file called settings.json. The following lists describe the most common ones, ordered per parameter type.

Path parameters:

  • al.packageCachePath: It is possible to change the default value to a local folder or a shared folder for multi-developer environments. This represents the path where to store and look for symbols.
  • al.assemblyProbingPaths: This parameter is fundamental to compiling extensions when there are references to external assemblies. Its data type is a JSON array, so the developer has to specify a comma-separated list of paths where the assemblies should be stored at design time.
  • al.editorServicesPath: If service logging is enabled, it determines where to store the service and debugger logs.
  • al.algoSuggestedFolder: This defines where any new project folder should be created. It overrides the default creation path.

Compilation parameters:

  • al.compilationOptions: Used to specify whether a report layout should be generated or not when compiling, if it does not exist, whether to have a serialized or parallel build of the package, and finally, the polling to emit diagnostics. Within the compilation options, it is also possible to specify the folder where the compiler should place the resulting extension file (.app).

Browser parameters:

  • al.browser: Choose your preferred browser to launch your Dynamics 365 Business Central application from Visual Studio Code or leave it to use the system default. It is useful if you have multiple browsers installed.
  • al.incognito: Choose to start the browser in a normal session that stores existing credentials or use the private/incognito browsing mode.

Miscellaneous parameters:

  • al.enableCodeActions: Enables or disables code actions such as automatically converting multiple if statements to a CASE statement or kicking in spell check. By default, it is enabled. Code actions, as you might imagine, are quite expensive in terms of resource consumption.
  • al.enableScriptIntelliSense: Enables or disables the IntelliSense for JavaScript control add-in script files.
  • al.showHomeAtStartup: You could choose to let the AL Home page pop up Always, Never, or, preferably, WhenUpdated.
  • al.showExplorerAtStartup: You could choose to let the AL Explorer page pop up Always, Once, or Never.
  • al.inlayhints.functionReturnTypes.enabled: Inlay hints are additional information provided for the source code that are displayed inline. Inlay hints should be enabled by default, but you could set them to have a different behavior by changing the parameter editor.inlayHints.enabled from on to offUnlessPresseds or onUnlessPressed to have the information appear selectively, depending on whether the Ctrl + Alt keys are being pressed.
  • al.inlayhints.parameterNames.enabled: As above, but info is provided for every single parameter name in the signature.

By pressing Ctrl + Shift in any place inside the settings.json file and typing al, you might have noticed that it will show a few other AL Language configuration parameters. These are related to code analyzers, rule sets, log paths, performance profilers, and other features that will be addressed later on or in other chapters.

If you would like to learn more about every single parameter and how to streamline your configuration for the best performance, we recommend reading Optimize Visual Studio Code for AL Development:

After exploring the core settings that are needed to develop an extension, let us have a quick look into a notable feature offered by Visual Studio Code and the AL Language extension to better develop clean solutions according to best practices and guidelines: code analyzers.

Understanding code analyzers

The AL Language design-time experience is greatly enhanced by code analyzers. Code analyzers are part of the standard AL Language extension and are a set of contextual rules that are applied to extension development. These rules can generate an error, a warning, or info when you’re developing an extension. Since they patrol every single line or sentence of your code, they are also known as code cops.

Code analyzers can be enabled and disabled at will, both per workspace and globally.

To enable code analyzers, perform the following steps:

  1. Go to File | Preferences | Settings (Workspace settings) | Extension | AL language extension and choose to edit the settings.json file.

    You could also choose to edit the settings.json file through the user settings. However, since you might develop per-tenant extensions and also AppSource apps in the same environment, it would make more sense to have these enabled per workspace instead of per user.

  1. In the settings.json file, it is possible to add or change the following relevant parameters:
    • al.enableCodeAnalysis: Changing this parameter to true enables the analyzers that are specified in the JSON array parameter al.codeAnalyzers.
    • al.codeAnalyzers: Currently, the supported values are as follows:
      • ${AppSourceCop}: This must be enabled when developing extensions targeted for the AppSource marketplace.
      • ${CodeCop}: This strengthens the standard AL Language development guidelines, and it is recommended to be enabled for every kind of target.
      • ${PerTenantExtensionCop}: Together with ${CodeCop}, this should be enabled on every development target, except when developing extensions for the AppSource marketplace, where ${AppSourceCop} should be used.
      • ${UICop}: This is the last addition to the code analyzers, and it checks that the code matches the features that are supported by modern clients and avoids hitting user interface limitations. It should always be enabled, like ${CodeCop}.
    • al.backgroundCodeAnalysis: This defines if the analysis should also happen in the background during coding and the frequency at which it should kick in. Since code analysis is quite resource-consuming, if it kicks in too frequently, it could interfere with normal programming activity. Therefore, it is recommended to have this set per File for small to mid-sized extensions, while with quite complex solutions, it is recommended to have this changed to a more resource-savvy Project scope.
    • al.outputAnalyzerStatistics: This parameter will generate statistics at every compilation build. It is useful to determine code cops’ performance.
    • al.ruleSetPath: This is the path to a file that contains changes to the rules that are provided through standard code analyzers. A ruleset file is written in JSON notation and has a reference to an existing ruleset item ID that is implemented in the standard AL Language extension. This file is typically edited to redefine the importance of the rules within a specific extension project or workspace.
    • al.enableExternalRuleSets: This enables or disables the capability of using a URL as a path for ruleset files.
  2. If we implement code analyzers in any extension project that we have created, even the super simple HelloWorld sample created through the AL: GO! command, it will help us to find out more info about the code style, and whether there are improvements to be applied.

    Let’s see what the analyzers will find out in the default HelloWorld project by changing the settings.json file in the workspace settings as follows:

    "al.enableCodeAnalysis": true,
    "al.backgroundCodeAnalysis": "File",
    "al.codeAnalyzers": ["${CodeCop}",
  1. In the PROBLEMS window, there might now be something displayed. In this very simple case, there should be one warning, as per the following screenshot:

Figure 2.31: Viewing a displayed warning

Looking at the error, it is clear that the file does not reflect the standard naming convention and should be changed to

It is trivial to say that if you rename the file according to what is reported by the warning, the warning will magically disappear. But what if, for some reason, we do not want to have that warning or info message displayed at all (to avoid the PROBLEMS window cluttering, for example)?

A rule’s importance value can be changed at will or the rule itself can be suppressed by simply creating a JSON file that contains the IDs of the rules that need to be changed and how they have to be set according to your company’s development rules:

  1. Let’s create a directory in the extension’s main folder called .ruleset, and create a file called demo.ruleset.json:

Figure 2.32: Creating a file within a folder

  1. Open demo.ruleset.json, and invoke the ruleset standard snippet to write the following:
        "name": "PacktDemoExtensionRuleSet",
        "description": "Demo Rule Set for Hello World (PTE)",
        "rules": [
                "id": "AA0215",
                "action": "Hidden",
                "justification": "File naming warning is kept hidden"

    In this way, we would like to instruct the AL Language code analyzer to avoid adding a warning record in the PROBLEMS window for the rule whose ID is AA0215.

  1. The last step to make it work is to assign the alRuleSetPath parameter to point to the newly created file in the settings.json file:
    "al.ruleSetPath": "./.ruleset/demo.ruleset.json"

    When you assign the path to a ruleset file, it is recommended that you save all files and close and reopen Visual Studio Code or use the Developer: Reload Window command from the Command Palette, to be sure that there are no permission errors, and access the ruleset file by the current process.

Once the ruleset file is in place, there should not be any warnings in the PROBLEMS window related to the file. Takeaways at this stage are that developers should make good use of these rules in their own company and discuss what needs to be changed, maintained as is, or completely turned off.

Be careful when enabling code analyzers, since they might increase the memory consumption footprint in the development machine. It is recommended to turn on statistics with "al.outputAnalyzerStatistics": true in the settings.json file, if any performance problem arises, during compilation.

Now that we have mastered Visual Studio Code’s main elements and features and are close to our first sample or our super sexy solution being developed, it is time to change gears and introduce GitHub Copilot to help us code faster (and sometimes better).

GitHub Copilot for AL developers

In your daily practice, you have probably desired, at some point in time, to have someone other than the rubber duck on your desk to help you find out the right procedure or code snippet faster to finalize your code. GitHub Copilot could be your dream come true in assisting you while developing.

GitHub Copilot’s documentation and price plans (currently $10/month for individuals, $100 per year, and $19 per user per month for the Business edition) can be found at this web page: and is available as a Visual Studio Code extension in the marketplace:

Figure 2.33: GitHub Copilot

Before installing GitHub Copilot, it is required to have a GitHub account. If you haven’t already got your own, you could easily create one at This operation is free of charge.

Let’s enable the free trial together, step by step.

  1. Go to and click on Start my free trial. NOTE: If you have not already signed in to your GitHub account, you will be prompted to do so.
  2. Give consent to the 30-day trial period.
  3. Add your payment details. NOTE: Remember to confirm or remove the payment details before the end of the trial period
  4. When prompted with GitHub Copilot can allow or block suggestions matching public code, choose Allow.

    When you apply for a trial version, it might take up to 30 minutes to process and synchronize your submission. You should wait for this time before moving forward with the next bullet point.

  1. Launch Visual Studio Code and go to Extensions (Ctrl + Shift + X)
  2. Search for GitHub Copilot and install it.
  3. Reload the Visual Studio Code window. You will be prompted to sign in (see below):

Figure 2.34: Signing in to GitHub Copilot

  1. Allow and grant all prompt requests to generate the appropriate token to interact and work with Copilot.

And that’s all. You should be ready to work together with Copilot right away. To be sure that Copilot is enabled, just check the small Copilot icon at the bottom right in the status bar:

Figure 2.35: GitHub Copilot icon

You can click on it if you want to disable it and go back to flying solo.

To test the effectiveness of Copilot’s knowledge and how this could be of any help, just perform these simple steps in a simple file.

Under the trigger declaration, add a var section, then press Enter and Tab. GitHub Copilot will suggest creating a record variable called Customer of type Customer, as follows:

Figure 2.36: GitHub Copilot suggestions

You might accept the suggestion by simply pressing Tab twice.

From now on, you can continue experimenting with how good, fast, and proficient it is to develop together with GitHub Copilot.

If you want to learn more about GitHub Copilot, it is worth watching 20221121 - GitHub Copilot Write Extensions for Business Central with AL:


Visual Studio Code is a code-centric tool that supports, out of the box, a wide variety of languages, providing coding features such as syntax colorization, delimiter matching, code block folding, multiple cursors, IntelliSense, and so much more.

By installing the AL Language extension, this modern development environment is fully set up as an app playground for beginner and skilled developers. We have unveiled some tips and tricks in this chapter that enable you to be proficient in the developer’s daily work of creating modern apps for Dynamics 365 Business Central.

We then moved on to learn about the powerful coding features that this modern development environment offers, and, in the end, we had some fun working with GitHub Copilot and tasted a bit of how artificial intelligence could help developers.

After all of this, it is time to see AL Language in action throughout this book and move into a structured basic and advanced extension development. This is what we will do in the next couple of chapters.

Learn more on Discord

To join the Discord community for this book – where you can share feedback, ask questions to the author, and learn about new releases – follow the QR code below:

Left arrow icon Right arrow icon
Download code icon Download Code

Key benefits

  • Extend Business Central's functionalities through Azure, Power Platform, GitHub, and custom extensions
  • Unlock the potential of data exchange and functionality expansion by integrating with external systems using APIs and OData
  • Build reliable, maintainable, and continuously improving solutions while writing performant, well-structured code and using telemetries and DevOps


This book dives straight into guiding you through the process of building real-world solutions with the AL language and Visual Studio Code. It emphasizes best practices and extensibility patterns to ensure your extensions are well-structured, maintainable, and meet the needs of modern businesses. You'll learn advanced AL techniques, report creation methods, debugging strategies, and how to leverage telemetries for monitoring. Additionally, it covers performance optimization practices and API integration to help you create efficient and interconnected solutions. With a focus on extension development, this new edition allows you to jump right into coding without spending time on setup processes. This book introduces new chapters covering essential tasks that Business Central developers frequently encounter, such as file handling and printing management. Finally, the book expands its scope by including chapters on various integration aspects, including VS Code extensions, GitHub DevOps, Azure services, and Power Platform integrations. We’ll wrap up by covering Copilot capabilities in Business Central and how you can create your own generative AI copilots. By mastering these concepts and techniques, you'll be well-equipped to create powerful and customized solutions that extend the capabilities of Dynamics 365 Business Central.

What you will learn

Developing a customized solution for Dynamics 365 Business Central Writing performant code following extensibility patterns Handling reporting, files, and printing on a cloud environment Handling Business Central telemetries with Azure Writing APIs and integrations for Dynamics 365 Business Central Applying DevOps and CI/CD to development projects by using GitHub Integrating Business Central with Power Platform Publishing your solutions to AppSource marketplace Manage Copilot capabilities and create your own generative AI copilot

Product Details

Country selected

Publication date : Mar 19, 2024
Length 684 pages
Edition : 2nd Edition
Language : English
ISBN-13 : 9781837630646
Vendor :
Category :

What do you get with eBook?

Product feature icon Instant access to your Digital eBook purchase
Product feature icon Download this book in EPUB and PDF formats
Product feature icon AI Assistant (beta) to help accelerate your learning
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want

Product Details

Publication date : Mar 19, 2024
Length 684 pages
Edition : 2nd Edition
Language : English
ISBN-13 : 9781837630646
Vendor :
Category :

Table of Contents

21 Chapters
Preface Chevron down icon Chevron up icon
1. Microsoft Dynamics 365 Business Central’s Online Momentum Chevron down icon Chevron up icon
2. Mastering a Modern Development Environment Chevron down icon Chevron up icon
3. Extension Development Fundamentals Chevron down icon Chevron up icon
4. Developing a Customized Solution for Dynamics 365 Business Central Chevron down icon Chevron up icon
5. Writing Code for Extensibility Chevron down icon Chevron up icon
6. Advanced AL Development Chevron down icon Chevron up icon
7. Handling Files with Dynamics 365 Business Central Chevron down icon Chevron up icon
8. Report Development Chevron down icon Chevron up icon
9. Printing Chevron down icon Chevron up icon
10. Debugging Chevron down icon Chevron up icon
11. Telemetry Chevron down icon Chevron up icon
12. Coding for Performance Chevron down icon Chevron up icon
13. Dynamics 365 Business Central APIs Chevron down icon Chevron up icon
14. Extending Dynamics 365 Business Central with Azure Services Chevron down icon Chevron up icon
15. DevOps for Dynamics 365 Business Central Chevron down icon Chevron up icon
16. Dynamics 365 Business Central and Power Platform Integration Chevron down icon Chevron up icon
17. Useful and Proficient Tools for AL Developers Chevron down icon Chevron up icon
18. Creating Generative AI Solutions for Dynamics 365 Business Central Chevron down icon Chevron up icon
19. Other Books You May Enjoy Chevron down icon Chevron up icon
20. Index Chevron down icon Chevron up icon

Customer reviews

Top Reviews
Rating distribution
Full star icon Full star icon Full star icon Full star icon Full star icon 5
(2 Ratings)
5 star 100%
4 star 0%
3 star 0%
2 star 0%
1 star 0%
Filter icon Filter
Top Reviews

Filter reviews by

Daniel Hodenius Feb 20, 2024
Full star icon Full star icon Full star icon Full star icon Full star icon 5
Feefo Verified review Feefo image
N/A Apr 10, 2024
Full star icon Full star icon Full star icon Full star icon Full star icon 5
Feefo Verified review Feefo image
Get free access to Packt library with over 7500+ books and video courses for 7 days!
Start Free Trial


How do I buy and download an eBook? Chevron down icon Chevron up icon

Where there is an eBook version of a title available, you can buy it from the book details for that title. Add either the standalone eBook or the eBook and print book bundle to your shopping cart. Your eBook will show in your cart as a product on its own. After completing checkout and payment in the normal way, you will receive your receipt on the screen containing a link to a personalised PDF download file. This link will remain active for 30 days. You can download backup copies of the file by logging in to your account at any time.

If you already have Adobe reader installed, then clicking on the link will download and open the PDF file directly. If you don't, then save the PDF file on your machine and download the Reader to view it.

Please Note: Packt eBooks are non-returnable and non-refundable.

Packt eBook and Licensing When you buy an eBook from Packt Publishing, completing your purchase means you accept the terms of our licence agreement. Please read the full text of the agreement. In it we have tried to balance the need for the ebook to be usable for you the reader with our needs to protect the rights of us as Publishers and of our authors. In summary, the agreement says:

  • You may make copies of your eBook for your own use onto any machine
  • You may not pass copies of the eBook on to anyone else
How can I make a purchase on your website? Chevron down icon Chevron up icon

If you want to purchase a video course, eBook or Bundle (Print+eBook) please follow below steps:

  1. Register on our website using your email address and the password.
  2. Search for the title by name or ISBN using the search option.
  3. Select the title you want to purchase.
  4. Choose the format you wish to purchase the title in; if you order the Print Book, you get a free eBook copy of the same title. 
  5. Proceed with the checkout process (payment to be made using Credit Card, Debit Cart, or PayPal)
Where can I access support around an eBook? Chevron down icon Chevron up icon
  • If you experience a problem with using or installing Adobe Reader, the contact Adobe directly.
  • To view the errata for the book, see and view the pages for the title you have.
  • To view your account details or to download a new copy of the book go to
  • To contact us directly if a problem is not resolved, use
What eBook formats do Packt support? Chevron down icon Chevron up icon

Our eBooks are currently available in a variety of formats such as PDF and ePubs. In the future, this may well change with trends and development in technology, but please note that our PDFs are not Adobe eBook Reader format, which has greater restrictions on security.

You will need to use Adobe Reader v9 or later in order to read Packt's PDF eBooks.

What are the benefits of eBooks? Chevron down icon Chevron up icon
  • You can get the information you need immediately
  • You can easily take them with you on a laptop
  • You can download them an unlimited number of times
  • You can print them out
  • They are copy-paste enabled
  • They are searchable
  • There is no password protection
  • They are lower price than print
  • They save resources and space
What is an eBook? Chevron down icon Chevron up icon

Packt eBooks are a complete electronic version of the print edition, available in PDF and ePub formats. Every piece of content down to the page numbering is the same. Because we save the costs of printing and shipping the book to you, we are able to offer eBooks at a lower cost than print editions.

When you have purchased an eBook, simply login to your account and click on the link in Your Download Area. We recommend you saving the file to your hard drive before opening it.

For optimal viewing of our eBooks, we recommend you download and install the free Adobe Reader version 9.