Skip to content

outdoThe typed task runner for Bun

Tasks live in a typed do.ts — no YAML, no Makefile, no DSL. Compile-time dependency checking, schema-validated env, parallel DAG scheduling, caching, and watch mode. Zero runtime dependencies.

Sixty seconds of outdo

sh
bun add -d @meslzy/outdo
bunx outdo init      # scaffolds a starter do.ts
ts
import { defineTasks, task } from "@meslzy/outdo";
import { z } from "zod";

export default defineTasks({
	build: {
		desc: "Build the project",
		inputs: ["src/**/*.ts"], // fingerprint cache
		outputs: ["dist/**"],
		run: async ({ $ }) => {
			await $`bun build src/index.ts --outdir dist`;
		},
	},
	test: {
		deps: ["biuld"], // ← compile error: Did you mean "build"?
		run: async ({ $ }) => {
			await $`bun test`;
		},
	},
	deploy: task({
		env: z.object({ DEPLOY_URL: z.url() }), // validated before anything runs
		args: { dry: { type: "boolean", short: "d" } },
		run: async ({ $, env, args }) => {
			if (!args.dry) {
				await $`./push.sh ${env.DEPLOY_URL}`;
			}
		},
	}),
});
sh
outdo                     # grouped task list
outdo build               # run a task + its deps
outdo deploy -d           # typed flags
outdo --watch build       # re-run on change
outdo explain build       # why will it run? what's cached?
outdo --affected test     # only what changed vs the base branch
outdo --json build        # full run report for CI / agents

Released under the MIT License.