Claude
Skills
Sign in
Back

dotnet-file-based-apps

Included with Lifetime
$97 forever

Running C# without a project file (.NET 10 SDK). Directives, CLI commands, migration.

Backend & APIs

What this skill does


# dotnet-file-based-apps

.NET 10 SDK file-based apps let you build, run, and publish C# applications from a single `.cs` file without creating a `.csproj` project file. The SDK auto-generates project configuration from `#:` directives embedded in the source file. This feature targets scripts, utilities, and small applications where traditional project scaffolding is unnecessary.

**This is NOT file I/O.** For FileStream, RandomAccess, FileSystemWatcher, and path handling, see [skill:dotnet-file-io].

**Prerequisites:** Requires .NET 10 SDK or later. Run [skill:dotnet-version-detection] to confirm SDK version.

Cross-references: [skill:dotnet-version-detection] for SDK version gating, [skill:dotnet-project-analysis] for project-based analysis (file-based apps have no `.csproj`), [skill:dotnet-scaffold-project] for csproj-based project scaffolding.

---

## Directives Overview

File-based apps use `#:` directives to configure the build. Directives are **SDK-level instructions, not C# syntax**. They must appear at the top of the `.cs` file, before any C# code.

Four directive types are supported:

| Directive | Purpose | Example |
|-----------|---------|---------|
| `#:package` | Add a NuGet package reference | `#:package [email protected]` |
| `#:sdk` | Set the SDK (default: `Microsoft.NET.Sdk`) | `#:sdk Microsoft.NET.Sdk.Web` |
| `#:property` | Set an MSBuild property | `#:property PublishAot=false` |
| `#:project` | Reference another project file | `#:project ../Lib/Lib.csproj` |

---

## `#:package` Directive

Adds a NuGet package reference. Specify the package name, optionally followed by `@version`.

```csharp
#:package Newtonsoft.Json
#:package [email protected]
#:package Spectre.Console@*
```

Version behavior:
- **`@version`** -- pins to a specific version
- **`@*`** -- uses the latest stable version (NuGet floating version)
- **No version** -- only works when Central Package Management (CPM) is configured with a `Directory.Packages.props` file; otherwise, specify a version explicitly or use `@*`

---

## `#:sdk` Directive

Specifies which SDK to use. Defaults to `Microsoft.NET.Sdk` if omitted.

```csharp
#:sdk Microsoft.NET.Sdk.Web
```

```csharp
#:sdk [email protected]
```

Use this directive to access SDK-specific features. For example, `Microsoft.NET.Sdk.Web` enables ASP.NET Core features and automatically includes `*.json` configuration files in the build.

---

## `#:property` Directive

Sets an MSBuild property value. Use this to customize build behavior.

```csharp
#:property TargetFramework=net10.0
#:property PublishAot=false
```

### Conditional Property Values

Property directives support MSBuild property functions and expressions for conditional configuration.

**Environment variables with defaults:**

```csharp
#:property LogLevel=$([MSBuild]::ValueOrDefault('$(LOG_LEVEL)', 'Information'))
```

**Conditional expressions:**

```csharp
#:property EnableLogging=$([System.Convert]::ToBoolean($([MSBuild]::ValueOrDefault('$(ENABLE_LOGGING)', 'true'))))
```

---

## `#:project` Directive

References another project file or directory containing a project file. Use this to share code between a file-based app and a traditional project.

```csharp
#:project ../SharedLibrary/SharedLibrary.csproj
```

The referenced project is built and linked as a project reference, just like `<ProjectReference>` in a `.csproj`.

---

## CLI Commands

The .NET CLI supports file-based apps through familiar commands.

### Run

```bash
# Preferred: pass file directly
dotnet run app.cs

# Explicit --file option
dotnet run --file app.cs

# Shorthand (no 'run' subcommand)
dotnet app.cs

# Pass arguments after --
dotnet run app.cs -- arg1 arg2
```

When a `.csproj` exists in the current directory, `dotnet run app.cs` (without `--file`) runs the project and passes `app.cs` as an argument to preserve backward compatibility. Use `dotnet run --file app.cs` to force file-based execution.

### Pipe from stdin

```bash
echo 'Console.WriteLine("hello");' | dotnet run -
```

The `-` argument reads C# code from standard input. Useful for quick testing and shell script integration.

### Build

```bash
dotnet build app.cs
```

Build output goes to a cached location under the system temp directory by default. Override with `--output` or `#:property OutputPath=./output`.

### Clean

```bash
# Clean build artifacts for a specific file
dotnet clean app.cs

# Clean all file-based app caches in the current directory
dotnet clean file-based-apps

# Clean caches unused for N days (default: 30)
dotnet clean file-based-apps --days 7
```

### Publish

```bash
dotnet publish app.cs
```

File-based apps enable **native AOT by default**. The output goes to an `artifacts` directory next to the `.cs` file. Disable AOT with `#:property PublishAot=false`.

### Pack as .NET Tool

```bash
dotnet pack app.cs
```

File-based apps set `PackAsTool=true` by default. Disable with `#:property PackAsTool=false`.

### Restore

```bash
dotnet restore app.cs
```

Restore runs implicitly on build/run. Pass `--no-restore` to `dotnet build` or `dotnet run` to skip it.

---

## Shell Execution (Unix)

Enable direct execution on Unix-like systems with a shebang line.

```csharp
#!/usr/bin/env dotnet
#:package Spectre.Console

using Spectre.Console;

AnsiConsole.MarkupLine("[green]Hello, World![/]");
```

```bash
chmod +x app.cs
./app.cs
```

The file must use `LF` line endings (not `CRLF`) and must not include a BOM.

---

## Launch Profiles

File-based apps support launch profiles via a flat `[AppName].run.json` file in the same directory as the source file. For `app.cs`, create `app.run.json`:

```json
{
  "profiles": {
    "https": {
      "commandName": "Project",
      "launchBrowser": true,
      "applicationUrl": "https://localhost:5001;http://localhost:5000",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    }
  }
}
```

Select a profile with `--launch-profile`:

```bash
dotnet run app.cs --launch-profile https
```

If both `app.run.json` and `Properties/launchSettings.json` exist, the traditional location takes priority.

---

## User Secrets

File-based apps generate a stable user secrets ID from the file's full path.

```bash
dotnet user-secrets set "ApiKey" "your-secret-value" --file app.cs
dotnet user-secrets list --file app.cs
```

---

## Implicit Build Files

File-based apps respect MSBuild and NuGet configuration files in the same or parent directories:

- **`Directory.Build.props`** -- inherited MSBuild properties
- **`Directory.Build.targets`** -- inherited MSBuild targets
- **`Directory.Packages.props`** -- Central Package Management versions
- **`nuget.config`** -- NuGet package source configuration
- **`global.json`** -- SDK version pinning

Be mindful of these files when placing file-based apps in a repository that also contains traditional projects. Inherited properties may cause unexpected build behavior.

---

## Build Caching

The SDK caches build outputs based on source content, directives, SDK version, and implicit build files. Caching improves repeated `dotnet run` performance.

Known caching pitfalls:
- Changes to implicit build files (`Directory.Build.props`, etc.) may not trigger rebuilds
- Moving files to different directories does not invalidate the cache
- **Concurrent execution** of the same file-based app can cause build contention errors -- build first with `dotnet build app.cs`, then run multiple instances with `dotnet run app.cs --no-build`

Clear the cache with `dotnet clean app.cs` or `dotnet clean file-based-apps`.

---

## Folder Layout

Do not place file-based apps inside a `.csproj` project's directory tree. The project's implicit build configuration will interfere.

```
# Recommended layout
repo/
  src/
    MyProject/
      MyProject.csproj
      Program.cs
  scripts/           # Separate directory for file-based apps
    utility.cs
    tool.cs
```

---

## Migration: File-Based to Project-Based

When a file-based app outg

Related in Backend & APIs