kosh 0.4.1
dotnet tool install --global kosh --version 0.4.1
dotnet new tool-manifest
dotnet tool install --local kosh --version 0.4.1
#tool dotnet:?package=kosh&version=0.4.1
nuke :add-package kosh --version 0.4.1
kosh
kosh is a lightweight, fast, and developer-friendly tool for running and orchestrating multiple services (
docker-compose, dotnet, node, caddy).
It was created to solve a simple problem: smaller projects often need a quick, zero‑friction way to start all their
services at once, without complex scripts, multiple terminals, or heavy tooling.
✨ Why kosh exists
Large orchestration tools (like Aspire, Nx, etc.) are powerful but often overkill for smaller projects.
I needed something that:
- initiates my local development environment (set domains in .hosts file, start docker-compose for infrasturcture, run migrations)
- starts all services with one command
- shows logs in a clean, unified console
- restarts services automatically on file changes
- works the same on Linux, macOS, and Windows
- requires minimal configuration
Installation Guide
kosh is distributed as a .NET global tool via NuGet.org.
This makes installation, updates, and removal extremely simple and fully cross‑platform.
📦 Prerequisites
You need:
- .NET Runtime 8.0 or later
Download: https://dotnet.microsoft.com/download
Check your version:
dotnet --version
🚀 Installing kosh
Install the tool globally:
dotnet tool install -g kosh
Check the version
kosh version
If the command is recognized, you're ready to go.
*NOTE:
- After installation, ensure your .dotnet/tools directory is in your PATH.
- On most systems, .NET adds this automatically.
- kosh works on Linux, macOS, and Windows.
📦 Project Configuration - koshconfig.yaml
koshconfig.yaml is the central configuration file used by kosh.
It defines:
- the project name
- all services that kosh should start
- local development domains
kosh reads this file on every command execution and uses it to orchestrate your entire development environment.
*NOTE: Everything in koshconfig.yaml is optional except projectName
🧱 File Structure Overview
projectName: Kosh Example
services:
- name: infra
type: docker-compose
path: ./devops/local
logs: none
- name: gateway
type: caddy
logs: error
path: ./devops/local
args: "--config Caddyfile"
- name: core-migration
type: dotnet-run
path: ./src/apps/KoshTestProject.Console
inheritEnv: true
- name: api
type: dotnet-watch
path: ./src/apps/KoshTestProject.Api
args: "--urls http://localhost:6001"
env:
ASPNETCORE_ENVIRONMENT: Development
- name: admin-api
type: dotnet-watch
path: ./src/apps/KoshTestProject.Admin.Api
args: "--urls http://localhost:6002"
env:
ASPNETCORE_ENVIRONMENT: Development
- name: frontend-react
type: node
path: ./src/apps/kosh-test-project-react
hosts:
- domain: kosh-test.api.localhost
- domain: kosh-test.localhost
1) projectName
Human‑readable name of the project. Displayed in console logs.
2) services
A list of all services that kosh will start. Each service entry contains:
| Field | Req | Description |
|---|---|---|
| name | Y | Unique identifier for the service (displayed in console logs) |
| type | Y | Service Runner type (defines how the service is started) |
| path | Y | Working directory of the service relative to the koshconfig.yaml file |
| args | N | Additional arguments passed to the runner |
| env | N | Environment variables passed to the runner |
| inheritEnv | N | Flag indicating should a service inherit environment variables from a global .env (false by default) |
| logs | N | Kind of logs that should be streamed to the terminal [none, error, all] (all by default) |
3) hosts
Defines a local development domains that can be used by reverse proxy. It will insert these domains to the .hosts file. On Linux/MacOS it will ask you for the user password to do that and on Windows it will open the confirmation window.
🔧 Service Examples
1) Docker Compose service
- name: infra
type: docker-compose
path: ./devops/local
logs: false
Runs docker-compose up inside the specified directory and shows only error logs in the console.
Useful for local infrastructure setup.
2) Caddy reverse proxy
- name: gateway
type: caddy
logs: false
path: ./devops/local
args: "--config Caddyfile"
Starts Caddy with a custom configuration file (Caddyfile) that is located in the specified directory.
I like to use it this way because it will handle the local ssl certificates automatically.
3) dotnet run (one‑off execution)
- name: Migrations
type: dotnet-run
path: ./src/apps/KoshTest.*.Migrations
Runs dotnet run once and will pause with the services execution until it is completed.
Ideal for migrations and similar jobs.
*NOTE: dotnet-run is currently the only service that supports globbing directory or file pattern matching. In
the example above
all migration projects that matches the provided pattern will be executed in parallel and execution of the registered
services will be
stopped until all migrations are completed successfully.
4) dotnet watch with Hot Reload
- name: api
type: dotnet-watch
path: ./src/apps/KoshTestProject.Api
args: "--urls http://localhost:6001"
env:
ASPNETCORE_ENVIRONMENT: Development
Runs dotnet watch run with hot reload enabled by default. To disable hot reload pass the '--no-hot-reload' to
the args
5) Node application
- name: frontend-react
type: node
path: ./src/apps/kosh-test-project-react
Runs a Node-based application using the npm run command (React, Angular, Next.js, etc.).
*NOTE: by default (if no args are provided) it will run using the dev arg like this: npm run dev but you
can override it using the args field.
🌱 Environment Variables
kosh supports three sources of environment variables (all are optional):
- environment variables defined directly in
koshconfig.yaml .envfile located inside each service’s working directory- global
.envfile located in the root of the project (applied for services with flaginheritEnv: true)
Environment variables from these sources are merged in a deterministic order to ensure predictable behavior.
1. Environment variables in koshconfig.yaml
Each service can define its own environment variables directly in the configuration:
services:
- name: api
type: dotnet-watch
path: ./src/apps/Api
env:
ASPNETCORE_ENVIRONMENT: Development
API_PORT: "6001"
*NOTE: These have the highest priority in case you define same variable from multiple different sources.
2. Service local .env file (applied automatically)
If a service’s working directory contains a .env file, kosh automatically loads it and applies its variables to
that service:
src/apps/Api/.env
These variables are applied after environment variables defined in the koshconfig.yaml (only if the variable
does not already exist).
3. Global .env file (opt‑in)
If the root directory of your solution contains a .env file, kosh loads it into memory:
/.env
/koshconfig.yaml
A service will inherit variables from the global .env only if it explicitly enables it in koshconfig.yaml with a
flag: inheritEnv: true
Example:
services:
- name: api
type: dotnet-watch
path: ./src/apps/Api
inheritEnv: true
Global .env variables have the lowest priority and are applied only if the service does not already define a
variable with the same name.
🚀 Usage Guide (Step‑by‑Step)
1. Create and configure koshconfig.yaml
In the root directory of your solution, create a file named:
koshconfig.yaml
2. Navigate to the solution root
Open your terminal and move to the directory where koshconfig.yaml is located:
cd path/to/your/solution
3. Start orchestration
Run:
kosh start
kosh will launch every service defined in koshconfig.yaml and show logs in the same terminal.
4. Stop all services
To stop everything, simply press:
CTRL + C
🔄 Updating kosh
To update to the latest version:
dotnet tool update -g kosh
🗑️ Uninstalling kosh
If you ever want to remove the tool:
dotnet tool uninstall -g kosh
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
This package has no dependencies.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.4.1 | 129 | 2/1/2026 |
| 0.4.0 | 113 | 1/27/2026 |
| 0.3.5 | 114 | 1/22/2026 |
| 0.3.4 | 114 | 1/21/2026 |
| 0.3.3 | 109 | 1/21/2026 |
| 0.3.2 | 110 | 1/21/2026 |
| 0.3.1 | 113 | 1/21/2026 |
| 0.3.0 | 110 | 1/21/2026 |
| 0.2.2 | 110 | 1/19/2026 |
| 0.2.1 | 107 | 1/19/2026 |
| 0.2.0 | 108 | 1/19/2026 |
| 0.1.6-alpha | 106 | 1/19/2026 |
| 0.1.5-alpha | 107 | 1/18/2026 |