This is a question about Hardhat, the task runner that facilitates building on Ethereum.

From Writing scripts with Hardhat:

You can write your custom scripts that can use all of Hardhat's functionality. A classic use case is writing a deployment script for your smart contracts.

From Creating a task:

A task is a JavaScript async function with some associated metadata. This metadata is used by Hardhat to automate some things for you. Arguments parsing, validation, and help messages are taken care of.

What is the difference between the two and when should go with one over another?

1 Answer 1


The first thing to know is that almost everything you can do with a task can be done with a script, and vice versa. But there are things that can only be done with tasks or only with scripts, and things that are possible with both but easier with one of them.


The most important thing you can do with a task but not with a script is to override another task. For example, you can do something before running your tests:

task("test", async (args, hre, runSuper) => {
  // do something
  return runSuper()

What about custom tasks? In that case, there's nothing you can do with a task that can't be done with a script. The main reason to use a task then is to plug into Hardhat's argument parser. So if you are working on a token and want to check the balance of some address in some network for that token, you could do something like:

hh balance --address 00x4403B5d2Fed270D18b6d83122C818c2413D9BC05 --network mainnet

(where hh is the hardhat shorthand).


One thing you can do with scripts but not with tasks is to run them directly with node. That is, instead of

hh run my-script.js

you can do

node my-script.js

So you can do things like passing extra flags to the node binary, for example. This also lets you execute the script with another binary, like ts-node, ndb or mocha.

Keep in mind that if you do this you need to explicitly import the Hardhat Runtime Environment:

const hre = require("hardhat")

Alternatively, you can do:

node --require hardhat/register my-scripts.js

to have the same globally available variables that you get when you use hh run.

Another reason to use scripts is to parse arguments with a different library, like commander, instead of using Hardhat's own parser.

Notice that if you do this, you won't be able to specify the network anymore with the --network param. In that case, you need to set the HARDHAT_NETWORK environment variable:

HARDHAT_NETWORK=rinkeby node my-scripts.js

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.