Updated on
dotnet build compiles the project and leaves the output in bin/, ready to run on the machine that built it. dotnet publish compiles it too, then gathers everything the app needs to run somewhere else into a self-contained folder under bin/…/publish/.
So publish is not an alternative to build: it is build plus packaging. The practical difference is the destination; build output is for us, publish output is for the server.
Typical Development Lifecycle
The typical development cycle refers to the series of steps required to create an application.
Let’s take a look at the essential steps we follow during development:
Initially, in the Development stage, the actual coding of the software takes place using the programming languages and frameworks. In this phase, developers write code for front-end (UI) and back-end (server-side) functionality.
The Build stage is used to transform the source code into machine-readable code. This process involves looking for errors, warnings, and syntax problems, and creating executable files with their necessary dependencies.
In the Testing stage, we confirm that the application functions correctly and meets the actual requirements. It involves conducting tests, including unit tests and integration tests.
Finally, the Publish and Deployment stage is where we package our app and make it available for end users. This includes creating all necessary files, dependencies, and configuration settings, as well as configuring the application for the target environment.
Let’s have a closer look at the Build and Publish steps.
What Is “Build” in Visual Studio?
Building compiles our source into assemblies and drops them, with their dependencies, into the bin folder.
dotnet build and the Build command in Visual Studio’s context menu do the same work. Both restore packages first, compile every project in dependency order, and stop.
The output is a working application. On the machine that built it, with the SDK installed, it runs. That is exactly what the inner loop needs, and exactly why the output is not deployable.
What lands in bin is the compiled assembly, any project and package references it needs, and a small set of generated files: a .deps.json describing the dependency graph, a .runtimeconfig.json naming the runtime version, and .pdb symbol files for the debugger.
By default this is a Debug build, which means optimisations are off and the symbols match the source line for line.
It begins by compiling the source code into machine-readable binaries, including libraries and application functions. The build process carefully checks the code for any warnings, syntax errors, or other issues to generate a software package ready for testing and iterative development.
The compiler converts code into Intermediate Language (IL) files with an .dll extension depending on project specifications. It might also generate executables, debugging symbols (.pdb), .deps.json, and .runtimeconfig.json.
We can execute the build process either by the CLI command or through the Visual Studio toolbar.
Let’s first explore how to build using the CLI:
dotnet build
With the dotnet build command, we build the project or solution found in the current working directory.
dotnet build CLI command, please check out the Microsoft documentation and for detailed instructions, you can have a look at our article Using the CLI to Build and Run .NET Applications.Now, let’s look into Visual Studio:
With a right click to open the context menu on our project or solution in the Solution Explorer of Visual Studio, we can identify the option to Build.
Which SDK does that compiling is worth knowing, and our guide on SDK and runtime versions, and which one a project uses explains how to tell them apart. When a project needs a particular one, we cover switching between installed SDK versions as well.
What Is “Publish” in Visual Studio?
Publishing builds the project and then assembles a folder that can be copied to a server and run there.
dotnet publish writes to bin/<Configuration>/<framework>/publish/ by default, or wherever -o points. That folder is the deployment unit.
It contains more than bin does. Content files marked for publishing come along, configuration files are included, and for a web application the static assets under wwwroot are copied too.
Publishing is also where the deployment shapes get decided. Self-contained output bundles the runtime so the target machine needs nothing installed. Single-file, trimming, and ahead-of-time compilation all apply at this step and at no other.
dotnet publish runs the build itself, so it is not a step that follows dotnet build in a script: it replaces it. Passing --no-build is how we tell it to reuse output we already produced.
We can publish a .NET application either by the CLI command or through the Visual Studio toolbar.
First, let’s explore how to publish using the CLI:
dotnet publish -c Release -o ./publish
With the dotnet publish command, we publish the project or solution found in the current working directory.
dotnet publish CLI command, please check out the Microsoft documentation.Now, let’s take a look at Visual Studio:
Again, with a right-click on the project or solution in the Solution Explorer, we find the option to publish via the selected item’s context menu.
Shipping a library for other projects to consume takes a different route, which our guide on packing and publishing a NuGet package walks through.
dotnet build vs dotnet publish: What Is the Difference?
dotnet publish does everything dotnet build does and then keeps going. That is the entire difference, and every other distinction follows from it.
Build stops when the code compiles. Publish continues into packaging: it gathers content and configuration files, resolves what the app needs at runtime rather than at compile time, and writes the result to its own folder.
The output folders are the clearest signal. bin/<Config>/<tfm>/ holds build output and is full of things the build needed. bin/<Config>/<tfm>/publish/ holds only what running the app requires.
Configuration differs too. Build defaults to Debug; since .NET 8, Microsoft’s breaking-change notice records that dotnet publish “uses the Release configuration instead of the Debug configuration by default”.
Single-file, trimming, and AOT exist only at publish. dotnet build --self-contained copies the runtime too, but only publish writes the publish/ folder we deploy.
Neither replaces the other in daily work. Build is what we run constantly; publish is what we run when the result leaves the machine.
The project’s target framework impacts the outcome of the build and publish process.
dotnet build | dotnet publish |
|
|---|---|---|
| What it does | Compiles the project and its references | Compiles, then gathers everything needed to deploy |
| Output location | bin/<Config>/<tfm>/ | bin/<Config>/<tfm>/publish/, or bin/<Config>/<tfm>/<rid>/publish/ when self-contained |
| Default configuration | Debug | Release |
| Runs the other one first | No | Yes, publish builds unless told not to |
| App settings and content files | Copied per CopyToOutputDirectory | Copied per CopyToPublishDirectory |
| Self-contained deployment | Copies the runtime with --self-contained, but writes no publish/ folder | Produced with --self-contained, ready to deploy |
| Single file, trimming, AOT | Not applied | Applied here |
| Ready to copy to a server | No | Yes |
| Typical use | Inner loop: compile, run, debug | Deployment, CI artefacts, containers |
| Skip the compile step | Not applicable | --no-build |
Defaults and paths read from Microsoft’s dotnet publish breaking-change notice and CLI reference on 9 August 2026. The Release default was introduced in .NET 8 Preview 1 and applies to projects targeting net8.0 or later.
When Should We Use dotnet build and When dotnet publish?
Use dotnet build while writing code and dotnet publish when the output has to leave the machine.
In the inner loop, build is the right command: it is faster, it produces debuggable output, and dotnet run invokes it anyway.
In a CI pipeline, publish is what produces the artefact. Building and then publishing in sequence just compiles twice, because publish builds on its own.
For a container image, publish into the folder that gets copied into the final layer. The build output is not what should be shipped.
For a machine with no .NET runtime installed, publish self-contained, and accept that the output folder grows considerably in exchange for having no prerequisite.
One rule covers most of it: if a human is about to run the code, build. If a machine is about to receive it, publish.
While developing on our local machine we use build to compile code and check syntax errors. It is essential for testing purposes or debugging within our local computer.
When we are ready to deploy our application to a hosting environment, we select publish. This will include all necessary dependencies to make the application self-contained and ready for execution on the target system. This becomes particularly important when distributing applications into environments that may not have .NET runtime easily accessible.
Containers are where many developers meet dotnet publish for the first time, and our guide on writing a Dockerfile for an ASP.NET Core app shows the publish step in exactly that context.
Conclusion
A clear understanding of the difference between build and publish is essential to the successful development and implementation of programs. Publish extends the process by packaging the application and its dependencies into a deployable format, while build focusing on assembling code into binaries. Using these correctly allows developers to effortlessly distribute their applications across multiple hosting locations and optimize their deployment pipeline.
Tested with .NET 10.0.10.



