Wednesday, January 14, 2026

Developing Business Central Extensions : Naming conventions and VS Code launch.json strategy for multi-app repo

 Here’s a battle-tested, simple structure for one repo hosting many Business Central extensions, plus a clean naming/ID/range/versioning standard that won’t hurt you later when you add CI/CD.


Recommended repo structure (one repo, many apps)

Option A (recommended): One folder per extension under /apps

Works great with pipelines later, easy to clone anywhere.

bc-extensions/

  README.md

  .gitignore

  .editorconfig                 (optional)

  .azure-pipelines/             (later)

 

  apps/

    CustomerExt-01/

      src/                      (AL project lives here)

        app.json

        .vscode/

          launch.json

          settings.json

        HelloWorld.al           (or your objects)

        tables/

        pageextensions/

        codeunits/

      docs/                     (optional: specs)

        overview.md

      test/                     (optional: test app later)

 

    VendorExt-01/

      src/

        app.json

        .vscode/...

        ...

 

  tools/                        (optional)

    scripts/

Why this is best

  • Each app is self-contained.
  • Developers open apps/<AppName>/src and they’re productive immediately.
  • CI/CD can build all apps or only changed apps.

Option B: Monorepo with shared “workspace” and common VS Code config

Only do this if your team is mature with AL tooling; otherwise it adds complexity.


VS Code launch.json strategy for multi-app repo

You have two clean choices:

Choice 1 (simplest): each app has its own .vscode/launch.json

  • Each apps/<AppName>/src/.vscode/launch.json targets the correct sandbox.
  • No confusion—open that app’s src folder and publish.

Choice 2 (more advanced): one shared .vscode at repo root

  • Use variables / multiple configurations, but it’s easier to mess up.
  • I’d avoid until CI/CD is in.

Naming standards

Repo name

  • bc-extensions (if it hosts multiple)
  • OR bc-<customer>-extensions (if dedicated to one customer)

App folder name

Use: PascalCase + short suffix:

  • CustomerExt-01
  • SalesEnhancements-01
  • IntegrationPack-01

app.json name

Match folder:

  • "name": "CustomerExt-01"

app.json publisher

Use one publisher consistently (important later for upgrades):

  • "publisher": "MicroCloud 360"

Avoid “Default Publisher” once you start real work.


App IDs (GUIDs)

Rule

  • One unique GUID per extension app
  • Never change it after first release (changing ID breaks upgrade path)

Practical approach

  • Let AL generate it once.
  • Store it forever in app.json.

Tip: Keep a small registry in /README.md or /docs/apps.md listing:

  • App Name
  • App ID (GUID)
  • Range
  • Purpose

Example:

App

App ID

Range

CustomerExt-01

xxxxxxxx-xxxx-...

50100–50149


Object range strategy (IDs)

You need a clean plan so multiple apps never collide.

Option A (simple and scalable): allocate blocks per app

Example allocation (easy to remember):

  • CustomerExt-01: 50100–50149
  • VendorExt-01: 50150–50199
  • SalesExt-01: 50200–50249
  • IntegrationExt-01: 50250–50299

This works well if you keep apps small.

Option B (more enterprise): allocate blocks per domain

  • Customers: 50100–50999
  • Vendors: 51000–51999
  • Sales: 52000–52999

Then each app inside the domain takes a smaller block.

Recommendation for you

Since you’re building multiple discrete extensions: Option A (block per app) is the cleanest.


Versioning standard (app.json version)

Use Semantic-ish versioning

MAJOR.MINOR.PATCH.BUILD

  • MAJOR: breaking change / major release (rare)
  • MINOR: new feature
  • PATCH: bugfix
  • BUILD: optional increment for internal builds

Examples:

  • 1.0.0.0 first release
  • 1.0.1.0 bugfix release
  • 1.1.0.0 new features
  • 2.0.0.0 breaking change

Practical rule (easy to follow)

  • For each change you deploy to sandbox: bump PATCH
  • For new features: bump MINOR
  • For hotfixes: bump PATCH
  • Ignore BUILD unless CI uses it later

Runtime / platform / application fields

Keep runtime aligned with your BC version

If your SaaS is current (v25/26/27 etc), typical runtime is 13+, 14+, 15+, 16+, 17+ depending on the environment.

Rule:

  • Don’t guess—use what your sandbox expects (your earlier issue was caused by runtime mismatch).

Recommended approach

  • After creating the project, download symbols successfully, then keep:
    • "platform" and "application" consistent with your environment symbols.
  • If symbols download is ok, your platform/application is typically fine.

Git branching / workflow (simple but correct)

Branches

  • main (protected ideally)
  • feature branches per change:
    • feature/customer-fields
    • bugfix/customer-card-tooltip

Commit message standard

  • CustomerExt-01: Add MC Reviewed fields
  • VendorExt-01: Fix validation in posting

Tagging (later)

When you release a version:

  • tag: CustomerExt-01/v1.1.0

.gitignore for multi-app repo

At repo root:

# AL generated artifacts (in any app)

**/.alpackages/

**/.alcache/

**/.snapshots/

**/*.app

 

# VS Code - keep only shared config if you want

**/.vscode/*

!**/.vscode/launch.json

!**/.vscode/settings.json

 

# OS

.DS_Store

Thumbs.db


“Open the right folder” rule (avoids confusion)

When working on an app:
Open folder:

  • apps/CustomerExt-01/src

Not the repo root, not /apps, not src of another app.


Suggested “starter template” per app (clean folders)

Inside each src:

src/

  app.json

  .vscode/

    launch.json

    settings.json

  tableextensions/

  pageextensions/

  codeunits/

  permissionsets/

  profiles/              (optional)

No comments:

Post a Comment

Business Central SaaS Extension Design: Implementing Plant Tracking with AL Event Subscribers

  Extending Business Central SaaS: Plant Tracking Using AL Extensions  1️⃣ Problem Statement In many manufacturing and service-oriented or...