Solidity Hot Loader with the Tutorial Starter Kit

Guide on how to use the Solidity Hot Loader with the Tutorial Starter Kit on a local development network.


The Solidity Hot Loader watches the .sol files you’re using. Once there’s a change, it compiles them, updates the local blockchain using the OpenZeppelin SDK, and refreshes your app in the browser while preserving your blockchain state.

Here’s Solidity Hot Loader cycle:

  1. Make a change in the .sol file and save it
  2. Wait a bit
  3. Done

Watch @ylv-io’s Devcon presentation: Devcon Delightful Developer Experience With Solidity Hot Loader:


Install and run a local blockchain using ganache-cli

$ npm install -g ganache-cli
$ ganache-cli --deterministic

In a separate terminal create the project folder.

$ mkdir myproject
$ cd myproject

Unpack the Tutorial Starter Kit (this could take a little while so maybe make a cup of tea)

$ npx @openzeppelin/cli unpack tutorial

Initialize the project

$ npx openzeppelin init
? Welcome to the OpenZeppelin SDK! Choose a name for your project myproject
? Initial project version 1.0.2
Project initialized. Write a new contract in the contracts folder and run 'openzeppelin create' to deploy it.

Enable the hot loader in client/config/webpack.js by setting disabled: false in your favorite editor.

const solidityLoaderOptions = {
  network: 'development',
  // you can stop loader from automatic compile/push/upgrade
  // action by setting disabled flag to true, but it will still
  // serve .json files from file system
  disabled: false,

module.exports = {
  solidityLoader: {
    test: /\.sol$/,
    use: [
      { loader: 'json-loader' },
        loader: '@openzeppelin/solidity-loader',
        options: solidityLoaderOptions,

Counter contract

Compile the Counter contract with OpenZeppelin CLI

$ npx oz compile
✓ Compiled contracts with solc 0.5.13 (commit.5b0b510c)

Deploy the Counter contract.

Run npx oz create and use the interactive commands to deploy the Counter contract to the development network and initialize to a value e.g. 23.

$ npx oz create
Nothing to compile, all contracts are up to date.
? Pick a contract to instantiate Counter
? Pick a network development
✓ Added contract Counter
✓ Contract Counter deployed
All contracts have been deployed
? Call a function to initialize the instance after creating it? Yes
? Select which function * initialize(num: uint256)
? num (uint256): 23
✓ Setting everything up to create contract instances
✓ Instance created at 0xCfEB869F69431e42cdB54A4F4f105C19C080A601


Start the app

$ cd client
$ npm run start

The app will open in a browser on http://localhost:3000/

Click on Counter to go to http://localhost:3000/counter

In MetaMask change your network to Localhost:8545 to connect to ganache-cli.

Fund MetaMask account

If you need to fund your MetaMask account (e.g. it has a balance of 0 test Ether)

From your project directory in another terminal, call npx oz transfer to transfer 0.5 (test) ether to your account in MetaMask.

$ npx oz transfer
? Pick a network development
? Choose the account to send transactions from (0) 0xF983502f33E2c9E62d0465557446B86C595C4919
? Enter the receiver account 0x77737a65C296012C67F8c7f656d1Df81827c9541
? Enter an amount to transfer 0.5 ether
✓ Funds sent. Transaction hash: 0x69a0ecc17b325a0e4cd414ca9d197a59e88a466c8d3b4d7a0a518ca384526af4

Use the app

In the app, press Increase Counter by 1 button.
Confirm the transaction in MetaMask and once the transaction is confirmed the app will have the updated counter value.

Update the Counter contract

In an editor, modify the Counter contract to change the calculation in the increaseCounter function to add 3.

  function increaseCounter(uint256 amount) public {
    count = count + 3;

The contract should look as follows:

pragma solidity ^0.5.0;

// import "openzeppelin-eth/contracts/ownership/Ownable.sol";
import "@openzeppelin/upgrades/contracts/Initializable.sol";

contract Counter is Initializable {
  //it keeps a count to demonstrate stage changes
  uint private count;
  address private _owner;

  function initialize(uint num) public initializer {
    _owner = msg.sender;
    count = num;

  function owner() public view returns (address) {
    return _owner;

  // getter
  function getCounter() public view returns (uint) {
    return count;

  //and it can add to a count
  function increaseCounter(uint256 amount) public {
    count = count + 3;

  //We'll upgrade the contract with this function after deploying it
  //Function to decrease the counter
  function decreaseCounter(uint256 amount) public returns (bool) {
    require(count > amount, "Cannot be lower than 0");
    count = count - amount;
    return true;

The Solidity Hot Loader will recompile the contract and upgrade it on the development network and update the artifacts.

In the app, press Increase Counter by 1 button.
Confirm the transaction in MetaMask and once the transaction is confirmed the app will have the updated counter value.
The value should increase by 3.