Developer ToolsFree generatorPDF, Excel, Word exportMicrosoft Dynamics 365 Business Central

Business Central AL Extension Skeleton Generator

Starting a Business Central extension means writing the same handful of files every time: app.json, a table extension, a page extension, an event subscriber and a permission set. This generator fills them with your publisher, prefix and ID range so you can paste them into a new AL project and begin with consistent naming.

Fill in

Use your reserved AppSource or partner prefix.

Generated code
Download:

app.json

{
  "id": "00000000-0000-0000-0000-000000000000",
  "name": "Customer Loyalty",
  "publisher": "Contoso Partners",
  "version": "1.0.0.0",
  "brief": "Customer Loyalty extension",
  "platform": "26.0.0.0",
  "application": "26.0.0.0",
  "idRanges": [
    { "from": 50100, "to": 50149 }
  ],
  "runtime": "15.0",
  "target": "Cloud"
}

Table extension: Customer

tableextension 50100 "CLY Customer Ext" extends Customer
{
    fields
    {
        field(50100; "CLY Loyalty Tier"; Code[20])
        {
            Caption = 'Loyalty Tier';
            DataClassification = CustomerContent;
        }
    }
}

Page extension: Customer Card

pageextension 50100 "CLY Customer Card Ext" extends "Customer Card"
{
    layout
    {
        addafter(Name)
        {
            field("CLY Loyalty Tier"; Rec."CLY Loyalty Tier")
            {
                ApplicationArea = All;
                ToolTip = 'Specifies the Loyalty Tier of the customer.';
            }
        }
    }
}

Codeunit with event subscriber

codeunit 50100 "CLY Customer Events"
{
    [EventSubscriber(ObjectType::Table, Database::Customer, 'OnAfterInsertEvent', '', false, false)]
    local procedure SetDefaultOnInsert(var Rec: Record Customer; RunTrigger: Boolean)
    begin
        if Rec.IsTemporary() then
            exit;
        if Rec."CLY Loyalty Tier" = '' then begin
            Rec."CLY Loyalty Tier" := 'STANDARD';
            Rec.Modify();
        end;
    end;
}

Permission set

permissionset 50100 "CLY ALL"
{
    Assignable = true;
    Caption = 'Customer Loyalty all permissions';

    Permissions =
        tabledata Customer = RIMD,
        codeunit "CLY Customer Events" = X;
}

Each object here uses the same ID, which is allowed because IDs are unique per object type, but change them as you add objects so they stay inside your range. Generate a fresh GUID for app.json. Set the runtime value to match your target BC version in the AL Language extension. Add a ToolTip on every page field to satisfy AppSource validation. Verify syntax in VS Code with the AL Language extension before publishing.

Planning to port NAV customisations to AL?

Optional: a review of which customisations to rebuild, replace with standard or retire.

Optional. The tool and every export work without this. No spam.

How to use the generator

Enter your publisher, app name, an object prefix and the ID range assigned to you, plus the name and length of a new field on the Customer table. Copy each block into its own .al or app.json file in VS Code with the AL Language extension. Compile, then publish to a sandbox with F5. Adapt the objects to your design rather than keeping the sample customer field.

Why extensions replace base code changes

In Business Central you do not change Microsoft's objects. A table extension adds fields to an existing table, a page extension adds controls to an existing page, and event subscribers react to published events instead of editing standard code. This keeps your changes separate, so Microsoft can update the base application without overwriting your work. It also makes your app installable per tenant and upgradeable.

  • Table extension: add fields and keys
  • Page extension: add or move controls
  • Event subscriber: run code at defined points
  • Permission set: grant access to your objects

Naming and ID conventions

Prefix object and field names to avoid collisions with other apps, and keep IDs inside the range declared in app.json. AppSource apps get ranges from Microsoft, while per-tenant extensions commonly use 50000 to 99999. Use DataClassification on every field you add, and write captions and tooltips for end users. Your permission set should be small and explicit, not SUPER.

Common mistakes

Using identical IDs across extension projects, forgetting permissions for new tables so users get errors in production, running code in OnInsert events on temporary records, and hard coding values that should be setup fields. Always test with a user who has only the roles they will have in real life.

Frequently Asked Questions

What files does a minimal AL extension need?

At minimum an app.json manifest and one .al object file. A realistic extension also has a permission set, captions and tooltips, and a launch.json for connecting to a sandbox environment.

What ID range should I use?

Per-tenant extensions typically use 50000 to 99999. For AppSource or partner apps, request a range from Microsoft. Keep every object in the range declared in app.json.

Why is the field not visible after publishing?

Check that the page extension is part of the app, the field has ApplicationArea set, and personalization is not hiding it. Also confirm the app published without errors in the extension management page.

Can I edit standard Business Central code?

Not in SaaS or modern on-premises versions. You extend through table and page extensions, events and interfaces. Where no event exists, you can request one from Microsoft on GitHub.

If you are moving NAV customisations into AL extensions, Netray can help inventory the code and plan what to rebuild.