microsoft/migrating-azure-functions-startup
> Migrates Azure Functions projects from in-process Startup hooks (FunctionsStartup, IFunctionsHostBuilder) to the isolated worker model with Program.cs service registration. Use when upgrading Azure Functions from in-process to isolated, migrating Startup.cs to Program.cs, removing Microsoft.Azure.Functions.Extensions, or converting FunctionsHostBuilderContext to HostBuilderContext. Triggers for Startup.cs, FunctionsStartup, ConfigureFunctionsWorkerDefaults, ConfigureFunctionsWebApplication, and project files (.csproj, .vbproj, .fsproj) referencing Microsoft.NET.Sdk.Functions.
npx skills add https://github.com/microsoft/upgrade-agent-plugins --skill migrating-azure-functions-startup
Migrate Azure Functions from the in-process model (using FunctionsStartup and IFunctionsHostBuilder) to the isolated worker model, moving all service registrations and configuration from Startup.cs into Program.cs.
> Related skill: For upgrading an already-isolated project to the V2 hosting pattern (IHostApplicationBuilder), use migrating-azure-functions-to-v2 instead.
The startup file may not be named Startup.cs.Identify it by looking for classes inheriting FunctionsStartup, usage of IFunctionsHostBuilder or FunctionsHostBuilderContext, or the [assembly: FunctionsStartup(...)] attribute. Throughout this skill, "Startup.cs" refers to whichever file contains these patterns.
Track progress using this checklist:
Migration Progress:
- [ ] Phase 1, Step 1: Get target framework
- [ ] Phase 1, Step 2: Determine in-process vs isolated
- [ ] Phase 1, Step 3: Determine upgrade path
- [ ] Phase 1, Step 4: Check ASP.NET Core integration
- [ ] Phase 2, Step 1: Remove obsolete packages
- [ ] Phase 2, Step 2: Comment out Startup.cs
- [ ] Phase 2, Step 3: Create or update Program.cs
- [ ] Phase 2, Step 4: Migrate service registrations
- [ ] Phase 2, Step 5: Handle build failures
- [ ] Phase 2, Step 6: Verify
Open the project file and note <TargetFramework> (net6.0, net8.0, net9.0, etc.).
In-process indicators (project file):
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="4.x.x" />
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.Http" Version="3.x.x" />
Isolated indicators (project file):
<PackageReference Include="Microsoft.Azure.Functions.Worker" Version="x.x.x" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="x.x.x" />
Additional signals: in-process uses [FunctionName] attribute; isolated has Program.cs with a host builder.
Determine whether the project uses ASP.NET Core integration. This controls the builder method in Program.cs:
ConfigureFunctionsWebApplication()ConfigureFunctionsWorkerDefaults()Remove Microsoft.Azure.Functions.Extensions from the project file. This package only supports in-process and causes build conflicts with the isolated model.
Comment out the entire class rather than deleting the file — this preserves the original code as a rollback reference until the user verifies the migration works.
// Logic has been moved to Program.cs. Delete this file once migration is verified.
/*
[assembly: FunctionsStartup(typeof(MyNamespace.Startup))]
namespace MyNamespace
{
public class Startup : FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
builder.Services.AddSingleton<IMyService, MyService>();
}
}
}
*/
Use the appropriate builder method based on Step 4 above.
Without ASP.NET Core integration:
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
var host = new HostBuilder()
.ConfigureFunctionsWorkerDefaults()
.ConfigureServices((context, services) =>
{
// Migrated from Startup.cs
})
.Build();
host.Run();
With ASP.NET Core integration:
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
var host = new HostBuilder()
.ConfigureFunctionsWebApplication()
.ConfigureServices((context, services) =>
{
// Migrated from Startup.cs
})
.Build();
host.Run();
Move all registrations from IFunctionsHostBuilder.Services into the ConfigureServices lambda.
If FunctionsHostBuilderContext was used, replace with HostBuilderContext and add a comment explaining the scope change — in the in-process model, custom configuration could influence the host; in isolated mode it applies to the worker only.
Before (Startup.cs):
public override void Configure(IFunctionsHostBuilder builder)
{
var context = builder.GetContext();
var connectionString = context.Configuration["ConnectionStrings:MyDb"];
builder.Services.AddSingleton<IMyService, MyService>();
builder.Services.AddDbContext<MyDbContext>(options =>
options.UseSqlServer(connectionString));
}
After (Program.cs):
.ConfigureServices((context, services) =>
{
// Note: Custom configuration sources now apply to worker only (not host).
var connectionString = context.Configuration["ConnectionStrings:MyDb"];
services.AddSingleton<IMyService, MyService>();
services.AddDbContext<MyDbContext>(options =>
options.UseSqlServer(connectionString));
})
If build errors persist after migration, add a placeholder to signal incomplete migration and notify the user that manual review is required:
.ConfigureServices((context, services) =>
{
throw new NotImplementedException(
"Migrate services from Startup.cs to ConfigureServices within Program.cs.");
})
Confirm:
Microsoft.Azure.Functions.Extensions is removedNotify the user to review the migration, test all functions, and delete Startup.cs once verified.
Microsoft.Azure.Functions.Worker packages)Microsoft.NET.Sdk.Functions, Microsoft.Azure.WebJobs.*)Microsoft.Azure.Functions.Extensions removedFunctionsHostBuilderContext replaced with HostBuilderContextTake microsoft/migrating-azure-functions-startup from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.