A tasks.json file lets you run build scripts, linters, tests, and any command-line tool directly from VS Code without typing in the terminal. Once configured, a task runs with a keyboard shortcut or a Command Palette selection.
Tasks work only inside a workspace folder. If you open a single file without a folder, tasks are not available.
Create your first tasks.json
Open the Command Palette (Ctrl+Shift+P on Windows/Linux, Cmd+Shift+P on macOS) and run Tasks: Configure Task.
VS Code looks for tools it can auto-detect in your project. If you have a package.json with scripts, it lists npm tasks. If you have a tsconfig.json, it lists TypeScript tasks. For Gulp, Grunt, and Jake files, it lists those too.
Select one of the detected tasks from the list. VS Code creates a .vscode/tasks.json file and pre-fills it with the task configuration. If no tasks were detected, select Create tasks.json file from template, then choose Others for a blank shell task template.
The file that VS Code generates looks like this for an npm script:
{
"type": "npm",
"script": "test",
"group": "test",
"problemMatcher": [],
"label": "npm: test",
"detail": "jest"
}The label is what you see when you run Tasks: Run Task. The type tells VS Code how to execute it. The script maps to a script in your package.json.
Write a custom shell task
Detected tasks cover npm, TypeScript, and a few build tools. For everything else, write a shell task.
Here is a task that runs a Python script:
{
"label": "Run data export",
"type": "shell",
"command": "python3 scripts/export.py",
"group": "build",
"presentation": {
"reveal": "always",
"panel": "new"
}
}The command runs in your default shell. On Windows, it uses PowerShell or cmd depending on your VS Code settings. On macOS and Linux, it uses the shell configured for the integrated terminal.
For cross-platform tasks, provide platform-specific commands:
{
"label": "Clean build",
"type": "shell",
"command": "rm -rf dist/",
"windows": {
"command": "rmdir /s /q dist"
}
}The windows block overrides the command and any other property when the task runs on Windows. Use linux and osx for platform-specific overrides on those systems.
Set a default build task
A default build task runs when you press Ctrl+Shift+B (Windows/Linux) or Cmd+Shift+B (macOS), or when you select Terminal > Run Build Task from the menu.
To set a task as the default build task, add a group property:
{
"label": "TypeScript build",
"type": "shell",
"command": "tsc",
"group": {
"kind": "build",
"isDefault": true
}
}Only one task can be the default build task. If you run Tasks: Configure Default Build Task, VS Code lets you pick which task to promote.
The same pattern works for a default test task. Set group.kind to test and isDefault to true. Run it with Tasks: Run Test Task from the Command Palette.
Add a problem matcher
A problem matcher scans the task's output for errors and warnings, then shows them in the Problems panel (Ctrl+Shift+M / Cmd+Shift+M). Without a problem matcher, you have to read the terminal output manually.
VS Code ships with built-in matchers for common tools. These are referenced with a dollar-sign prefix:
| Matcher | Tool |
|---|---|
| $tsc | TypeScript compiler |
| $tsc-watch | TypeScript in watch mode |
| $eslint-compact | ESLint compact format |
| $eslint-stylish | ESLint stylish format |
| $jshint | JSHint |
| $jshint-stylish | JSHint stylish format |
| $go | Go compiler |
| $mscompile | C# and VB compiler |
| $lessc | Less compiler |
| $node-sass | Node Sass compiler |
To attach a matcher, add it to the task:
{
"label": "Lint",
"type": "npm",
"script": "lint",
"problemMatcher": ["$eslint-stylish"]
}Now when the lint task runs, every ESLint error appears in the Problems panel with file, line, and column information. Click an error to jump to the exact location.
If your tool is not in the built-in list, you can write a custom problem matcher using a regular expression. This is an advanced topic covered in the VS Code tasks documentation.
Control task output
By default, task output appears in the integrated terminal. The presentation property controls how that terminal behaves:
{
"label": "Run tests",
"type": "shell",
"command": "npm test",
"presentation": {
"reveal": "always",
"panel": "dedicated",
"clear": true,
"focus": false
}
}| Property | Values | Effect |
|---|---|---|
| reveal | always, never, silent | Whether the terminal panel opens. silent opens it only on errors. |
| panel | shared, dedicated, new | Whether the terminal is reused. new gives each run a fresh terminal. |
| clear | true, false | Clear the terminal before running. |
| focus | true, false | Move keyboard focus to the terminal. |
| showReuseMessage | true, false | Show the "press any key to close" message. |
For build watchers and long-running tasks, set reveal to silent so the terminal stays hidden unless the task produces an error.
Bind a task to a keyboard shortcut
Open the Keyboard Shortcuts editor: Ctrl+K Ctrl+S (Windows/Linux) or Cmd+K Cmd+S (macOS). Search for Tasks: Run Task and click the plus icon to add a binding.
In the keybindings.json file that opens, add an args field with the exact task label:
{
"key": "ctrl+shift+t",
"command": "workbench.action.tasks.runTask",
"args": "Run tests"
}Now pressing Ctrl+Shift+T runs your test task from anywhere in VS Code.
Use workspace variables in tasks
Task commands and arguments can include variables that VS Code resolves at runtime:
| Variable | Resolves to |
|---|---|
| ${workspaceFolder} | Root path of the open workspace |
| ${file} | Currently active file |
| ${fileBasename} | Active file name without path |
| ${fileDirname} | Directory of the active file |
| ${fileExtname} | Extension of the active file |
| ${cwd} | Current working directory |
| ${selectedText} | Currently selected text in the editor |
An example that compiles the currently open file:
{
"label": "Compile current file",
"type": "shell",
"command": "tsc ${file}",
"problemMatcher": ["$tsc"]
}Variables also work in the args array and the options.cwd property.
Troubleshooting
Task says "command not found"
The task runs in a non-login, non-interactive shell. Commands added to your PATH by shell startup scripts (like .bashrc or .zshrc) are not available. Install the command globally or provide the full path to the executable in the task.
For Node.js tools, install them as dev dependencies and run them through npm scripts or npx instead of calling the binary directly.
Auto-detected tasks are missing
VS Code detects npm, TypeScript, Gulp, Grunt, and Jake tasks automatically. If your tasks use a different system, write them as custom shell tasks. Also check the task.autoDetect setting: if set to off, auto-detection is disabled globally.
A task I did not create appears in the task list
Extensions can contribute tasks. Language extensions often add build, watch, and test tasks that appear alongside your custom tasks. These are normal and cannot be deleted, but you can customize them by selecting the gear icon next to the task in the Tasks: Run Task list.
Once your tasks are set up, learn how to create dependent, background, and compound tasks for more advanced automation. You can also set a default build task to run your most-used task with a single keystroke.
Rune AI
Key Insights
- Run Tasks: Configure Task from the Command Palette to generate a tasks.json file. VS Code auto-detects npm, TypeScript, Gulp, Grunt, and Jake tasks.
- A shell task runs any command in a terminal shell. Set type: shell and provide a label and command.
- Add a problemMatcher to parse error output into the Problems panel. Built-in matchers include $tsc, $eslint-stylish, and $eslint-compact.
- Assign group: { kind: build, isDefault: true } to make a task run with Ctrl+Shift+B (Cmd+Shift+B on macOS). Use kind: test for the default test task.
- Bind a task to a keyboard shortcut by assigning a key to the workbench.action.tasks.runTask command with an args field containing the task label.
Frequently Asked Questions
Where is tasks.json stored?
How do I run a task after creating it?
What is the difference between a shell task and a process task?
How do I make a keyboard shortcut for a specific task?
Conclusion
A tasks.json file turns any command-line tool into a VS Code action you can run from the Command Palette, a keyboard shortcut, or a build trigger. Start with auto-detection for npm and TypeScript tasks. Write shell tasks for custom scripts. Add problem matchers so linter and compiler output appears in the Problems panel. Use group assignments to create default build and test tasks accessible with Ctrl+Shift+B.
More in this topic
How to Use VS Code with WSL 2 on Windows
Run VS Code connected to Windows Subsystem for Linux so you can develop in a full Linux environment with native tools, terminals, and debugging, all from Windows.
20 Best VS Code Extensions for Web Developers in 2026
Twenty carefully chosen VS Code extensions every web developer should know. Covers formatting, linting, frameworks, debugging, Git, and developer experience.
How to Install, Disable, Update, and Uninstall VS Code Extensions
Learn how to install, disable, update, and uninstall VS Code extensions from the Marketplace and the command line. Step-by-step instructions for every action.