{"id":501,"date":"2026-08-18T15:10:00","date_gmt":"2026-08-18T22:10:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/aspire\/?p=501"},"modified":"2026-08-18T15:10:46","modified_gmt":"2026-08-18T22:10:46","slug":"whats-new-aspire-13-5","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/aspire\/whats-new-aspire-13-5\/","title":{"rendered":"Aspire 13.5: Fresh pixels and better workflows"},"content":{"rendered":"<p>Aspire 13 thus far has been all about expanding Aspire&#8217;s capabilities across languages, deployment targets, and coding agents. We&#8217;ve shipped a full-parity TypeScript AppHost, tons of CLI features, an optimized docs workflow, Kubernetes and Docker Compose deployment integrations, and plenty more. We figured that after a crazy half of a year, it was time to take a step back, freshen up our look, and spend time on some much-requested quality-of-life features.<\/p>\n<p>Today, we shipped Aspire 13.5. The dashboard has a visual refresh, <a href=\"https:\/\/aspire.dev\">aspire.dev<\/a> has a redesigned homepage, and a pile of usability improvements smooth out even more of your day-to-day dev experience. This release also gives your AppHost more ways to interact with you directly, from file uploads and progress dialogs to a full terminal session hosted in the dashboard and accessible from the CLI.<\/p>\n<p>Deployment with Aspire has gotten more flexible, too. You can model persistent volumes for Kubernetes, reference existing Azure resources across subscriptions and tenants, and express more deployment specifics in C# or TypeScript in the AppHost so you never have to <a href=\"https:\/\/www.bonfire.com\/friends-dont-let-friends-write-yaml\/\">write YAML again<\/a>.<\/p>\n<p>This blog highlights some of my favorites. For the complete inventory, migration notes, and breaking changes, check out the <a href=\"https:\/\/aspire.dev\/whats-new\/aspire-13-5\/\">What&#8217;s new in Aspire 13.5<\/a> page on our docs.<\/p>\n<p><div  class=\"d-flex justify-content-center\"><a class=\"cta_button_link btn-primary mb-24\" href=\"https:\/\/get.aspire.dev\" target=\"_blank\">Get Aspire 13.5<\/a><\/div><\/p>\n<h2>\ud83c\udfa8 A fresh view of Aspire<\/h2>\n<p>Let&#8217;s start with the part you will notice immediately. Our website&#8217;s <a href=\"https:\/\/aspire.dev\">homepage<\/a> and the dashboard got a fresh coat of paint! The overall experience, layout, and features didn&#8217;t change, so everything is still where you expect it. We just thought it was time for an updated look and feel. Of course, we checked contrast and accessibility across the updated surfaces so the new look works great for everyone.<\/p>\n<p>The dashboard also got a lot of smaller improvements that you have been asking for:<\/p>\n<ul>\n<li>Filter console logs with a case-insensitive text search.<\/li>\n<li>Filter logs and traces by timestamp, or use exact numeric comparisons.<\/li>\n<li>Reconnect cleanly when the dashboard loses its resource-service connection.<\/li>\n<li>Friendlier health-check failures instead of raw exception stacks.<\/li>\n<li>Keep telemetry streaming correctly while resource filters are active.<\/li>\n<\/ul>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/aspire\/wp-content\/uploads\/sites\/90\/2026\/08\/aspire-dashboard-refresh.webp\" alt=\"The refreshed Aspire dashboard showing resources in the Stress playground\" \/><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/aspire\/wp-content\/uploads\/sites\/90\/2026\/08\/aspire-dev-homepage-light.webp\" alt=\"The redesigned aspire.dev homepage in light theme\" \/><\/p>\n<h2>\ud83d\udcac Your AppHost can ask for files<\/h2>\n<p>The <a href=\"https:\/\/aspire.dev\/extensibility\/interaction-service\/\">Interaction Service<\/a> and resource commands elevate Aspire from a fancy launch script to a customized developer experience that lives in your source. A resource command can ask for input, validate the answer, show a notification, or open a message box right where the developer is already working.<\/p>\n<p>In 13.5, we added file import support to commands. Picture a resource command named <strong>Import configuration<\/strong>. It opens a file picker that accepts JSON or YAML, enforces a size limit, sends the file to the AppHost, and gives the command a stream to read. No &#8220;put this file in a magic directory, then run the script from the README&#8221; detour.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/aspire\/wp-content\/uploads\/sites\/90\/2026\/08\/interaction-file-upload.webp\" alt=\"An Aspire resource command prompting for a configuration file\" \/><\/p>\n<p>Longer work can also now show a progress dialog with optional cancellation, and resource commands can declare named arguments that become input controls in the dashboard and <code>--name<\/code> options in the CLI. Together, that gives integration authors the pieces for a complete setup or import flow: collect exactly what the command needs, run the work, and return a useful result.<\/p>\n<p><div style=\"width: 1250px;\" class=\"wp-video\"><video class=\"wp-video-shortcode\" id=\"video-501-1\" width=\"1250\" height=\"720\" preload=\"metadata\" controls=\"controls\"><source type=\"video\/mp4\" src=\"https:\/\/devblogs.microsoft.com\/aspire\/wp-content\/uploads\/sites\/90\/2026\/08\/81Giz2QElHS97nYq.mp4?_=1\" \/><a href=\"https:\/\/devblogs.microsoft.com\/aspire\/wp-content\/uploads\/sites\/90\/2026\/08\/81Giz2QElHS97nYq.mp4\">https:\/\/devblogs.microsoft.com\/aspire\/wp-content\/uploads\/sites\/90\/2026\/08\/81Giz2QElHS97nYq.mp4<\/a><\/video><\/div><\/p>\n<p><div class=\"alert alert-primary\"><p class=\"alert-divider\"><i class=\"fabric-icon fabric-icon--Info\"><\/i><strong>Preview API<\/strong><\/p>The core Interaction Service and file input APIs are stable. Progress dialogs still use the experimental <code>ASPIREINTERACTION001<\/code> diagnostic in 13.5.<\/div><\/p>\n<h2>\ud83d\udda5\ufe0f We put a terminal in the dashboard<\/h2>\n<p>Some resources are not background services with logs. They are REPLs, shells, terminal user interfaces, and interactive tools that expect a real stdin and stdout. Until now, running one inside your distributed app meant keeping a separate terminal around and mentally matching it back to the resource in Aspire.<\/p>\n<p>In 13.5, add <code>WithTerminal()<\/code> and the resource gets an interactive terminal session inside the dashboard. You can type into it, switch between replicas, and move back to the normal console logs without stopping the session. Multiple viewers can attach at once, so a dashboard tab and a local terminal can watch the same process.<\/p>\n<p>The Aspire repository has a tiny guessing game playground for this. The game runs as a JavaScript resource from a TypeScript AppHost, and the whole thing is playable in the dashboard. It is a wonderfully unnecessary and yet perfect way to prove that the in-dashboard terminal is real \ud83d\ude2c<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/aspire\/wp-content\/uploads\/sites\/90\/2026\/08\/aspire-terminal-guessing-game.webp\" alt=\"A guessing game running in the Aspire dashboard terminal\" \/><\/p>\n<p>The matching <code>aspire terminal<\/code> commands can list sessions and attach from your shell after you enable the terminal command feature flag.<\/p>\n<p><div class=\"alert alert-primary\"><p class=\"alert-divider\"><i class=\"fabric-icon fabric-icon--Info\"><\/i><strong>Preview API<\/strong><\/p><code>WithTerminal()<\/code> and the <code>aspire terminal<\/code> commands are experimental in 13.5. Resources using a terminal run as plain processes for now, so attach the debugger manually when you need it.<\/div><\/p>\n<p>Learn how to <a href=\"https:\/\/aspire.dev\/app-host\/with-terminal\/\">test terminal apps with <code>WithTerminal()<\/code><\/a>.<\/p>\n<h2>\u2601\ufe0f More ways to describe your production deployment<\/h2>\n<p>The AppHost should describe the infrastructure your app actually uses. Aspire 13.5 makes that model more complete for both Kubernetes workloads and existing Azure resources.<\/p>\n<h3>Persistent storage for Kubernetes workloads<\/h3>\n<p>You can add a persistent volume to a Kubernetes or AKS environment, configure its storage class, capacity, and access mode, then bind it to a project or container workload.<\/p>\n<pre><code class=\"language-csharp\">var k8s = builder.AddKubernetesEnvironment(\"k8s\");\n\nvar data = k8s.AddPersistentVolume(\"data\")\n    .WithStorageClass(\"managed-csi\")\n    .WithCapacity(\"20Gi\")\n    .WithAccessMode(PersistentVolumeAccessMode.ReadWriteOnce);\n\nbuilder.AddContainer(\"postgres\", \"postgres:16\")\n    .WithVolume(\"data\", \"\/var\/lib\/postgresql\/data\")\n    .WithPersistentVolume(data);<\/code><\/pre>\n<p>PostgreSQL needs durable storage, so you say so next to PostgreSQL. Aspire emits the persistent volume claim and renders the workload as a <code>StatefulSet<\/code>.<\/p>\n<p><div class=\"alert alert-primary\"><p class=\"alert-divider\"><i class=\"fabric-icon fabric-icon--Info\"><\/i><strong>Preview API<\/strong><\/p>The compute-environment persistent volume APIs are experimental and use the <code>ASPIRECOMPUTE002<\/code> diagnostic in 13.5.<\/div><\/p>\n<p>See the full <a href=\"https:\/\/aspire.dev\/deployment\/kubernetes\/persistent-volumes\/\">persistent volumes guide<\/a> for C# and TypeScript examples.<\/p>\n<h3>Existing Azure resources stay in the model<\/h3>\n<p>Your app might use a shared Service Bus namespace, a resource owned by another team, or infrastructure outside its resource group. Aspire 13.5 adds <code>AsExistingInResourceGroup(...)<\/code>, <code>AsExistingInSubscription(...)<\/code>, and <code>AsExistingInTenant(...)<\/code>, plus run-mode and publish-mode variants.<\/p>\n<pre><code class=\"language-csharp\">var name = builder.AddParameter(\"service-bus-name\");\nvar resourceGroup = builder.AddParameter(\"service-bus-resource-group\");\nvar subscription = builder.AddParameter(\"service-bus-subscription\");\n\nbuilder.AddAzureServiceBus(\"messaging\")\n    .AsExistingInResourceGroup(name, resourceGroup, subscription);<\/code><\/pre>\n<p>Names and scopes can be literal values or Aspire parameters, keeping environment details out of the AppHost source while references, configuration, and deployment intent stay in the model.<\/p>\n<p>Read more about <a href=\"https:\/\/aspire.dev\/integrations\/cloud\/azure\/customize-resources\/\">using existing Azure resources<\/a>.<\/p>\n<h2>\u2728 Easier than ever to get started with Homebrew, WinGet, and more<\/h2>\n<p>Over the last couple of months, we&#8217;ve expanded our release process to ship the Aspire CLI through Homebrew, WinGet, npm, Nix, mise, and NuGet! Now you can use your package manager of choice to install and update the Aspire CLI. <code>aspire update --self<\/code> still works, too, no matter where you originally installed the CLI.<\/p>\n<h2>\ud83d\udcab Try Aspire 13.5<\/h2>\n<p>Update the CLI and your projects:<\/p>\n<pre><code class=\"language-bash\">aspire update --self\naspire update<\/code><\/pre>\n<p>If you have an older TypeScript AppHost, <code>aspire update --migrate<\/code> can move <code>apphost.ts<\/code> to the current <code>apphost.mts<\/code> format.<\/p>\n<p>Then, build out some features for command-driven file uploads, persistent Kubernetes-managed storage, or watch <a href=\"https:\/\/github.com\/mitchdenny\/aspire-loves-terminals\/tree\/main\/starwars-ssh\">ASCII Star Wars<\/a> in the refreshed dashboard.<\/p>\n<p><strong>New to Aspire?<\/strong> <a href=\"https:\/\/get.aspire.dev\">Install the CLI<\/a> from your package manager of choice, and try the <a href=\"https:\/\/aspire.dev\/get-started\/add-aspire-existing-app-typescript-apphost\/\">Aspireify<\/a> skill on your existing apps.<\/p>\n<p>Share feedback on <a href=\"https:\/\/github.com\/microsoft\/aspire\">GitHub<\/a>, join us on <a href=\"https:\/\/aka.ms\/aspire-discord\">Discord<\/a>, follow <a href=\"https:\/\/x.com\/aspiredotdev\">@aspiredotdev on X<\/a>, or find us on <a href=\"https:\/\/bsky.app\/profile\/aspire.dev\">BlueSky<\/a>.<\/p>\n<p>Happy Aspirifying! \ud83d\udcab<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Aspire 13.5 refreshes the dashboard and aspire.dev, expands the Interaction Service, adds cross-scope Azure references and Kubernetes persistent volumes, and brings live terminals into the AppHost.<\/p>\n","protected":false},"author":1965,"featured_media":505,"comment_status":"open","ping_status":"closed","sticky":true,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1,52],"tags":[26,9,23,53,70],"class_list":["post-501","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-aspire-category","category-releases","tag-apphost","tag-aspire","tag-azure","tag-dashboard","tag-kubernetes"],"acf":[],"blog_post_summary":"<p>Aspire 13.5 refreshes the dashboard and aspire.dev, expands the Interaction Service, adds cross-scope Azure references and Kubernetes persistent volumes, and brings live terminals into the AppHost.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/aspire\/wp-json\/wp\/v2\/posts\/501","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/aspire\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/aspire\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/aspire\/wp-json\/wp\/v2\/users\/1965"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/aspire\/wp-json\/wp\/v2\/comments?post=501"}],"version-history":[{"count":2,"href":"https:\/\/devblogs.microsoft.com\/aspire\/wp-json\/wp\/v2\/posts\/501\/revisions"}],"predecessor-version":[{"id":509,"href":"https:\/\/devblogs.microsoft.com\/aspire\/wp-json\/wp\/v2\/posts\/501\/revisions\/509"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/aspire\/wp-json\/wp\/v2\/media\/505"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/aspire\/wp-json\/wp\/v2\/media?parent=501"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/aspire\/wp-json\/wp\/v2\/categories?post=501"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/aspire\/wp-json\/wp\/v2\/tags?post=501"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}