DEV Community

Cover image for How to Compile Smart Contracts in React
Duc Nguyen
Duc Nguyen

Posted on • Updated on


How to Compile Smart Contracts in React

Demo Compiling Solidity Smart Contract in React with WebWorker

In this post I gonna compile a Solidity program with Solidity Compiler JS in browsers supported WebWorker.

Tools and plugins:

webpack@4 (included in NX)
Enter fullscreen mode Exit fullscreen mode

Compiling a smart contract with Solc is a heavy task for browsers, and for such heavy task we need to use WebWorker.

The tool for setting up the project is NX. it is great tool to create monos-repository.

Configuring WebWorker for NX

NX is using Webpack underhood, In this post we use worker-plugin to make WebWorker work with Webpack. In order to config worker-plugin we need to extend the default configuration of Webpack inside NX.

  1. Create webpack.json in root folder of frontend module.

    const WorkerPlugin = require('worker-plugin');
    const nrwlConfig = require('@nrwl/react/plugins/webpack.js');
    module.exports = (config, context) => {
        return {
            node: {
                Buffer: true,
                module: 'empty',
            plugins: [new WorkerPlugin(), ...config.plugins],

    As you can see we have some polyfill configurations for NodeJS in Webpack

  2. Add webpack.json to workspace.json file.

    "webpackConfig": "apps/frontend/webpack.config.js"

Here is the detail of webpackConfig option.

Compile Solidity Smart Contract with WebWorker

  1. Solc@0.8.7-fixed doesn't have typescript declaration yet, we have to add a type declaration manually. Simply add declare module 'solc/wrapper'; to *.d.ts file in your project.

  2. Creating a worker SolcJs.worker.ts file.

    /* eslint-disable no-restricted-globals */
    import * as wrapper from 'solc/wrapper';
    const ctx: Worker = self as any;
    ctx.addEventListener('message', ({ data }) => {
        const solc = wrapper((ctx as any).Module);
        const compileResult = solc.compile(
            createCompileInput(data.contractFileName, data.content)
    function createCompileInput(
        fileName = 'storage.sol',
        fileContent: string
    ): string {
        const CompileInput = {
            language: 'Solidity',
            sources: {
                [fileName]: {
                    content: fileContent,
            settings: {
                outputSelection: {
                    '*': {
                        '*': ['*'],
        return JSON.stringify(CompileInput);
  3. Create a Promisify function to call SolcJs.worker.ts and wait until the compilation finished.

    const compileWithWorker = async (data: any) => {
            return new Promise((resolve, reject) => {
                const worker = new Worker('../../SolcJs.worker.ts', {
                    type: 'module',
                worker.onmessage = function (event: any) {
                worker.onerror = reject;

    Thank to the great answer from T.J. Crower

  4. Now we are ready to use WebWorker to compile a Simple Solidity Smart Contract.

    const handleCompile = async () => {
            const result = await compileWithWorker({
                content: SimpleStorageContact,
            setCompileResult(result as string);

SourceCode in Github - nx-webworker-sample

Top comments (0)

11 Tips That Make You a Better Typescript Programmer


1 Think in {Set}

Type is an everyday concept to programmers, but it’s surprisingly difficult to define it succinctly. I find it helpful to use Set as a conceptual model instead.

#2 Understand declared type and narrowed type

One extremely powerful typescript feature is automatic type narrowing based on control flow. This means a variable has two types associated with it at any specific point of code location: a declaration type and a narrowed type.

#3 Use discriminated union instead of optional fields


Read the whole post now!