Skip to content

/commands/csharp/run-cs-file-without-project

dotnet run app.cs: run a C# file without a project (.NET 10 file-based apps)

verified onenvironmentlocal · windows 10.0.26200 arm64 · GNU bash 5.3.15 (Git Bash) · 10.0.401updated
tool
C#
versions
.NET 10 SDK+, #:include: SDK 10.0.300+
os
linux, macos, windows

With the .NET 10 SDK, dotnet run app.cs builds and runs a single C# file directly: no .csproj, no Program.cs template. The file uses top-level statements, and directives at the top such as #:package and #:property replace the project file. Arguments for your program go after --, and dotnet app.cs is an even shorter form.

Run a file

bash
cat > app.cs <<'EOF'
var name = args.Length > 0 ? args[0] : "world";
Console.WriteLine($"Hello, {name}! Running on .NET {Environment.Version.Major}");
Console.WriteLine($"args: [{string.Join(", ", args)}]");
EOF
dotnet run app.cs
dotnet run app.cs -- file-based --verbose

Output

Hello, world! Running on .NET 10
args: []
Hello, file-based! Running on .NET 10
args: [file-based, --verbose]

Everything after -- reaches args; without the separator, options such as --verbose would be read by dotnet run itself. The first run takes a few seconds because the SDK builds a virtual project; later runs of an unchanged file reuse the cached build.

Directives

DirectiveExampleEffect
#:package#:package Serilog@3.1.1Add a NuGet package reference
#:property#:property TargetFramework=net10.0Set any MSBuild property
#:sdk#:sdk Microsoft.NET.Sdk.WebUse another SDK, for example for a minimal web API
#:project#:project ../Shared/Shared.csprojReference a project
#:include#:include helpers.csCompile another file into the app (SDK 10.0.300+)
#!#!/usr/bin/env -S dotnet --Shebang: run ./app.cs directly on Linux and macOS after chmod +x
CommandWhat it does
dotnet app.csShorthand for dotnet run app.cs
echo 'Console.WriteLine(1);' | dotnet run -Read the program from standard input
dotnet build app.csBuild only
dotnet publish app.csPublish a native AOT executable (on by default; #:property PublishAot=false disables it)
dotnet project convert app.csCreate a regular project from the file
dotnet clean file-based-appsDelete cached builds unused for 30 days (--days to change)

Pitfalls

  • A project in the same folder wins. When the current directory contains a .csproj, dotnet run app.cs runs that project and passes app.cs to it as an argument. Use dotnet run --file app.cs or move the file.
  • SDK too old. Before .NET 10, dotnet run app.cs without a project fails with Couldn't find a project to run. Check dotnet --version (10.0.100 or later).
  • Shebang files need LF line endings and no byte order mark, according to the documentation; files saved with CRLF fail to start from the shell.
  • Build files in parent folders. Directory.Build.props, Directory.Packages.props and NuGet.config above the file still apply to it.
  • Compile errors look like any C# build error, for example CS0103 for a misspelled name.

Confirm it worked

The program's output appears and the exit status is the value your code returns (0 by default). dotnet build app.cs shows where the compiled files went.

FAQ

Where does dotnet run app.cs put the build output?

In a per-user cache under the system temporary directory (dotnet/runfile/APPNAME-HASH), not next to the file. dotnet clean file-based-apps removes old entries; --output on dotnet build chooses another folder.

Can a file-based app use NuGet packages?

Yes. Add a #:package Name@Version line at the top of the file; the SDK restores it on the first run. Without central package management the version (or @* for the latest) is required.

How do I turn the file into a normal project later?

dotnet project convert app.cs creates a folder with a .csproj and a copy of the file, translating the #: directives into project settings. The original file is left untouched.

Sources