Acta. apache-2.0 · .net 10 · pg / mssql / sqlite

get started · five minutes

Run your first durable job in five minutes.

ASP.NET Core, embedded SQLite, one job, and the Acta dashboard. No Docker, no database server, nothing to provision — the only prerequisite is the .NET 10 SDK. Two equally good doors: hand a prompt to your AI agent, or type it yourself.

Door one

Create it with AI.

Copy a prompt, paste it into your coding agent, done. The agent finds everything it needs from useacta.net — you never need to know how.

Use useacta.net to add Acta here.

Create a worker, one job, and the dashboard. Job description: [what the job should do]

Build and run it when finished.

Working in an existing codebase, or want the guardrails spelled out? The long form:

Add Acta to this project by following useacta.net.

If this is an empty directory, create a minimal ASP.NET Core Acta app using SQLite, with one worker, one job, and the dashboard at /acta.

If this is an existing application, inspect its hosting and database setup first, preserve its architecture, and add Acta appropriately.

Detect whether the producer and worker are in the same assembly or separate assemblies and use the correct Acta registration model.

Create one job for this description: [describe the job here]

Restore, build, start the app, run the job once, and tell me how to open the dashboard. Only enable automatic migrations for local development.

Door two

By hand: three commands, one file.

dotnet new web -n Shipping && cd Shipping
dotnet add package Acta.Sqlite --prerelease
dotnet add package Acta.AspNetCore --prerelease

Replace Program.cs with this, all of it:

using Shipping;                 // the generated manifest lands in your project's root namespace
using Acta;
using Acta.AspNetCore;
using Acta.Sqlite;

var builder = WebApplication.CreateBuilder(args);

builder.Services.UseActa(j =>
{
    j.UseSqlite(sqlite =>
    {
        sqlite.ConnectionString = "Data Source=acta-local.db";
        sqlite.ApplyMigrationsOnStartup = true;   // local development only; apply from a deploy step in production
    });
    j.Run<ShippingJobs>("shipping");
});

var app = builder.Build();
app.MapActa("/acta");           // dashboard + JSON API; local-only by default, controls disabled

await app.StartAsync();
await app.Services.GetRequiredService<IJobs>().EnqueueAsync(new ShipOrder(1042));
Console.WriteLine($"Enqueued. Dashboard: {app.Urls.First()}/acta");
await app.WaitForShutdownAsync();

public sealed record ShipOrder(int OrderId);

public static class ShippingHandlers
{
    [Job("ship-order")]
    public static void Handle(ShipOrder input) => Console.WriteLine($"Shipping order {input.OrderId}");
}

dotnet run, and success looks like this:

The job was a row in acta-local.db before it was a method call. Swap UseSqlite for UsePostgres or UseSqlServer and nothing else changes.

Existing app?

Add Acta to what you already run.

Keep your host and your database. Add the provider package that matches your server (Acta.Postgres, Acta.SqlServer, or Acta.Sqlite), register with your existing connection string, and put one real job behind [Job("...")]. Handlers resolve through DI, so your services inject as they always did. Production schema comes from a deploy step, never from startup migration.

Separate API and worker processes? See the quickstart's split-deployment notes.

Next

What to learn after the first job.

Also: every capability, in plain terms·how Acta compares·llms.txt, for your agent