[docs] Document appsettings.json support for TypeScript AppHosts - #1597
Conversation
Documents that polyglot (TypeScript) AppHosts now load appsettings.json
and appsettings.{Environment}.json from the guest AppHost directory,
per microsoft/aspire#19719.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Frontend HTML artifact readyThe latest frontend build uploaded the This comment updates automatically when a new frontend build artifact is uploaded. |
David Pine (IEvangelist)
left a comment
There was a problem hiding this comment.
Automated docs-accuracy review
Source of truth: microsoft/aspire @ main (HEAD 1cdf7d17248ae78ee018abbc314f772ace5e624d).
⚠️ Branch note (non-blocking): This PR targetsrelease/13.6, which does not exist inmicrosoft/aspire. The source change (microsoft/aspire#19719, "Load polyglot AppHost settings from project root", mergeade22c6ed1) is merged onmainbut not yet in a GA release (latest tagv13.5.3; nov13.6tag). I verified every claim againstupstream/main. Re-confirm againstrelease/13.6if that branch is later cut.
Phase A — claims: 6 non-narrative claims extracted → ✅ 6 verified, 0 verified-with-nuance, 0 unverifiable, 0 contradicted.
Phase B — doc-tester: 1 route exercised (/app-host/typescript-apphost/) → 0 critical, 0 warnings; 1 knowledge gap (local build predates PR — mitigated).
The documented API chain, the guest-directory content-root behavior, the preserved-but-overridable logging defaults, and the getConfigValue("Deployment:Region") example all match the merged source (the example is copied verbatim from the PR's own spec).
Phase A — Claim verification
No contradicted or unverifiable claims, so there are no inline blocking comments. All evidence is below for audit.
✅ 6 verified claims (click to expand)
| id | claim | evidence (microsoft/aspire @ main) |
|---|---|---|
| C1 | TS AppHosts load appsettings.json + appsettings.{Environment}.json placed next to apphost.mts into the AppHost configuration (alongside env vars + CLI args) |
ade22c6ed1 — DistributedApplication.cs sets realOptions.ContentRootPath = options.ProjectDirectory; DistributedApplicationBuilder.cs passes it into HostApplicationBuilderSettings { ContentRootPath = … }, so the standard HostApplicationBuilder loads appsettings.json / appsettings.{Env}.json from the content root. Commit: "Use the guest AppHost directory as the inner host content root." |
| C2 | FileTree: appsettings.json / appsettings.Development.json sit next to apphost.mts (with .aspire/modules/, aspire.config.json, package.json) |
Placement follows from C1/C4 (content root = guest AppHost dir = where apphost.mts lives); the other entries are pre-existing TS-AppHost structure already documented on the page. |
| C3 | const builder = await createBuilder(); const configuration = await builder.getConfiguration(); const region = await configuration.getConfigValue("Deployment:Region"); |
src/Aspire.Hosting/Ats/BuilderExports.cs — [AspireExport] GetConfiguration(this IDistributedApplicationBuilder) -> IConfiguration and [AspireExport] GetConfigValue(this IConfiguration, string key) -> string?. Public API surface Aspire.Hosting/getConfigValue(key: string) -> string (api/Aspire.Hosting.Capabilities.txt:301). Double-await shape matches .github/workflows/polyglot-validation/test-typescript.sh await (await builder.getConfiguration()).getConfigValue(...). |
| C4 | Configuration resolves relative to the guest AppHost directory (where apphost.mts lives), not the CLI-owned managed-server directory |
ade22c6ed1 DistributedApplication.cs comment: "The polyglot AppHost runs in a separate guest process, so the managed server's working directory does not point at the user's appsettings files." → ContentRootPath = options.ProjectDirectory. |
| C5 | The managed server's own logging defaults are preserved, but application settings can still override them | ade22c6ed1 — s_polyglotConfigurationDefaults (Logging:LogLevel:Default=Information, Microsoft.AspNetCore=Warning, Aspire.Hosting.Dcp=Warning) is added via configuration.AddInMemoryCollection(options.DefaultConfiguration) before env/host-default sources: "Keep them as fallbacks so every user configuration source can override them while existing AppHosts retain the same logging behavior." |
| C6 | getConfigValue("Deployment:Region") colon key-path maps to nested JSON {"Deployment":{"Region":"westus"}} |
GetConfigValue delegates to the standard IConfiguration indexer (: hierarchy separator); the identical example appears in the source spec docs/specs/polyglot-apphost.md:1382. |
Phase B — Doc-tester results
Playwright-only run against the local docs frontend; no
microsoft/aspiresource was consulted in this phase.
Route exercised: /app-host/typescript-apphost/
| Category | Passed | Failed | Warnings |
|---|---|---|---|
| Page health (HTTP/console) | 1 | 0 | 0 |
| Reused component rendering | 1 | 0 | 0 |
| Insertion-region integrity | 1 | 0 | 0 |
Critical issues: none.
Warnings: none (from a blind-user perspective).
Passed checks
/app-host/typescript-apphost/— HTTP 200, title "TypeScript AppHost project structure | Aspire". 0 console errors (8 benign Vite dev-serverNo popup container foundwarnings, content-independent).- Reused components render: the page already shows a
<FileTree>with.aspire/modules/ # Generated TypeScript SDK (do not edit),apphost.mts, andaspire.config.json(the exact entries the new FileTree reuses);NoteandTip<Aside>landmarks render (the new section reusesAside type="note");json/typescriptcode fences already render. The PR introduces no new component types. - Insertion region intact: the new H2 is inserted before the existing "## Package managers" section, which renders; the preceding Legacy-
apphost.tsAside renders.
Knowledge gap — local docs build predates this PR: The served HTML contains neither the new "Configuration with appsettings.json" heading nor the string getConfigValue, so I could not exercise the new prose/examples directly as a blind user. Mitigation: validated page health, confirmed every reused component already renders on this page, confirmed the insertion point is intact, and confirmed the section adds no new internal links. The twoslash TypeScript block is type-checked by CI (out of scope). This is a test-environment limitation, not a documentation defect.
Verdict: APPROVE
All 6 non-narrative claims are verified against microsoft/aspire @ main (source PR #19719 is merged), the TypeScript API chain and behavior match the merged implementation and spec, and the doc-tester run found no critical issues or warnings. The only caveat is the informational branch-name mismatch (release/13.6 not present in microsoft/aspire); re-confirm against that branch if/when it is cut.
🤖 Automated Phase A (source-of-truth claims) + Phase B (doc-tester) review. Phase A read microsoft/aspire @ main; Phase B used Playwright against the local docs site only.
Rewrite the Configuration section on the TypeScript AppHost page to describe appsettings.json purely as a JSON configuration system for TypeScript, using camelCase keys, a case-insensitive lookup note, and an ASPIRE_ENVIRONMENT-based environment section. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR updates the TypeScript AppHost documentation to describe newly supported appsettings.json (and appsettings.{Environment}.json) configuration loading for polyglot/TypeScript AppHosts, including how to read configuration values from apphost.mts.
Changes:
- Add a “Configuration with appsettings.json” section describing file placement and load/override behavior.
- Add JSON + TypeScript samples using
builder.getConfiguration()andconfiguration.getConfigValue(...). - Add OS-specific terminal snippets for setting the environment via
ASPIRE_ENVIRONMENT(usingOsAwareTabs).
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
|
|
||
| Aspire always loads `appsettings.json` first, then layers `appsettings.{environment}.json` on top when its name matches the active environment. Values in the environment file override the base file, so you can keep shared defaults in `appsettings.json` and change only what differs per environment in files such as `appsettings.Development.json` or `appsettings.Production.json`. | ||
|
|
||
| The active environment is selected by the `ASPIRE_ENVIRONMENT` environment variable. For example, set it to `Development` to load `appsettings.Development.json` over the base file when you run the AppHost: |
| </OsAwareTabs> | ||
|
|
||
| <Aside type="note"> | ||
| Aspire looks for `appsettings.json` and `appsettings.{environment}.json` in the same directory as `apphost.mts`. Environment variables and command-line arguments take precedence over both files, so you can override any setting at run time without editing JSON. |
David Pine (IEvangelist)
left a comment
There was a problem hiding this comment.
Docs-accuracy review — cannot verify (source-of-truth branch missing)
Verdict: COMMENT — no claims verified, doc-tester (Phase B) not run.
This PR targets release/13.6 on microsoft/aspire.dev. My claim-verification protocol requires the matching release branch in microsoft/aspire as the sole source of truth, and that branch does not exist yet:
microsoft/aspirerelease branches currently top out atrelease/13.5(b5f14331…). There is norelease/13.6branch.- The source change this PR documents, microsoft/aspire#19719 (milestone 13.6), was merged to
main(ade22c6e…) on 2026-08-31 — so theappsettings.jsonsupport described here currently lives onmain, not on a cutrelease/13.6branch.
Because the release branch that corresponds to this PR hasn't been cut, I can't pin the claims to the required source-of-truth branch, and I do not verify release-targeted docs against main (which may already contain post-13.6 drift). Per the reviewer's source-of-truth rule I'm stopping here rather than guessing — I have intentionally not run the Phase A claim checks against a fallback branch and not run the Phase B doc-tester pass.
What unblocks a full review: re-target this PR once release/13.6 is cut in microsoft/aspire, or confirm the intended source-of-truth branch. The next review pass will then run the full claim-verification + doc-tester checks.
Source-of-truth checked: microsoft/aspire (git ls-remote --heads upstream 'release/*' → highest release/13.5 = b5f143315ffb6968ea939a9978797a5b20e4c688; source PR #19719 base main, merge ade22c6ed10c25eee2398184c5d114351e5338b5).
Replace the ASPIRE_ENVIRONMENT example with the single aspire start --environment CLI command, add a LearnMore link to the aspire start CLI reference, and drop the now-unused OsAwareTabs import. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Adam Ratzman (adamint)
left a comment
There was a problem hiding this comment.
No issues from this review.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Alistair Matthews (alistairmatthews)
left a comment
There was a problem hiding this comment.
I think some clearer wording would improve this. Otherwise it's good to go.
|
|
||
| ## Configuration with appsettings.json | ||
|
|
||
| TypeScript AppHosts read configuration from JSON files that live next to `apphost.mts`. Add an `appsettings.json` file to your AppHost and Aspire loads it into the AppHost's configuration at startup. You read the effective values in `apphost.mts` through the builder's configuration accessor. |
There was a problem hiding this comment.
This is a little bit clearer with regards to who does what - the developer and Aspire.
| TypeScript AppHosts read configuration from JSON files that live next to `apphost.mts`. Add an `appsettings.json` file to your AppHost and Aspire loads it into the AppHost's configuration at startup. You read the effective values in `apphost.mts` through the builder's configuration accessor. | |
| TypeScript AppHosts read configuration from JSON files that live next to `apphost.mts`. If you add an `appsettings.json` file to your AppHost then Aspire loads it into the AppHost's configuration at startup. Aspire reads the effective values in `apphost.mts` by using the builder's configuration accessor. |
|
|
||
| #### Development | ||
|
|
||
| Add the Development overrides: |
There was a problem hiding this comment.
| Add the Development overrides: | |
| To add overridden settings for the `Development` environment, use JSON code like this: |
| } | ||
| ``` | ||
|
|
||
| Start the AppHost with the `Development` environment: |
There was a problem hiding this comment.
| Start the AppHost with the `Development` environment: | |
| Those overridden settings apply when you start the AppHost with the `Development` environment: |
|
|
||
| #### Production | ||
|
|
||
| Add the Production overrides: |
There was a problem hiding this comment.
| Add the Production overrides: | |
| Similarly, you can control overridden settings for the Production environment like this: |
| } | ||
| ``` | ||
|
|
||
| Start the AppHost with the `Production` environment: |
There was a problem hiding this comment.
| Start the AppHost with the `Production` environment: | |
| Then, to apply Production settings, start the AppHost with the `Production` environment: |
Documents changes from microsoft/aspire#19719
@sebastienrosTargeting
release/13.6based on the source PR milestone13.6(exact match onmicrosoft/aspire.dev).Why
microsoft/aspire#19719 roots the inner distributed application host at the guest AppHost directory for polyglot (TypeScript) AppHosts, so the server-side application builder can now discover
appsettings.jsonfiles next toapphost.mts. TypeScript AppHosts previously had no documented way to load structured application settings, and the PR's own "User-facing usage" section (triggered signalpr_body_has_user_facing_section) describes exactly this new capability:appsettings.json(and optionalappsettings.{Environment}.json) next toapphost.mts.apphost.mtsviaawait builder.getConfiguration()andawait configuration.getConfigValue("Key:Path").This wasn't documented anywhere on aspire.dev, so a docs update is required.
What changed
Added a new "Configuration with appsettings.json" section to
src/frontend/src/content/docs/app-host/typescript-apphost.mdx(the main TypeScript AppHost reference page), including:FileTreeshowing whereappsettings.json/appsettings.{Environment}.jsonlive relative toapphost.mts.appsettings.json.builder.getConfiguration()andconfiguration.getConfigValue(...), copied verbatim from the source PR's example.Asidenote clarifying that configuration resolves relative to the guest AppHost directory (not the CLI-owned managed-server directory), and that managed server logging defaults are preserved but overridable by application settings — this nuance comes directly from the PR description.Files modified
src/frontend/src/content/docs/app-host/typescript-apphost.mdx(updated, existing page)No new pages were created; this is an addition to an existing, actively maintained reference page.