Your First Business Central Extension: AL Development from Scratch
Step-by-step guide to writing your first AL extension for Business Central, from VS Code setup to deploying a custom field on the Customer Card.
AL is the programming language Microsoft created for extending Business Central. If you’ve worked with C/AL (the old way), AL will feel familiar but more structured. If you’re coming from another language, it’s readable and relatively forgiving.
This walkthrough takes you from zero to a deployed extension that adds a custom field to the Customer table and shows it on the Customer Card. It’s the “Hello World” of BC development, but it’s a complete, real workflow.
Prerequisites
If you’re new to Business Central, read the Getting Started guide first to get familiar with the environment before diving into development.
Before writing any code you need:
- VS Code: code.visualstudio.com
- AL Language extension for VS Code: search “AL Language” in the Extensions panel (publisher: Microsoft)
- A Business Central sandbox environment: use your BC tenant’s sandbox or Docker. Learn how to set up a Docker BC environment
Step 1: Create a New AL Project
Open VS Code. Press Ctrl + Shift + P (or ⌘ + Shift + P on Mac) and run:
AL: Go!
This command initializes a new AL project. You’ll be prompted for:
- Which server? Choose “Your own server” if using Docker, or “Microsoft cloud sandbox”
- Which version? Pick the version matching your BC environment
- Authentication type? UserPassword for Docker, AAD for cloud
VS Code will create a folder structure like:
my-extension/
├── .alpackages/ ← BC symbol packages (auto-downloaded)
├── .vscode/
│ └── launch.json ← Connection to your BC instance
├── HelloWorld.al ← A sample AL file
└── app.json ← Extension manifest
Step 2: Configure app.json
Open app.json: this is your extension’s manifest. Update it:
{
"id": "your-unique-guid-here",
"name": "Daxly Customer Extensions",
"publisher": "Daxly",
"version": "1.0.0.0",
"brief": "Adds custom fields to the Customer table",
"description": "",
"privacyStatement": "",
"EULA": "",
"help": "",
"url": "https://daxly.io",
"logo": "",
"dependencies": [],
"screenshots": [],
"platform": "25.0.0.0",
"application": "25.0.0.0",
"idRanges": [
{
"from": 50000,
"to": 50099
}
],
"runtime": "13.0"
}
The id must be a unique GUID. Generate one at guidgenerator.com or use Ctrl + Shift + P → “Insert GUID” in VS Code.
The idRanges are important: all objects you create (tables, pages, etc.) need IDs in the range you specify. For production extensions published to AppSource, you need a registered range from Microsoft. For internal extensions, 50000–99999 is conventionally used.
Step 3: Create a Table Extension
Delete the sample HelloWorld.al file and create a new file called CustomerExt.TableExt.al:
tableextension 50000 "Customer Extension" extends Customer
{
fields
{
field(50000; "Customer Tier"; Enum "Daxly Customer Tier")
{
Caption = 'Customer Tier';
DataClassification = CustomerContent;
}
field(50001; "Internal Notes"; Text[500])
{
Caption = 'Internal Notes';
DataClassification = CustomerContent;
}
}
}
Now create the Enum referenced above: CustomerTier.Enum.al:
enum 50000 "Daxly Customer Tier"
{
Extensible = true;
value(0; " ") { Caption = ' '; }
value(1; "Bronze") { Caption = 'Bronze'; }
value(2; "Silver") { Caption = 'Silver'; }
value(3; "Gold") { Caption = 'Gold'; }
value(4; "Enterprise") { Caption = 'Enterprise'; }
}
Step 4: Create a Page Extension
Now surface those fields on the Customer Card. Create CustomerCardExt.PageExt.al:
pageextension 50000 "Customer Card Extension" extends "Customer Card"
{
layout
{
addafter("Credit Limit (LCY)")
{
field("Customer Tier"; Rec."Customer Tier")
{
ApplicationArea = All;
ToolTip = 'Specifies the customer tier classification.';
}
}
addlast(General)
{
field("Internal Notes"; Rec."Internal Notes")
{
ApplicationArea = All;
ToolTip = 'Specifies internal notes about this customer. Not visible to the customer.';
MultiLine = true;
}
}
}
}
Step 5: Publish to Your Sandbox
Press F5 in VS Code (or Ctrl + F5 to publish without debugging). VS Code will:
- Compile your AL code
- Package it into a
.appfile - Deploy it to the BC instance configured in
launch.json
If everything is correct, your BC browser tab will open (or refresh) automatically.
Navigate to any Customer Card and you’ll see Customer Tier (a dropdown) and Internal Notes (a multiline text field) now appear on the page.
Common First-Timer Mistakes
Wrong idRanges: If you get a “ID is not within the range” error, your object ID (50000 in our case) must fall within the range declared in app.json.
DataClassification is required: Every field on a Table or TableExtension must have a DataClassification property. Use CustomerContent for business data, SystemMetadata for internal tracking fields.
Forgetting ApplicationArea: Page fields need ApplicationArea = All (or a more specific value like Basic, Suite) or they won’t appear.
Next Steps
From here, the AL object model is logical to explore:
- Codeunits: business logic, procedures, event subscribers
- Reports: data exports and printed documents (uses RDLC or Word layouts)
- Queries: SQL-like data access optimized for reporting
- API Pages: expose BC data via REST API
The Microsoft AL Developer documentation is comprehensive and well-maintained. Once you have this first extension working, the rest builds naturally on the same patterns.
For day-to-day productivity while working in BC alongside your development, see 20 Business Central Keyboard Shortcuts That Actually Save Time.