
Company News
Socket Named Top Sales Organization by RepVue
Socket won two 2026 Reppy Awards from RepVue, ranking in the top 5% of all sales orgs. AE Alexandra Lister shares what it's like to grow a sales career here.
@hackwaly/task
Advanced tools
A lightweight, TypeScript-native task runner inspired by Turborepo. Define your build pipeline with code, not configuration files.
A lightweight, TypeScript-native task runner inspired by Turborepo. Define your build pipeline with code, not configuration files.
npm install @hackwaly/task
# or
pnpm add @hackwaly/task
# or
yarn add @hackwaly/task
taskfile.js in your project root:import { configInit } from "@hackwaly/task";
const { defineTask } = configInit(import.meta);
export const build = defineTask({
name: "build",
command: "tsc --build",
inputs: ["src/**/*.ts", "tsconfig.json"],
outputs: ["dist/**/*.js"],
});
export const test = defineTask({
name: "test",
command: "vitest run",
dependsOn: [build],
});
export const dev = defineTask({
name: "dev",
command: "tsc --watch",
persistent: true,
});
export default build;
# Run a single task
npx task run build
# Run multiple tasks
npx task run build test
# Run with watch mode
npx task run build --watch
# List available tasks
npx task list
Tasks are defined using the defineTask function with the following options:
interface TaskConfig {
name: string; // Task name (required)
description?: string; // Task description for help text
command?: string | string[] | { program: string; args?: string[] };
env?: Record<string, string>; // Environment variables
cwd?: string; // Working directory (defaults to taskfile location)
inputs?: string[]; // Input file patterns (for change detection)
outputs?: string[]; // Output file patterns
persistent?: boolean; // Whether task runs continuously (like servers)
interruptible?: boolean; // Whether task can be interrupted safely
dependsOn?: TaskDef[]; // Task dependencies
}
Commands can be specified in multiple formats:
// String (parsed with shell-like parsing)
command: "tsc --build --verbose"
// Array
command: ["tsc", "--build", "--verbose"]
// Object
command: {
program: "tsc",
args: ["--build", "--verbose"]
}
Tasks can depend on other tasks. Dependencies are resolved automatically:
export const generateTypes = defineTask({
name: "generate-types",
command: "generate-types src/schema.json",
outputs: ["src/types.ts"],
});
export const build = defineTask({
name: "build",
command: "tsc --build",
inputs: ["src/**/*.ts"],
dependsOn: [generateTypes], // Runs generateTypes first
});
For long-running processes like development servers:
export const server = defineTask({
name: "server",
command: "node server.js",
persistent: true, // Runs continuously
interruptible: true, // Can be stopped gracefully
});
Watch mode automatically re-runs tasks when their input files change:
npx task run build --watch
Features:
node_modules by defaultrun <tasks...>Run one or more tasks:
# Single task
npx task run build
# Multiple tasks
npx task run lint test build
# With watch mode
npx task run build --watch
list / lsList all available tasks:
npx task list
Shows task names and descriptions in a formatted table.
import { configInit } from "@hackwaly/task";
const { defineTask } = configInit(import.meta);
export const lint = defineTask({
name: "lint",
description: "Lint TypeScript files",
command: "eslint src/**/*.ts",
inputs: ["src/**/*.ts", ".eslintrc.json"],
});
export const typecheck = defineTask({
name: "typecheck",
description: "Type check TypeScript files",
command: "tsc --noEmit",
inputs: ["src/**/*.ts", "tsconfig.json"],
});
export const build = defineTask({
name: "build",
description: "Build the project",
command: "tsc --build",
inputs: ["src/**/*.ts", "tsconfig.json"],
outputs: ["dist/**/*.js"],
dependsOn: [lint, typecheck],
});
export const test = defineTask({
name: "test",
description: "Run tests",
command: "vitest run",
dependsOn: [build],
});
export const generateSchema = defineTask({
name: "generate-schema",
command: "generate-schema api.yaml",
inputs: ["api.yaml"],
outputs: ["src/generated/schema.ts"],
});
export const dev = defineTask({
name: "dev",
description: "Start development server",
command: "vite dev",
persistent: true,
interruptible: true,
dependsOn: [generateSchema],
});
export const buildWatch = defineTask({
name: "build:watch",
description: "Build in watch mode",
command: "tsc --watch",
persistent: true,
dependsOn: [generateSchema],
});
Each package can have its own taskfile.js:
// packages/ui/taskfile.js
import { configInit } from "@hackwaly/task";
const { defineTask } = configInit(import.meta);
export const build = defineTask({
name: "build:ui",
command: "rollup -c",
inputs: ["src/**/*", "rollup.config.js"],
outputs: ["dist/**/*"],
});
// packages/app/taskfile.js
import { build as buildUI } from "../ui/taskfile.js";
export const build = defineTask({
name: "build:app",
command: "vite build",
dependsOn: [buildUI], // Cross-package dependency
});
For complex tasks, you can provide custom logic:
export const customTask = defineTask({
name: "custom",
async run(ctx) {
// Custom async logic
console.log("Running custom task...");
// Check if aborted
if (ctx.abort.aborted) {
return;
}
// Your custom logic here
},
inputs: ["src/**/*"],
});
MIT
FAQs
A lightweight, TypeScript-native task runner inspired by Turborepo. Define your build pipeline with code, not configuration files.
We found that @hackwaly/task demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Company News
Socket won two 2026 Reppy Awards from RepVue, ranking in the top 5% of all sales orgs. AE Alexandra Lister shares what it's like to grow a sales career here.

Security News
NIST will stop enriching most CVEs under a new risk-based model, narrowing the NVD's scope as vulnerability submissions continue to surge.

Company News
/Security News
Socket is an initial recipient of OpenAI's Cybersecurity Grant Program, which commits $10M in API credits to defenders securing open source software.