Skip to content
cccskills
FreePublished on GitHub

aspire-ts

Orchestrate JavaScript/TypeScript applications with .NET Aspire. Use when building Node.js APIs, React/Vue/Svelte frontends, or Vite apps that need service discovery, telemetry, and deployment orchestration via Aspire's AppHost. Covers AddViteApp, AddNodeApp, AddJavaScriptApp, package mana...

The English summary is being prepared. Showing the original description.

Run score Not tested

See how to install

Files included (7)

  • SKILL.md12.6 KB
  • references/acceptance-criteria.md2.5 KB
  • references/apphost-patterns.md5.4 KB
  • references/azure-integrations.md7.2 KB
  • references/deployment-cicd.md5.6 KB
  • references/service-discovery-networking.md5.4 KB
  • references/telemetry-observability.md6.8 KB

SKILL.md (original)

Review the instructions the agent will receive before you install.

.NET Aspire for JavaScript/TypeScript

Orchestrate JavaScript and TypeScript applications using .NET Aspire's AppHost. Aspire treats JS/TS apps as first-class resources alongside .NET services, containers, and cloud infrastructure — providing service discovery, telemetry, health monitoring, and deployment from a single code-first model.

Important: The AppHost is always written in C#, even when orchestrating JS/TS apps. The Aspire.Hosting.JavaScript NuGet package provides the hosting APIs.

Prerequisites

  • .NET SDK 10.0+ — Required for the Aspire AppHost
  • Aspire CLI installed (aspire --version)
  • Node.js 22+ with npm, yarn, or pnpm
  • NuGet package: Aspire.Hosting.JavaScript in your AppHost project
# Install in AppHost project
dotnet add package Aspire.Hosting.JavaScript

# For file-based AppHost (apphost.cs), use directive:
#:package Aspire.Hosting.JavaScript@13.1.0

Resource Types

Three methods to add JS/TS apps to the AppHost:

MethodUse CaseEntry Point
AddViteAppVite-based apps (React, Vue, Svelte)npm script (dev)
AddNodeAppNode.js apps with direct file entryJavaScript file
AddJavaScriptAppGeneral JS apps with npm scriptsnpm script (dev)

AddViteApp — Vite Applications

Best for React, Vue, Svelte, and other Vite-based frontends.

var builder = DistributedApplication.CreateBuilder(args);

var api = builder.AddProject<Projects.Api>("api");

var frontend = builder.AddViteApp("frontend", "./packages/web")
    .WithExternalHttpEndpoints()
    .WithReference(api)
    .WaitFor(api);

builder.Build().Run();

Defaults:

  • Runs dev script during development
  • Runs build script when publishing
  • Auto-generates Dockerfile for production
  • Auto-detects package manager from lockfiles

AddNodeApp — Node.js Applications

For Node.js servers with a direct JavaScript entry point.

var api = builder.AddNodeApp("api", "./packages/api", "src/server.js")
    .WithNpm()
    .WithHttpEndpoint(port: 3000, env: "PORT")
    .WithHttpHealthCheck("/health");

Parameters:

  • name — Resource name in Aspire dashboard
  • appDirectory — Path to directory containing the app
  • scriptPath — Path to the JS file to run (relative to appDirectory)

AddJavaScriptApp — Generic JavaScript

For any JS app using npm scripts. Foundation for both AddViteApp and AddNodeApp.

var app = builder.AddJavaScriptApp("app", "./frontend")
    .WithHttpEndpoint(port: 3000, env: "PORT");

Defaults: Uses npm, runs dev script in development, build script when publishing.


Package Managers

npm (Default)

var app = builder.AddViteApp("frontend", "./frontend");
// npm is used automatically

// Customize npm behavior:
var app2 = builder.AddViteApp("frontend", "./frontend")
    .WithNpm(installCommand: "ci", installArgs: ["--legacy-peer-deps"]);

yarn

var app = builder.AddViteApp("frontend", "./frontend")
    .WithYarn();

// With custom args:
var app2 = builder.AddViteApp("frontend", "./frontend")
    .WithYarn(installArgs: ["--immutable"]);

pnpm

var app = builder.AddViteApp("frontend", "./frontend")
    .WithPnpm();

// With custom args:
var app2 = builder.AddViteApp("frontend", "./frontend")
    .WithPnpm(installArgs: ["--frozen-lockfile"]);

Auto-install: All package managers install dependencies automatically before running. In publish mode, deterministic install commands are used (npm ci, yarn install --immutable, pnpm install --frozen-lockfile) when lockfiles exist.


Service Discovery

When you call .WithReference(api), Aspire injects environment variables into the JS app:

var api = builder.AddNodeApp("api", "./api", "server.js")
    .WithNpm()
    .WithHttpEndpoint(port: 3000, env: "PORT");

var frontend = builder.AddViteApp("frontend", "./frontend")
    .WithReference(api)      // Injects API_HTTP and API_HTTPS env vars
    .WaitFor(api);

Consuming in JavaScript/TypeScript

// Access injected service URLs
const apiUrl = process.env.API_HTTP || process.env.API_HTTPS;

// For databases and other resources
const redisHost = process.env.CACHE_HOST;
const redisPort = process.env.CACHE_PORT;
const pgConnectionString = process.env.POSTGRESDB_CONNECTIONSTRING;

Environment variable naming: {RESOURCE_NAME}_{PROPERTY} (uppercase, underscores).

Resource TypeVariables Injected
HTTP service{NAME}_HTTP, {NAME}_HTTPS
Redis{NAME}_HOST, {NAME}_PORT, {NAME}_URI
PostgreSQL DB{NAME}_HOST, {NAME}_PORT, {NAME}_URI, {NAME}_DATABASENAME
Connection stringConnectionStrings__{name}

Endpoints & Networking

Configure HTTP endpoint

var app = builder.AddViteApp("frontend", "./frontend")
    .WithHttpEndpoint(port: 3000, env: "PORT");
  • port — Host port (exposed to browser/other services)
  • env — Environment variable name set to the internal target port
  • Aspire inserts a reverse proxy between host port and app port

External endpoints

Mark endpoints as externally accessible (browser-facing):

var frontend = builder.AddViteApp("frontend", "./frontend")
    .WithExternalHttpEndpoints();

HTTPS with developer certificate (Vite)

var app = builder.AddViteApp("frontend", "./frontend")
    .WithHttpsEndpoint(env: "PORT")
    .WithHttpsDeveloperCertificate();

Aspire auto-injects HTTPS config into Vite without modifying vite.config.js.


Scripts & Arguments

Custom run/build scripts

var app = builder.AddJavaScriptApp("app", "./app")
    .WithRunScript("start")      // Use "npm run start" instead of "dev"
    .WithBuildScript("prod");    // Use "npm run prod" instead of "build"

Pass arguments

// Option 1: WithArgs
var app = builder.AddViteApp("frontend", "./frontend")
    .WithArgs("--no-open");

// Option 2: Custom script in package.json
// package.json: { "scripts": { "dev:no-open": "vite --no-open" } }
var app2 = builder.AddViteApp("frontend", "./frontend")
    .WithRunScript("dev:no-open");

Custom Vite config file

var app = builder.AddViteApp("frontend", "./frontend")
    .WithViteConfig("./vite.production.config.js");

OpenTelemetry for Node.js

Configure telemetry so JS/TS apps report to the Aspire dashboard.

Install packages

npm install @opentelemetry/api @opentelemetry/sdk-node \
  @opentelemetry/auto-instrumentations-node \
  @opentelemetry/exporter-trace-otlp-grpc \
  @opentelemetry/exporter-metrics-otlp-grpc

Create telemetry.js (must be imported first)

const { NodeSDK } = require('@opentelemetry/sdk-node');
const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node');
const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-grpc');
const { OTLPMetricExporter } = require('@opentelemetry/exporter-metrics-otlp-grpc');
const { PeriodicExportingMetricReader } = require('@opentelemetry/sdk-metrics');
const { resourceFromAttributes } = require('@opentelemetry/resources');
const { ATTR_SERVICE_NAME } = require('@opentelemetry/semantic-conventions');

const otlpEndpoint = process.env.OTEL_EXPORTER_OTLP_ENDPOINT || 'http://localhost:4317';

const sdk = new NodeSDK({
    resource: resourceFromAttributes({ [ATTR_SERVICE_NAME]: 'frontend' }),
    traceExporter: new OTLPTraceExporter({ url: otlpEndpoint }),
    metricReader: new PeriodicExportingMetricReader({
        exporter: new OTLPMetricExporter({ url: otlpEndpoint }),
    }),
    instrumentations: [getNodeAutoInstrumentations()],
});

sdk.start();

Import first in app entry point

require('./telemetry'); // Must be first!
const express = require('express');
// ... rest of app

Aspire auto-sets OTEL_EXPORTER_OTLP_ENDPOINT for orchestrated resources.


Integrations (Redis, PostgreSQL, etc.)

Redis

// AppHost
var cache = builder.AddRedis("cache");

var app = builder.AddNodeApp("api", "./api", "server.js")
    .WithNpm()
    .WithReference(cache);  // Injects CACHE_HOST, CACHE_PORT, CACHE_URI
// Node.js
const redis = require('redis');
const client = redis.createClient({
    socket: { host: process.env.CACHE_HOST, port: process.env.CACHE_PORT }
});

PostgreSQL

// AppHost
var postgres = builder.AddAzurePostgresFlexibleServer("postgres")
    .RunAsContainer();
var db = postgres.AddDatabase("mydb");

var app = builder.AddNodeApp("api", "./api", "server.js")
    .WithNpm()
    .WithReference(db);  // Injects MYDB_HOST, MYDB_PORT, MYDB_URI, etc.
// Node.js
const { Client } = require('pg');
const client = new Client({
    host: process.env.MYDB_HOST,
    port: process.env.MYDB_PORT,
    database: process.env.MYDB_DATABASENAME,
});

Polyglot Patterns

Mix JS/TS apps with .NET, Python, and containers in one AppHost:

var builder = DistributedApplication.CreateBuilder(args);

// Infrastructure
var cache = builder.AddRedis("cache");
var db = builder.AddPostgres("postgres").AddDatabase("appdb");

// .NET API
var api = builder.AddProject<Projects.Api>("api")
    .WithReference(db)
    .WithReference(cache);

// Node.js microservice
var worker = builder.AddNodeApp("worker", "./worker", "index.js")
    .WithNpm()
    .WithReference(cache);

// React frontend
var frontend = builder.AddViteApp("frontend", "./frontend")
    .WithExternalHttpEndpoints()
    .WithReference(api)
    .WaitFor(api);

builder.Build().Run();

Deployment

aspire run (Development)

aspire run

JS/TS apps run as Node.js processes (not containerized). Aspire dashboard launches with logs, traces, and metrics.

aspire deploy (Containerized)

aspire deploy

Aspire auto-generates Dockerfiles, builds container images, and deploys. JS apps become Docker containers.

aspire publish (CI/CD artifacts)

aspire publish --output-path ./aspire-output

Generates docker-compose.yaml and .env files for deployment.

Docker Compose output

Aspire generates production-ready Docker Compose for JS/TS apps:

  • Auto-generated multi-stage Dockerfile
  • Deterministic dependency install from lockfiles
  • Build step runs production build script
  • Proper environment variable injection

Common Patterns

Health checks

var api = builder.AddNodeApp("api", "./api", "server.js")
    .WithNpm()
    .WithHttpHealthCheck("/health");

Persistent containers

var redis = builder.AddRedis("cache")
    .WithLifetime(ContainerLifetime.Persistent);

Wait for dependencies

var frontend = builder.AddViteApp("frontend", "./frontend")
    .WithReference(api)
    .WaitFor(api)       // Wait for API to be ready
    .WaitFor(cache);    // Wait for Redis to be ready

Environment variables

var app = builder.AddViteApp("frontend", "./frontend")
    .WithEnvironment("NODE_ENV", "development")
    .WithEnvironment("VITE_API_URL", api.GetEndpoint("http"));

Quick Reference

TaskCode
Add Vite appbuilder.AddViteApp("name", "./path")
Add Node.js appbuilder.AddNodeApp("name", "./path", "server.js")
Use yarn.WithYarn()
Use pnpm.WithPnpm()
Set port via env.WithHttpEndpoint(port: 3000, env: "PORT")
Reference service.WithReference(otherResource)
Wait for dependency.WaitFor(otherResource)
External endpoint.WithExternalHttpEndpoints()
Health check.WithHttpHealthCheck("/health")
Custom script.WithRunScript("start")
Pass args.WithArgs("--no-open")
HTTPS dev cert.WithHttpsDeveloperCertificate()
Custom Vite config.WithViteConfig("./custom.config.js")

References

When to Use

This skill is applicable to execute the workflow or actions described in the overview.

Reviews

No reviews yet. Tell others what you thought.

Comments

No login needed. Share how it worked for you, ask a question, or note where it did not run.

No comments yet. Be the first to write one.

Comments are published right away. Do not include personal information such as email addresses or phone numbers. Up to 2 URLs.

0 / 1,000 characters

This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.

More skills from this repository

Shared SDD references for installed skills. Not invokable.

The English summary is being prepared. Showing the original description.

JantonioFC/skillsbank9Updated Aug 4, 2026

Arquitecto de Soluciones Principal y Consultor Tecnológico de Andru.ia. Diagnostica y traza la hoja de ruta óptima para proyectos de IA en español.

The English summary is being prepared. Showing the original description.

JantonioFC/skillsbank9Updated Aug 4, 2026

007

Free

Security audit, hardening, threat modeling (STRIDE/PASTA), Red/Blue Team, OWASP checks, code review, incident response, and infrastructure security for any project.

The English summary is being prepared. Showing the original description.

JantonioFC/skillsbank9Updated Aug 4, 2026

Ingeniero de Sistemas de Andru.ia. Diseña, redacta y despliega nuevas habilidades (skills) dentro del repositorio siguiendo el Estándar de Diamante.

The English summary is being prepared. Showing the original description.

JantonioFC/skillsbank9Updated Aug 4, 2026

Estratega de Inteligencia de Dominio de Andru.ia. Analiza el nicho específico de un proyecto para inyectar conocimientos, regulaciones y estándares únicos del sector. Actívalo tras definir el nicho.

The English summary is being prepared. Showing the original description.

JantonioFC/skillsbank9Updated Aug 4, 2026

2D game development principles. Sprites, tilemaps, physics, camera.

The English summary is being prepared. Showing the original description.

JantonioFC/skillsbank9Updated Aug 4, 2026

See all skills by JantonioFC

Report a problem with this skill