CLI and build arguments
The argument and environment-variable surface for RunOrBuildAsync — positional args, named flags, and the variables consulted when the host boots.
The command-line arguments and environment variables RunOrBuildAsync dispatches on. Two verbs are recognized — build (generate the static site) and diag (read-only inspection); dev-serving is the default when neither verb is present. --help, -h, -?, and --version print and exit without booting the host. Build arguments are an optional base URL and output directory, or the equivalent --base-url / --output named flags.
Commands
| Command | Arguments | Effect |
|---|---|---|
| (none) | — | Dev-serve. |
build |
[baseUrl] [outputDirectory] positional, or --base-url / --output named flags |
Static build; writes to OutputOptions.OutputDirectory, prints BuildReport, sets Environment.ExitCode = 1 when the report has errors. |
diag <subcommand> |
one of info, toc, routes, warnings, translation, frontmatter, llms, standard-site |
Read-only inspection. Runs the host headless (in-process, no socket bind), writes text to stdout, and exits. diag --help lists the subcommands. |
--help / --version |
— | Print usage (or the package version) and exit without serving. -h and -? are help aliases. |
| anything else | — | Dev-serve. An unrecognized args[0] is not interpreted as build/diag arguments. |
Positional arguments
Two positional slots follow the build verb, in this order:
| Slot | Name | Default | Description |
|---|---|---|---|
| 1 | baseUrl |
/ |
The URL sub-path the site will be served from; materialized as OutputOptions.BaseUrl (a UrlPath). |
| 2 | outputDirectory |
output |
The filesystem directory to write the generated site into; materialized as OutputOptions.OutputDirectory (a FilePath). |
Named flags
| Flag | Value form | Maps to |
|---|---|---|
--base-url |
--base-url /sub or --base-url=/sub |
OutputOptions.BaseUrl |
--output |
--output dist or --output=dist |
OutputOptions.OutputDirectory |
Both flags match case-insensitively and accept either the space-separated or =-joined value form.
Flag and positional resolution
Named flags win outright. A value given by --base-url or --output always populates its slot. The remaining positional arguments then fill any slots not already claimed by a flag, in declaration order — first the unclaimed baseUrl, then the unclaimed outputDirectory. So build --base-url=/sub dist puts /sub in baseUrl and the lone positional dist in outputDirectory, because the flag took the first slot and the positional flows into the next free one.
Unknown flags are silently ignored, which lets stray dev-mode arguments (--urls, the flags dotnet watch injects) pass through build without error.
Accepted input normalization
The base-URL value is normalized so common shell shapes resolve to a usable path:
- Bare segment.
--base-url my-appis accepted and promoted to/my-app. A leading slash is optional, which lets POSIX shells pass the value without the slash that MSYS would otherwise rewrite. - Windows-path recovery. A value shaped like
C:/Program Files/Git/my-app— the result of Git Bash translating a leading-slash argument — triggers a warning on stderr and is recovered to its last segment (/my-app) so the build still produces usable links.
Environment variables
| Variable | Consumer | Effect when set |
|---|---|---|
ASPNETCORE_URLS |
ASP.NET Core host | Standard ASP.NET URL binding for dev-serve. Inert under build, which binds no port. |
ASPNETCORE_ENVIRONMENT |
ASP.NET Core host | No Pennington-specific effect. Dev tooling (live reload, diagnostic overlay) gates on the run mode, not on this variable. |
Listening port
In dev mode, Pennington uses the standard ASP.NET Core host port-binding mechanisms — --urls, ASPNETCORE_URLS, or launchSettings.json — and the library adds middleware and endpoints on top of whatever URL Kestrel is told to listen on. Build mode binds no port: it drives the same pipeline in process. See Dev mode and build mode share one code path for the mechanism.
Exit codes
0—buildcompleted without errors (BuildReport.HasErrors == false), or dev-serve exited cleanly.1—buildcompleted but theBuildReportcontains at least one error diagnostic or failed page (BuildReport.HasErrors == true). Set explicitly byRunOrBuildAsyncafter writing the report.
Example
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddPennington(penn =>
{
penn.SiteTitle = "My First Pennington Site";
penn.ContentRootPath = "Content";
penn.AddMarkdownContent<DocFrontMatter>(md =>
{
md.ContentPath = "Content";
md.BasePageUrl = "/";
});
});
var app = builder.Build();
app.UsePennington();
await app.RunOrBuildAsync(args);
dotnet run against this host serves live; dotnet run -- build generates to ./output/ at base URL /; dotnet run -- build /sub dist or dotnet run -- build --base-url=/sub --output=dist generates to ./dist/ at base URL /sub.
See also
- Related reference: DI and middleware extension methods
- Related reference: Build report fields
- How-to: Build a static site
- How-to: Host under a sub-path (base URL)
- Background: Dev mode and build mode share one code path