Blog

One File, One Command: dotnet run app.cs 

Emanuele Bartolesi

Emanuele Bartolesi

November 20, 2025
4 minutes

Almost every day I have the same issue: I just want to try out a quick idea in C#. Maybe it’s testing a new library, writing a one-off script, or simply printing Hello, World. But before now, that small experiment often came with a lot of rituals: creating a project, restoring packages, and dealing with files you didn’t really need.

With the arrival of dotnet run app.cs in dotnet 10, that friction disappears. You can open your editor, type a few lines of code, and run it instantly from the terminal. No project setup, no extra boilerplate. Just you and your code.

Understanding dotnet run

At its core, dotnet run is a convenience command. It wraps two separate steps:

  1. Build your application – equivalent to running dotnet build.
  2. Run your application – equivalent to executing the compiled assembly with dotnet exec.

That means when you type:

dotnet run

inside a project folder, the CLI will build your project (unless it’s already up-to-date) and then launch the application.

Extending to single files

dotnet run app.cs takes this further. Instead of requiring a .csproj file, the CLI can now:

  • Treat a single C# file as the entry point.
  • Compile it on the fly.
  • Execute it immediately.

What used to be limited to projects now works for quick experiments, scripts, and teaching examples.

Running a Single File App

As always, the simplest way to experience dotnet run app.cs is by writing the classic (and evergreen) Hello, World program.

// app.cs
Console.WriteLine("Hello, World from a single file!");

Run it directly:

dotnet run app.cs

No project scaffolding. No restore step. Just code.

Why is this useful?

  • Prototyping: Need to test a snippet of C#? Write it and run it.
  • Learning: Teaching someone new to .NET? No project overhead — just one file.
  • Quick scripts: Automate a task without setting up a full solution.

Note: I started to replace a lot of my PowerShell scripts to .NET with this approach.

A Real Script: Call the GitHub API

Let’s go further and make a call to the GitHub API to fetch a user profile.

using System.Net.Http;
using System.Net.Http.Headers;
using System.Text.Json;

public sealed class GitHubUser
{
    public string? login { get; set; }
    public string? name { get; set; }
    public string? company { get; set; }
    public string? blog { get; set; }
    public string? location { get; set; }
    public string? bio { get; set; }
    public int followers { get; set; }
    public int following { get; set; }
    public int public_repos { get; set; }
    public DateTime created_at { get; set; }
}

var username = "kasuken";
var url = $"https://api.github.com/users/{username}";

using var http = new HttpClient();
http.DefaultRequestHeaders.UserAgent.ParseAdd("dotnet-run-app-demo");

// Optional: token for higher rate limits
var token = Environment.GetEnvironmentVariable("GITHUB_TOKEN");
if (!string.IsNullOrWhiteSpace(token))
{
    http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
}

using var resp = await http.GetAsync(url);
resp.EnsureSuccessStatusCode();

await using var stream = await resp.Content.ReadAsStreamAsync();
var user = await JsonSerializer.DeserializeAsync<GitHubUser>(
    stream,
    new JsonSerializerOptions { PropertyNameCaseInsensitive = true }
);

Console.WriteLine($"""
👤 {user?.name} (@{user?.login})
🏢 {user?.company}
📍 {user?.location}
🔗 {user?.blog}
📝 {user?.bio}

Repos: {user?.public_repos}
Followers: {user?.followers} | Following: {user?.following}
Joined: {user?.created_at:yyyy-MM-dd}
""");

Run it directly:

dotnet run app.cs

Referenging NuGet Packages

You can add NuGet package references directly in your .cs file using the #:package directive:

#:package Humanizer@2.14.1

using Humanizer;

var strangerThingsReleaseDate = DateTimeOffset.Parse("2016-07-15");
var since = DateTimeOffset.Now - strangerThingsReleaseDate;

Console.WriteLine($"It has been {since.Humanize()} since Stranger Things was released! 🍿");

Run it directly:

dotnet run app.cs

Make it Executable

On Unix-based systems (Linux, macOS), you can make your script executable by adding a shebang (#!) at the top of your file and setting the execute permission.

#!/usr/bin/dotnet run
Console.WriteLine("Hello from a C# script!");

Make it executable:

chmod +x app.cs

Run it directly:

./app.cs

As you can image, this opens up a lot of possibilities for quick scripts and automation tasks. You can use it in cron jobs, CI/CD pipelines, or anywhere you need a lightweight C# script or anyway you would use a shell script or Python script..

Written by

Emanuele Bartolesi

Senior Cloud Engineer

Emanuele is a Senior Cloud Engineer and long-time community contributor, passionate about helping teams succeed with cloud, DevOps, and AI. Microsoft MVP for over 12 years, a GitHub Star for 4 years and GitHub Star of the Year 2023. Emanuele regularly blogs and speaks at international conferences, sharing his experience on GitHub, Azure, and modern software development practices. He is also active in the open-source community, creating tools to improve developer productivity and governance. Outside of work, he enjoys playing guitar, traveling, and pushing his limits through endurance sports like triathlons and marathons.

Contact

Let’s discuss how we can support your journey.