-
Notifications
You must be signed in to change notification settings - Fork 0
Directives
File-based apps support a small set of #: directives that the .NET SDK interprets before compilation. Cadenza uses these — and only these — to configure your script.
#!/usr/bin/env dotnet run
#:sdk Cadenza.Web@1.0.15
#:package Humanizer@3.0.0
#:property PublishAot=true
#:include shared/helpers.cs
Get("/", () => "Cadenza".Pluralize());
await Run();(The shebang on line 1 is optional — on Unix it lets you chmod +x app.cs && ./app.cs.)
Selects which MSBuild SDK runs the file. Exactly one per script.
#:sdk Cadenza.Web@1.0.15| Directive | What you get |
|---|---|
#:sdk Cadenza@<v> |
Console / CLI (Cadenza Console) |
#:sdk Cadenza.Worker@<v> |
Background service (Cadenza Worker) |
#:sdk Cadenza.Web@<v> |
Minimal API (Cadenza Web) |
#:sdk Cadenza.Mcp@<v> |
MCP server (Cadenza Mcp) |
#:sdk Cadenza.Agent@<v> |
AI agent (Cadenza Agent) |
The MSBuild SDK resolver does not accept floating versions (1.*, @latest). You must specify an exact SemVer. This is the source of Cadenza's reproducibility guarantee: a script you receive today still runs in five years on the exact SDK its author tested against.
If you want a single place to bump versions across many scripts, drop a global.json next to them and omit the version in the directive:
{
"msbuild-sdks": {
"Cadenza": "1.0.15",
"Cadenza.Web": "1.0.15"
}
}#:sdk Cadenza.Web // version comes from global.jsonSee Troubleshooting → "wildcard / floating version errors" if a wildcard sneaks in by accident.
Add a NuGet package reference to the script.
#:package Humanizer@3.0.0
#:package Polly@8.4.2Like #:sdk, exact SemVer is required (NuGet's wildcard rules apply only to PackageReference items inside a real .csproj).
Pull in another .cs file. As of Cadenza 1.0 (recent point release), #:include is transitive by default — including a file pulls in everything that file includes.
#:include shared/helpers.csConvention:
- Use relative paths from the script's directory.
- A common pattern is
shared/(helpers shared across multiple scripts) orlib/(single-script utilities split for readability). - Included files don't need their own
#:sdk— they inherit the script's.
Set MSBuild properties for the build. Useful for opting into AOT, trimming, or container metadata.
#:property PublishAot=true
#:property InvariantGlobalization=true| Property | Effect |
|---|---|
PublishAot=true |
NativeAOT publish (see Deployment Single Binary) |
InvariantGlobalization=true |
Drop ICU — shrinks AOT binaries dramatically |
PublishTrimmed=true |
Trim unused IL |
TrimMode=full |
Aggressive trimming |
PublishReadyToRun=true |
Ahead-of-time compile to native code (JIT fallback) |
EnableCompressionInSingleFile=false |
Faster cold start, larger binary |
IncludeNativeLibrariesForSelfExtract=true |
No temp extraction on first launch |
| Property | Effect |
|---|---|
ContainerBaseImage |
Base image (e.g. mcr.microsoft.com/dotnet/runtime-deps:10.0-alpine) |
ContainerRegistry |
Push target (e.g. ghcr.io) |
ContainerRepository |
Image repo path (e.g. myorg/myapp) |
ContainerImageTag |
Image tag (e.g. 1.0.0) |
ContainerPort |
Declared port (EXPOSE equivalent) |
ContainerEnvironmentVariables |
KEY=value;KEY2=value2 baked into the image |
See Deployment Container for full recipes.
#!/usr/bin/env dotnet run
#:sdk Cadenza.Web@1.0.15
#:package Humanizer@3.0.0
#:property PublishAot=true
#:property InvariantGlobalization=true
#:property ContainerBaseImage=mcr.microsoft.com/dotnet/runtime-deps:10.0-alpine
#:property ContainerRepository=myorg/hello
#:property ContainerEnvironmentVariables=ASPNETCORE_URLS=http://0.0.0.0:8080
using Humanizer;
Get("/", () => "Cadenza".Pluralize());
await Run();dotnet run app.cs # local dev
dotnet publish app.cs -r linux-x64 -c Release # single binary
dotnet publish app.cs --os linux --arch x64 /t:PublishContainer # containerCadenza · MIT · .NET 10+ · github.com/rkttu/cadenza · No orchestra. No project. Just one file, playing solo.