Learn dotnet run from basics to .NET 10's single-file execution. Run C# files without projects—just dotnet run app.cs. Complete guide with examples.
Ever wanted to test a quick C# idea but couldn't be bothered creating a whole project? You open Visual Studio, wait for it to load, click File > New Project, pick a template, name it "TestProject47," choose a location, wait for scaffolding, and... wait, what was I trying to test again?
I've lost more coding momentum to project scaffolding than I'd like to admit.
Good news: those days are over. Let's talk about dotnet run—from the basics you might already know to the new single-file execution that changes how you prototype in C#.
TL;DR
dotnet run executes your .NET application from source code in one command. In .NET 10, you can now run a single .cs file directly with dotnet run app.cs—no project file needed. Think Python or Node.js, but with C#.
The Traditional dotnet run (Still Great, Still Relevant)
If you've been doing .NET for a while, you know the drill:
dotnet run
That's it. One command that builds and runs your project. Behind the scenes, it's doing dotnet build followed by executing the output, but you don't have to think about that.
The Options You Should Actually Know
Here's the thing—most developers use dotnet run naked. But there are options worth knowing:
# Run with a specific configuration
dotnet run -c Release
# Run a specific project (when you have multiple)
dotnet run --project ./src/MyApp/MyApp.csproj
# Pass arguments to YOUR app (not to dotnet)
dotnet run -- --my-flag value
# Skip the build (when you know nothing changed)
dotnet run --no-build
# Target a specific framework
dotnet run -f net9.0
That -- separator is crucial. Everything before it goes to dotnet run. Everything after goes to your application. I've watched developers struggle with this for embarrassingly long.
When to Use What
| Command | Use Case |
|---|---|
dotnet run |
Development, quick iterations |
dotnet build |
Just compile, check for errors |
dotnet publish |
Production deployment |
Here's the important bit: don't use dotnet run in production. It resolves dependencies from the NuGet cache, which isn't what you want when deploying. Use dotnet publish and deploy the output instead.
What Is dotnet run app.cs?
Now for the exciting part. Starting with .NET 10, you can do this:
dotnet run hello.cs
No .csproj. No Program.cs with a Main method. No namespace. Just your code.
Here's a complete, runnable C# program:
// hello.cs
Console.WriteLine("Hello from a single file!");
That's the whole file. Run it with dotnet run hello.cs and watch it execute.
I know what you're thinking: "This is basically what Python and Node have had forever." Yes. And it's glorious that C# finally caught up.
This Isn't Just Hello World
Before you dismiss this as a toy feature, let me show you what's actually possible.
Need a NuGet package? Use the #:package directive:
#:package Humanizer@2.14.1
using Humanizer;
var dotNet10Released = DateTimeOffset.Parse("2025-11-10");
var since = DateTimeOffset.Now - dotNet10Released;
Console.WriteLine($"It's been {since.Humanize()} since .NET 10 dropped.");
No dotnet add package. No editing XML. Just declare what you need and go.
Building a web API? Switch the SDK:
#:sdk Microsoft.NET.Sdk.Web
var app = WebApplication.CreateBuilder(args).Build();
app.MapGet("/", () => "Hello from a single-file API!");
app.Run();
That's a complete ASP.NET Core Minimal API in 7 lines, no project file required. Try doing that in Java. I'll wait.
Need to set build properties?
#:property LangVersion preview
#:property Nullable enable
You get the idea. The directives give you almost everything a .csproj would, without the XML ceremony.
How Do You Run C# as a Shell Script?
On macOS or Linux, you can go full script mode:
#!/usr/bin/env dotnet run
Console.WriteLine("I'm basically a shell script now");
Make it executable:
chmod +x script.cs
./script.cs
C# as a scripting language. My 2010 self would never believe this.
This is genuinely useful for automation tasks you'd normally write in Bash or Python. Now you can use proper types, LINQ, and all the C# goodness for your utility scripts.
The Directive Cheat Sheet
| Directive | Purpose | Example |
|---|---|---|
#:package |
Add NuGet reference | #:package Newtonsoft.Json@13.0.3 |
#:sdk |
Change SDK | #:sdk Microsoft.NET.Sdk.Web |
#:property |
Set build property | #:property LangVersion preview |
#:project |
Reference a project | #:project ../MyLib/MyLib.csproj |
When Your Script Grows Up
Eventually, your "quick script" becomes important. Maybe it's now handling production data. Maybe other people need to work on it. Time to graduate to a real project.
Instead of manually creating a .csproj and copying directives:
dotnet project convert app.cs
This creates a proper project structure, moves your file into a folder, generates the .csproj, and converts all your #: directives into proper MSBuild properties and package references.
Your single-file prototype becomes a maintainable project in one command.
Top-Level Statements: The Foundation
None of this would work without top-level statements, introduced back in C# 9. Remember when every program looked like this?
using System;
namespace MyApp
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("That's a lot of boilerplate");
}
}
}
Now it's just:
Console.WriteLine("Much better");
The compiler generates all that ceremony for you. It creates a Program class, an entry point method, handles async if needed, and exposes args as a magic variable.
This isn't just syntactic sugar—it fundamentally changed how approachable C# is for beginners and scripters.
The Constraints (Because Nothing Is Free)
- Only one file per project can have top-level statements
- Types (classes, structs, etc.) must come after your top-level code
- The entry point method is compiler-generated and not directly callable
These constraints rarely matter in practice, but they're worth knowing.
Real-World Use Cases
Let me share where I actually use single-file execution:
1. Data Exploration
#:package CsvHelper@30.0.1
#:package Spectre.Console@0.48.0
using CsvHelper;
using Spectre.Console;
var records = new StreamReader("data.csv")
.Using(r => new CsvReader(r, CultureInfo.InvariantCulture))
.GetRecords<dynamic>()
.Take(10);
AnsiConsole.Write(new Table()
.AddColumns(records.First().Keys.ToArray())
.AddRows(records));
Quick CSV inspection without leaving the terminal.
2. API Testing
#:package Refit@7.0.0
using Refit;
interface IGitHubApi
{
[Get("/users/{user}")]
Task<User> GetUser(string user);
}
record User(string Login, int PublicRepos);
var api = RestService.For<IGitHubApi>("https://api.github.com");
var user = await api.GetUser("dotnet");
Console.WriteLine($"{user.Login} has {user.PublicRepos} public repos");
Prototype your API client before committing to the full implementation.
3. One-Off Automation
That script you'd normally write in PowerShell but want proper error handling and types? Single-file C# is perfect.
What Are the Current Limitations?
I'd be lying if I said this was perfect. Some honest notes:
Single file only (for now). Multi-file support is being explored for future releases. Right now, you can't split your single-file app across multiple .cs files.
Requires .NET 10. This feature shipped with .NET 10 in November 2025. Make sure you have the latest SDK installed.
Not for production. This is for scripting, prototyping, and learning. Your production apps should still be proper projects with proper deployment pipelines.
IDE support varies. Visual Studio and VS Code are catching up, but the experience isn't as polished as with full projects yet.
Migration Path From Scripts to Projects
If you've been using tools like dotnet-script or csi (C# Interactive), here's how to think about the transition:
| Old World | New World |
|---|---|
dotnet-script |
dotnet run app.cs |
#r "nuget: Package" |
#:package Package |
.csx files |
.cs files |
| Third-party tool | Built into SDK |
The built-in approach means no extra tools to install, better integration with the ecosystem, and the same execution model as regular .NET apps.
The Practical Checklist
Before running dotnet run app.cs:
- [ ] Make sure you're on .NET 10 SDK or later
- [ ] Use
#:packagefor NuGet dependencies - [ ] Use
#:sdk Microsoft.NET.Sdk.Webfor web scenarios - [ ] Add shebang for Unix script execution
- [ ] Use
dotnet project convertwhen ready to grow
Frequently Asked Questions
Can I use NuGet packages in single-file C#?
Yes. Use the #:package directive at the top of your file: #:package Newtonsoft.Json@13.0.3. The package is restored automatically when you run the script—no dotnet add package required.
Does dotnet run app.cs work on Windows?
Yes, the core single-file execution works on Windows, macOS, and Linux. The only platform-specific feature is shebang scripts (#!/usr/bin/env dotnet run), which are Unix-only.
When should I convert to a full project?
Convert when you need multi-file support, team collaboration, CI/CD pipelines, or production deployment. Run dotnet project convert app.cs to generate a proper project structure from your script.
How is this different from dotnet-script?
dotnet run app.cs is built into the SDK—no extra tools to install. It uses standard .cs files (not .csx), the #:package directive (not #r "nuget:"), and follows the same execution model as regular .NET apps.
Final Thoughts
dotnet run went from "convenient development command" to "C# as a scripting language." That's a big deal.
For years, the friction of creating a project was a real barrier. Want to test if a NuGet package does what you think? Create a project. Want to show someone a C# concept? Create a project. Want to automate a quick task? Maybe just use Python instead.
That friction is gone. C# is now as approachable as any scripting language for quick tasks, while still being C# for when things get serious.
I've already replaced several Bash scripts with single-file C#. Better error handling, proper types, actual debugging support. All without the ceremony of project scaffolding.
The next time you need to test something quick, skip the project creation. Write a .cs file and run it. You might be surprised how often that's all you need.
About the Author
I'm Mashrul Haque, a Systems Architect with over 15 years of experience building enterprise applications with .NET, Blazor, ASP.NET Core, and SQL Server. I specialize in Azure cloud architecture, AI integration, and performance optimization.
When production catches fire at 2 AM, I'm the one they call.
- LinkedIn: Connect with me
- GitHub: mashrulhaque
- Twitter/X: @mashrulthunder
Follow me here on dev.to for more .NET and SQL Server content.
Sources:
Top comments (0)