blog
Ottorino Bruni  

C# File-based Apps in .NET 10: Run and Build Apps from a Single .cs File

Introduction

One of the first frictions developers encounter when approaching C# is not the language itself, but the project structure that comes with it.

If you come from languages like Python, JavaScript, or Go, you are used to writing a single file, running it and iterating quickly. In C#, even for the smallest script, the traditional workflow has always required a solution file, a project file, and a predefined folder structure. This overhead often makes C# feel heavier than it really is, especially for simple tasks, experiments or automation scripts.

With .NET 10, this gap has finally been addressed.

File-based apps, introduced in .NET 10, allow you to write and run a C# application starting from a single .cs file, without creating a project or a solution. You can execute it directly using the .NET CLI, keeping the focus on code instead of configuration.

This feature does not aim to replace traditional .NET projects. Instead, it fills a long-standing missing piece in the ecosystem: a lightweight entry point for scripting, prototyping, training, and small utilities. For developers coming from other languages, it significantly lowers the barrier to entry. For experienced .NET developers, it removes unnecessary friction when the problem does not justify a full project.

In this article, we will explore how C# file-based apps work in .NET 10, what you can build with them, their current limitations, and when they are the right tool for the job

What Are C# File-based Apps in .NET 10

C# file-based apps are a new execution model introduced in .NET 10 that allows you to build, run, and even publish a .NET application starting from a single C# file, without explicitly creating a project or solution.

Conceptually, a file-based app sits halfway between a classic console application and a scripting environment.

You still write standard C#, you still rely on the .NET SDK, and you still have access to the full .NET runtime. The difference is that all the project-related configuration, which normally lives in a .csproj file, becomes implicit and is resolved by the SDK at execution time.

When you run a file-based app, the .NET CLI automatically:

  • determines the SDK and target framework
  • restores required dependencies
  • builds the application
  • executes it

All of this happens without you having to define a project structure upfront.

From a developer perspective, this means you can treat a .cs file as a self-contained application, not just as source code. The file becomes the entry point, the configuration surface, and the executable unit at the same time.

It is important to clarify what file-based apps are not.

They are not a replacement for full .NET projects. They do not eliminate the need for solutions, projects, or structured codebases in real applications. Instead, they target scenarios where that structure becomes friction rather than value.

Typical examples include:

  • small command-line tools
  • automation and DevOps scripts
  • prototypes and experiments
  • training and onboarding exercises

In these cases, file-based apps allow you to focus on what the code does, not on how the project is wired together.

Another key aspect is that file-based apps are not limited to “toy scripts”. Despite their minimal surface, they support advanced features such as NuGet package references, custom SDKs, and even web workloads. This makes them a surprisingly powerful addition to the .NET toolbox, especially when used intentionally.

Creating and Running Your First File-based App

A file-based app starts from a single .cs file. There is no project, no solution, and no predefined folder structure.

Create a new file called hello.cs and add the following code:

using System;

Console.WriteLine("Hello from a C# file-based app!");

To run it, open a terminal in the same directory and execute:

dotnet run hello.cs

That’s it. The file is compiled and executed immediately.

What happens on the first run

When you run a file-based app for the first time, the .NET CLI performs several steps automatically:

  • determines the target framework and SDK
  • restores required dependencies
  • builds the application
  • executes the generated binary

This initial execution may take a little longer, especially if dependencies need to be restored. This is expected and happens only once.

Subsequent executions

If you run the same file again without modifying it, the startup is almost instantaneous.

The SDK detects that nothing has changed, reuses the cached build artifacts, and launches the application directly. In practice, this feels much closer to running a script than compiling a traditional .NET project.Why this matters

At this point, the key takeaway is not the code itself, but the workflow.

You can:

  • write C# in a single file
  • execute it with one command
  • iterate quickly without project overhead

This makes file-based apps ideal for small utilities, experiments, and learning scenarios where creating a full project would slow you down rather than help.

How File-based Apps Work Under the Hood

Even if a file-based app looks like a simple script, it is still a real .NET application.

When you run:

dotnet run hello.cs

the .NET SDK does not interpret the file at runtime. Instead, it goes through a familiar pipeline, just without exposing it to you.

You never see a .csproj file, but the runtime behaves exactly as if one existed. A target framework is selected, default SDK settings are applied, and references to the base class library are added automatically. This implicit project lives in a temporary location and is fully managed by the CLI.

On the first execution, the SDK restores any required NuGet packages, compiles the code and caches the build artifacts locally. This initial run may take a bit longer, especially if dependencies need to be downloaded. If the file does not change, subsequent executions skip both restore and compilation, which makes startup almost instantaneous. From a performance perspective, this is much closer to running a compiled binary than executing a traditional script.

File-based apps rely on top-level statements, just like modern console applications. The .cs file itself defines the entry point of the application, without requiring an explicit Main method. You can still define classes, split code into multiple files, and organize logic as needed. The only difference is that the entry point is inferred rather than explicitly declared.

This design keeps the execution model consistent with the rest of the .NET ecosystem. You are not learning a new language, a new runtime, or a special scripting syntax. You are using the same compiler, the same runtime, and the same tooling you already know, just with significantly less ceremony.

Directives and Configuration

What makes C# file-based apps powerful is that a single .cs file can also describe how the application should be built and executed.

This is done through a set of file-based directives, written at the very top of the file, that cover many of the same scenarios you would normally configure in a .csproj.

Important: these directives use the #: prefix and should appear before any using statements or code.

Referencing NuGet packages

You can reference NuGet packages directly from the .cs file, without creating a project.

For example:

#:package Dapper@2.1.35

using Dapper;
using System.Data.SqlClient;

When you run the file, the SDK automatically restores the package and makes it available at compile time. You can also omit the version and let the SDK resolve the latest compatible one, although specifying it is usually a better choice for reproducibility.

Referencing local assemblies or projects

File-based apps can also reference local assemblies or even other projects.

#:reference "path/to/MyLibrary.dll"

or

#:project "../MyLibrary/MyLibrary.csproj"

This allows you to reuse existing code without copying it into the script, making file-based apps viable even in larger solutions for small utilities or maintenance tasks.

Choosing a different SDK

By default, file-based apps use the standard .NET SDK, similar to a console application. However, you can explicitly specify a different SDK.

For example, to build a web application:

#:sdk "Microsoft.NET.Sdk.Web"

With this single line, your file-based app gains access to all the features you would normally expect from a web project, including Minimal APIs and HTTP endpoints.

MSBuild properties and defines

You can also define MSBuild properties and conditional compilation symbols directly in the file:

#:property LangVersion=preview
#:define DEBUG

This gives you fine-grained control over compilation behavior, similar to what you would configure in a .csproj, but scoped to a single file.

Why directives matter

At this point, it should be clear that file-based apps are not just about convenience.

Directives allow a single .cs file to describe:

  • its dependencies
  • its runtime model
  • its compilation behavior

This is what turns a simple file into a self-contained application definition. You get the flexibility of scripting, combined with the power and consistency of the .NET build system.

Convert a File-based App to a Traditional Project

One of the most important aspects of file-based apps is that they are not a dead end.

If a single-file utility grows over time or starts to require more structure, you can convert it into a traditional .NET project without rewriting any code.

The .NET CLI provides a dedicated command for this:

dotnet project convert file.cs

When you run this command, the SDK:

  • creates a new directory named after the application
  • copies the original .cs file into that directory
  • generates a .csproj file with equivalent SDK settings, properties, and package references
  • translates all #: directives into proper project configuration

The original .cs file is left untouched in its original location.

This makes file-based apps an excellent starting point, not a compromise. You can begin with a single file for speed and simplicity, and move to a full project only when the additional structure actually provides value.

Beyond Scripts: What You Can Really Build

File-based apps are not limited to simple scripts. They can be used to build small CLI tools, automation utilities, internal developer helpers, and even lightweight web applications by switching the SDK. They are especially useful for training, demos, and quick prototypes where setup time matters more than structure. As long as the scope remains small and focused, a single .cs file can still represent a real, executable .NET application.

Practical Example: Data Processing as a One-off Utility

Disclaimer: This example is purely for educational purposes. There are better ways to write code and applications that can optimize this example. Use this as a starting point for learning, but always strive to follow best practices and improve your implementation.

A very common use case for file-based apps is one-off data processing.

Think about tasks like validating input files, transforming data formats, or extracting summaries from datasets. These are typically repeatable operations, but they do not justify the overhead of a full application.

This makes them a perfect fit for a file-based app.

Prerequisites

Before starting, make sure you have the following installed:

  • .NET SDK: Download and install the .NET SDK if you haven’t already.
  • Visual Studio Code (VSCode): Install Visual Studio Code for a lightweight code editor.
  • C# Dev Kit for VSCode: Install the C# Dev Kit for VSCode to enable C# support.

Step 1 – Referencing a NuGet package

To keep the parsing logic simple, we’ll use a NuGet package instead of manually handling CSV parsing.

In a file-based app, you don’t need a project file to reference NuGet packages. You can do it directly at the top of the .cs file.

C# File-based Apps in .NET 10 – Create Folder

Create a new file called process-data.cs and start with the following directive:

#:package CsvHelper@30.0.1

This single line tells the .NET SDK to:

  • download the package from NuGet
  • restore it automatically
  • make it available at compile time

No .csproj, no PackageReference, no manual restore step.

Step 2 – Reading and validating the input file

After the NuGet directive, you can write normal C# code.

#:package CsvHelper@30.0.1

using CsvHelper;
using System.Globalization;
using System.IO;

if (args.Length == 0)
{
    Console.WriteLine("Please provide a CSV file path.");
    return;
}

var filePath = args[0];

using var reader = new StreamReader(filePath);
using var csv = new CsvReader(reader, CultureInfo.InvariantCulture);

var records = csv.GetRecords<dynamic>().ToList();

Console.WriteLine($"Rows processed: {records.Count}");

This code:

  • reads the CSV file path from the command-line arguments
  • parses the file using CsvHelper
  • outputs a simple summary

The entire utility lives in a single .cs file.

C# File-based Apps in .NET 10 – Simple App

Step 3 – Example input file: data.csv

Id,Name,Email,Age
1,Alice,alice@example.com,34
2,Bob,bob@example.com,29
3,Charlie,charlie@example.com,41
4,,invalid@example.com,27

This CSV represents a very common structure:

  • a header row
  • basic scalar values
  • a row with missing or invalid data
C# File-based Apps in .NET 10 – CSV Example

Step 4 – Running the utility

From the terminal, in the same folder as process-data.cs, run:

dotnet run process-data.cs data.csv

On the first execution, the SDK restores the NuGet package and compiles the file.
On subsequent runs, startup is immediate because the build output is cached.

This workflow is exactly what makes file-based apps practical for repeatable tasks that don’t deserve a full project.

C# File-based Apps in .NET 10 – Run App

Conclusion

File-based apps are a small but meaningful addition introduced in .NET 10. They remove much of the initial friction that has traditionally made C# feel heavy for simple tasks, especially for developers coming from other ecosystems.

By allowing a single .cs file to be compiled and executed directly, this feature lowers the entry barrier for new developers, simplifies experimentation, and makes C# feel more approachable for scripting, tooling, and learning scenarios.

File-based apps are not meant to replace full .NET projects, but they fill an important gap between scripts and applications. For many developers moving from other languages to .NET and C#, this will make the first steps easier, faster, and far less intimidating.

If you think your friends or network would find this article useful, please consider sharing it with them. Your support is greatly appreciated.

Thanks for reading!

Discover CodeSwissKnife Bar, your all-in-one, offline Developer Tools from Your Menu Bar

Leave A Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.