Load and run Solidity compilers in browser and Node.js environments.
This package provides a flexible system for loading and executing Solidity compilers in any JavaScript environment. In browsers, compilation runs inside a Web Worker to avoid blocking the main thread (and because this is the only way it works). In Node.js, compilers run natively with minimal overhead.
npm install --save web-solc
import { fetchAndLoadSolc } from "web-solc";
// Fetch and load a compiler in one step
const solc = await fetchAndLoadSolc("^0.8.0");
// Compile your contracts
const output = await solc.compile({
language: "Solidity",
sources: {
"Contract.sol": {
content: "pragma solidity ^0.8.0; contract MyContract { }",
},
},
settings: {
outputSelection: {
"*": {
"*": ["*"],
},
},
},
});
// Clean up (important in browsers to terminate the Worker)
solc.stopWorker();
This library separates compiler fetching from loading, giving you full control over how compilers are sourced, cached, and instantiated:
- Fetch: Get the compiler JavaScript (from CDN, cache, filesystem, etc.)
- Load: Create a working compiler instance from that JavaScript
- Compile: Use the instance to compile your Solidity code
import { fetchSolc, loadSolc } from "web-solc";
// Step 1: Fetch compiler JavaScript (a string)
const soljson = await fetchSolc("^0.8.26");
// Step 2: Create compiler instance
const solc = await loadSolc(soljson);
// Step 3: Compile
const output = await solc.compile(/* ... */);
This separation enables usage patterns like caching, offline usage, and custom compiler sources.
fetchAndLoadSolc(versionRange, options?)
— Fetch and load compiler in one step
function fetchAndLoadSolc(
versionRange: string,
options?: FetchAndLoadOptions
): Promise<WebSolc>;
The simplest way to get a working compiler. Combines fetchSolc
and loadSolc
for convenience.
Parameters:
-
versionRange
— Semantic version range ("^0.8.0"
,"0.8.26"
,"latest"
) -
options.fetch
— Repository configuration (optional) -
options.load
— Compiler loading options (optional)
Example:
const solc = await fetchAndLoadSolc("^0.8.0");
const output = await solc.compile(input);
solc.stopWorker();
fetchSolc(versionRange, options?)
— Download compiler JavaScript
function fetchSolc(
versionRange: string,
options?: FetchOptions
): Promise<string>;
Downloads the compiler JavaScript from binaries.soliditylang.org.
Parameters:
-
versionRange
— Semantic version range for selecting compiler -
options.repository.baseUrl
— Alternative CDN URL (optional) -
options.build
— Compiler build type:"wasm"
(default) or"emscripten"
(optional)
Returns: Compiler JavaScript as a string
Example:
const soljson = await fetchSolc("0.8.26");
// Store it, cache it, or load it immediately
localStorage.setItem("solc-0.8.26", soljson);
// Fetch emscripten build (for compatibility with older environments)
const emscriptenSoljson = await fetchSolc("0.8.26", { build: "emscripten" });
resolveSolc(versionRange, options?)
— Resolve version range to exact version
function resolveSolc(
versionRange: string,
options?: FetchOptions
): Promise<{ version: string; path: string }>;
Resolves a semantic version range to the exact compiler version and path, without downloading the compiler.
Parameters:
-
versionRange
— Semantic version range for selecting compiler -
options.repository.baseUrl
— Alternative CDN URL (optional) -
options.build
— Compiler build type:"wasm"
(default) or"emscripten"
(optional)
Returns: Object with exact version
and path
Example:
const { version, path } = await resolveSolc("^0.8.0");
console.log(version); // "0.8.26"
console.log(path); // "soljson-v0.8.26+commit.8a97fa7a.js"
// Useful for checking what version would be downloaded
const latest = await resolveSolc("latest");
console.log(`Latest version is ${latest.version}`);
loadSolc(soljson, options?)
— Create compiler instance
function loadSolc(soljson: string, options?: LoadOptions): Promise<WebSolc>;
Creates a working compiler instance from JavaScript source.
Parameters:
-
soljson
— The compiler JavaScript as a string -
options
— Advanced configuration (rarely needed)
Returns: WebSolc instance ready to compile
Example:
// From any source: CDN, filesystem, cache, etc.
const soljson = await getCompilerSomehow();
const solc = await loadSolc(soljson);
compile(input)
— Compile Solidity code
compile(input: CompilerInput): Promise<CompilerOutput>
Example:
const output = await solc.compile({
language: "Solidity",
sources: {
"Contract.sol": {
content: "pragma solidity ^0.8.0; contract C { }",
},
},
settings: {
outputSelection: {
"*": { "*": ["abi", "evm.bytecode"] },
},
},
});
stopWorker()
— Clean up resources
stopWorker(): void
Important: Always call this when done, especially in browsers where it terminates the Web Worker.
try {
const output = await solc.compile(input);
// Use output...
} finally {
solc.stopWorker();
}
The compile
method uses Solidity's Compiler Input and Output JSON format:
const input = {
language: "Solidity",
sources: {
"MyContract.sol": {
content: "pragma solidity ^0.8.0; contract MyContract { }",
},
},
settings: {
outputSelection: {
"*": {
"*": ["abi", "evm.bytecode", "evm.deployedBytecode"],
},
},
optimizer: {
enabled: true,
runs: 200,
},
},
};
const output = await solc.compile(input);
// Check for errors
if (output.errors?.some((e) => e.severity === "error")) {
console.error("Compilation failed:", output.errors);
}
// Access compiled contracts
const contract = output.contracts["MyContract.sol"]["MyContract"];
console.log(contract.abi);
console.log(contract.evm.bytecode.object);
import { fetchSolc, loadSolc } from "web-solc";
const compilerCache = new Map();
async function getCompiler(version) {
if (!compilerCache.has(version)) {
const soljson = await fetchSolc(version);
compilerCache.set(version, await loadSolc(soljson));
}
return compilerCache.get(version);
}
import { resolveSolc, fetchSolc, loadSolc } from "web-solc";
// Check what version a range resolves to
const { version } = await resolveSolc("^0.8.0");
console.log(`Will use Solidity ${version}`);
// Cache by exact version, not range
const versionCache = new Map();
async function getCompilerForRange(range) {
const { version } = await resolveSolc(range);
if (!versionCache.has(version)) {
const soljson = await fetchSolc(version);
versionCache.set(version, await loadSolc(soljson));
}
return versionCache.get(version);
}
// "^0.8.0" and ">=0.8.0 <0.9.0" may resolve to same version
const compiler1 = await getCompilerForRange("^0.8.0");
const compiler2 = await getCompilerForRange(">=0.8.0 <0.9.0");
// Pre-download compilers during build
const soljson = await fetchSolc("0.8.26");
fs.writeFileSync("./compilers/solc-0.8.26.js", soljson);
// Load from filesystem later
const soljson = fs.readFileSync("./compilers/solc-0.8.26.js", "utf8");
const solc = await loadSolc(soljson);
const solc = await fetchAndLoadSolc("^0.8.0", {
fetch: {
repository: {
baseUrl: "https://my-mirror.com/solidity-compilers",
},
},
});
const [solc8, solc7] = await Promise.all([
fetchAndLoadSolc("^0.8.0"),
fetchAndLoadSolc("^0.7.0"),
]);
// Use the appropriate compiler based on pragma
const output = pragma.includes("0.8")
? await solc8.compile(input)
: await solc7.compile(input);
// Clean up when done
solc8.stopWorker();
solc7.stopWorker();
This package is written in TypeScript and includes comprehensive type definitions.
View type definitions
import type {
WebSolc,
CompilerInput,
CompilerOutput,
FetchOptions,
LoadOptions,
FetchAndLoadOptions,
} from "web-solc";
// Core instance type
interface WebSolc {
compile(input: CompilerInput): Promise<CompilerOutput>;
stopWorker(): void;
}
// Options for fetchSolc
interface FetchOptions {
repository?: {
baseUrl?: string;
};
build?: "wasm" | "emscripten";
}
// Options for loadSolc
interface LoadOptions {
compatibility?: {
disableCompilerInterfaces?: Array<"legacy" | "modern">;
};
}
// Combined options for fetchAndLoadSolc
interface FetchAndLoadOptions {
fetch?: FetchOptions;
load?: LoadOptions;
}
- Browser: 0.4.16+ (requires WebAssembly builds for some older versions)
- Node.js: 0.4.16+
See the detailed compatibility report for specific version support.
web-solc supports two build types:
-
WebAssembly (WASM) - Default, recommended for browsers
- Available from Solidity 0.3.6+
- More efficient and stable in browser environments
- Avoids stack overflow issues with older compiler versions
-
Emscripten - Legacy JavaScript builds
- Available for all versions
- May cause stack overflow in browsers for some 0.4.x and 0.5.x versions
- Works reliably in Node.js
The library defaults to WASM builds when using fetchSolc
. Use the build
option to explicitly request Emscripten builds if needed for compatibility.