Heft The Build System You Didnβt Know You Needed
The Problem: Spaghetti Scripts in Frontend Projects
Many frontend projects grow organically. You start with a simple tsc, add eslint, jest, maybe webpack, and suddenly youβre juggling a pile of npm scripts and CLI options.
Even worse: teams often create different build logic per project, even though the tooling is 90% the same.
This leads to:
- Inconsistent build behaviors
- Hard-to-maintain scripts
- Onboarding pain
So what if we could have one standard build pipeline, with clean structure, plugin support, and TypeScript-first?
Enter: Heft.
What is Heft?
Heft is a task runner and build orchestrator developed by the RushStack team at Microsoft. Itβs used in projects like Fluent UI, SPFx, and the Azure SDK.
Itβs not another bundler. Instead, Heft focuses on orchestration:
- It runs TypeScript builds
- Integrates Jest, ESLint, and API Extractor
- Allows custom tasks and plugins
- Provides Rush support for monorepos
- Scales well across enterprise-grade codebases
How does Heft work?
When you call npx heft, the following happens:
- Loads
heft.jsonβ Defines plugin and task config - Initializes plugins β Each plugin can contribute tasks
- Runs tasks β Like
compile,test,lint, or custom - Shares state via build context and options
Tasks are just plugins. Heft doesnβt do anything unless tasks are defined.
You can imagine it like this:
Heft Core
βββ Plugin: TypeScript Task
βββ Plugin: Jest Task
βββ Plugin: Webpack Task
βββ Plugin: Custom Tasks (your code)
This modular architecture makes Heft ideal for enterprise build pipelines that need to scale across multiple teams.
Setting up Heft in a React App
Letβs walk through a real setup for a React + TypeScript project that uses Heft.
Project Structure
my-heft-app/
β
βββ config/
β βββ typescript.json
β βββ jest.config.json
β
βββ src/
β βββ App.tsx
β
βββ heft.json
βββ tsconfig.json
βββ package.json
Install Dependencies
npm install --save-dev @rushstack/heft typescript react react-dom
npm install --save-dev @types/react @types/react-dom
Optional (for test + lint):
npm install --save-dev jest ts-jest eslint
npm install --save-dev @rushstack/heft-jest-plugin @rushstack/heft-eslint-plugin
Configuration Files
heft.json
{
"$schema": "https://developer.microsoft.com/json-schemas/heft/heft.schema.json",
"heftVersion": "^0.63.0"
}
tsconfig.json
{
"compilerOptions": {
"target": "ES2020",
"module": "CommonJS",
"jsx": "react-jsx",
"strict": true,
"esModuleInterop": true,
"outDir": "lib"
},
"include": ["src"]
}
config/typescript.json
{
"$schema": "https://developer.microsoft.com/json-schemas/heft/typescript.schema.json",
"disableTscWatch": true
}
src/App.tsx
import React from "react";
export const App = () => <h1>Hello from Heft + React</h1>;
Build the Project
npx heft build
Outputs compiled .js into /lib.
Extending Heft β Custom Tasks
You can build your own Heft tasks by writing a plugin.
Example: A greet task
build-plugins/greet-plugin/GreetPlugin.ts
import {
HeftConfiguration,
HeftSession,
IHeftPlugin
} from '@rushstack/heft';
export default class GreetPlugin implements IHeftPlugin {
public apply(heftSession: HeftSession, heftConfig: HeftConfiguration): void {
heftSession.registerTask({
taskName: "greet",
run: async (taskSession) => {
taskSession.logger.terminal.writeLine("π Hello from your custom Heft task!");
}
});
}
}
Register in heft.json:
{
"plugins": [
{
"plugin": "./build-plugins/greet-plugin/GreetPlugin.js",
"options": {}
}
]
}
Run it:
npx heft greet
Integration with Jest and ESLint
config/jest.config.json
{
"$schema": "https://developer.microsoft.com/json-schemas/heft/jest.schema.json",
"preset": "ts-jest"
}
Then run:
npx heft test
npx heft lint
Takeaways
| Feature | Supported by Heft? |
|---|---|
| TypeScript | β Built-in |
| React | β Supported via JSX config |
| ESLint | β Via plugin |
| Jest | β Via plugin |
| Custom Tasks | β Simple to write |
| Rush Integration | β Native support |
Summary
If youβve ever struggled with:
- too many npm scripts
- maintaining consistent build logic
- scaling React/TypeScript projects in a team
Then Heft is a rock-solid foundation for your build process.
Itβs part of the RushStack ecosystem, backed by Microsoft, and it integrates smoothly with other tools like API Extractor, Jest, and ESLint. Plus: you can write custom tasks with minimal boilerplate.
β
Try it for small projects.
β
Scale it with Rush for monorepos.
β
Extend it when needed.
Links
- Heft Docs: https://rushstack.io/pages/heft/overview/
- Rush (monorepo): https://rushjs.io/
- GitHub: https://github.com/microsoft/rushstack/tree/main/apps/heft