Self-hosted service
moonbeam-foundation/moonbeam avatar
moonbeam-foundation/moonbeam

moonbeam: an Ethereum-compatible parachain built on the Polkadot SDK

An Ethereum-compatible smart contract parachain on Polkadot

935 stars383 forksTypeScriptGPL-3.0

At a glance

What is it?
moonbeam is the node implementation for the Moonbeam network, an Ethereum compatible parachain written in Rust on top of the Polkadot SDK. One repository carries three runtimes, dozens of precompiles and the tooling to run a parachain locally with Zombienet.
Who is it for?
moonbeam suits an engineer who needs to build and test Ethereum style contracts against a real parachain runtime without touching mainnet, and the three-runtime layout means the same codebase is testable against Moonbeam, Moonriver and Moonbase before you commit to a network.
Can I use it commercially?
Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
Is it still maintained?
Yes. The repository last received commits 9 days ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

One repository, three runtimes and a wide precompile surface

moonbeam is described as an Ethereum compatible Parachain built with the Polkadot SDK, and the project site is moonbeam.network with technical documentation at docs.moonbeam.network. The repository is the node implementation, not the chain configuration alone.

The workspace layout in Cargo.toml shows the shape of the system. Three runtimes are built from the same tree: runtime/moonbeam, runtime/moonriver and runtime/moonbase, each with its own xcm-emulator-tests member. The Cargo workspace also lists client/ and client/rpc/ pieces including a dev RPC client, a finality client and a vrf client, plus a node binary and node/cli.

The pallet set covers the parts of a parachain that are specific to being a parachain: parachain-staking, ethereum-xcm, erc20-xcm-bridge, xcm-transactor, xcm-weight-trader, moonbeam-foreign-assets, moonbeam-lazy-migrations, moonbeam-orbiters, crowdloan-rewards and proxy-genesis-companion.

The precompiles directory is the part that matters most to an Ethereum developer. It includes balances-erc20, batch, call-permit, collective, conviction-voting, identity, precompile-registry, preimage, proxy, referenda, relay-encoder, relay-data-verifier, xtokens, p256verify and a gmp precompile, alongside Moonbeam specific ones such as crowdloan-rewards and parachain-staking.

The primary language on the repository listing is TypeScript, which reflects the test tooling rather than the node. The workspace also holds typescript-api, types-bundle and test packages under pnpm workspaces, plus an MBIPS directory for the improvement proposals the network follows.

A single-node dev mode with instant seal for fast iteration

The quickest way to get a working chain locally is the Docker dev node, and it needs no relay chain behind it.

bash
# Run a dev service node
docker run --network="host" moonbeamfoundation/moonbeam:v0.52.0 --dev

The dev mode starts the node in instant seal mode, creating a block when a transaction arrives, which the README compares to Ganache auto-mine. For a developer writing contracts, that removes block time from the feedback loop entirely.

Block production is configurable rather than fixed. You can author on a regular interval or take manual control of authorship and finality through the RPC.

bash
# Author a block every 6 seconds.
docker run --network="host" moonbeamfoundation/moonbeam:v0.52.0 --dev --sealing 6000

# Manually control the block authorship and finality
docker run --network="host" moonbeamfoundation/moonbeam:v0.52.0 --dev --sealing manual

That third mode is the one that matters for testing upgrade paths and anything where ordering must be deterministic.

Running a node against the public testnet instead is the same image with a different chain argument:

bash
# Join the public testnet
docker run --network="host" moonbeamfoundation/moonbeam:v0.52.0 --chain alphanet

Docker images are published for every tagged release, and moonbeam --help lists the available options. The tradeoff of the Docker route is that the pinned image tag, v0.52.0 in these examples, will drift behind the newest release as the project ships versions.

Prefunded development accounts for testing without faucets

A development chain with no funded accounts is not usable, so the dev node pre-funds a set of well known addresses. The README explains that they mostly contain the letters th in their names, a reminder that they exist for ethereum-compatible usage, and that they are derived from Substrate's canonical mnemonic.

The list starts with Alith at 0xf24FF3a9CF04c71Dbc94D0b566f7A27B94566cac and Baltathar at 0x3Cd0A705a2DC65e5b1E1205896BaA2be8A07c6e0.

The full list runs from Alith through Baltathar, Charleth, Dorothy, Ethan, Faith, Goliath, Heath, Ida and Judith, and the documentation lists a private key for each of them. Gerald is described separately as the prefunded default account for testing purposes.

These keys are published in the documentation, which is the point: they are shared across every Substrate development chain, and any balance in them is worth nothing. What matters is that a developer never has to script a faucet request or wait for a testnet drip before deploying their first contract.

One practical consequence follows from the instant seal default. Because a block is authored on transaction arrival, a contract that expects multiple transactions to land in a specific order will behave differently on a dev node than on a network with real block times, which is exactly why the manual sealing mode exists.

Zombienet gives you a relay chain and a parachain together

The dev node above runs a parachain without its relay chain, which is fine for contract work but wrong for anything involving XCM or shared security. For that, the Makefile targets spin up a full local network with Zombienet.

bash
# Start Polkadot relay with Moonbeam parachain
make start-zombienet-moonbeam
# Start Kusama relay with Moonriver parachain
make start-zombienet-moonriver

The Makefile pins the versions it fetches: Zombienet v1.3.138, a Polkadot build named stable2512-3, and the bridge relay at v1.8.19. Binaries are downloaded into zombienet/bin and the path is extended there, with per-platform suffixes handled in the Makefile for Linux, macOS on arm64, and x64 versus arm64 processors.

The bridge relay binary is not optional decoration. It is the parity-bridges-common substrate-relay, which is the piece that talks to the remote chain, and it is why a target for the Kusama relay exists alongside the Polkadot one.

This is the heaviest part of the developer setup and the part most likely to fail on a new machine, since it needs a Polkadot binary, a bridge relay and Zombienet all present and version-matched to what the Makefile expects. If you only need to run Solidity, the Docker dev node is the far shorter path.

Lazy-loading nodes fetch state from a remote archive on demand

The lazy-loading mode exists for a specific problem: running a node with your own runtime changes against real production state without syncing the entire chain.

The mechanism is a runtime override. You build the node with your modified runtime, then start it in lazy-loading mode.

bash
# Build the release binary
make release-build
bash
# Start with default configuration (connects to Moonbeam network)
make start-lazy-loading-node

The start target sets up a runtime override directory at .lazy-loading/wasm-runtime-overrides, copies your built runtime WASM into it, creates a default state overrides configuration at .lazy-loading/state-overrides.json, and starts the node pointed at the remote RPC endpoint.

The endpoint and the network are configurable through environment variables:

bash
# Connect to a different network or RPC endpoint
RPC=https://rpc.api.moonriver.moonbeam.network RUNTIME=moonriver make start-lazy-loading-node

The RPC option defaults to https://trace.api.moonbeam.network, and RUNTIME accepts moonbeam, moonriver or moonbase, defaulting to moonbeam. The state-overrides.json file lets you override specific storage values in the remote state, which the README presents as a way to test runtime upgrades or custom configurations without touching the actual chain state.

This is the least documented corner of the repository. The overrides file format is not described, and the remote endpoint is assumed to be an archive node that serves state on demand. That assumption is the failure mode: point the node at a non-archive endpoint and requests for historical state will not be answerable.

Building from source needs a Substrate toolchain and a pinned tag

Building the node from source is a Rust and Substrate project, and the README is direct about the prerequisite: a proper Substrate development environment, with pointers to the Moonbeam development node guide and Polkadot's getting started guide for a refresher.

bash
# Fetch the code
git clone https://github.com/moonbeam-foundation/moonbeam
cd moonbeam

# Build the node (The first build will be long (~30min))
cargo build --release

The first build is documented as taking roughly thirty minutes, which is normal for a Substrate runtime but worth knowing before you start.

The warning that matters is about branches. The README states that cloning the master branch might result in an unstable build, and points to the latest releases for a stable version. That is a specific instruction, and following it is cheap: check out a tag such as v0.52.3 before building.

Testing is split by language. Rust unit tests run with cargo test, and TypeScript integration tests live in the pnpm workspace, executed in CI and runnable locally. The root package.json declares the workspace members test, typescript-api and types-bundle, with a build script that recurses across them and a check script of the same shape. Formatting and linting are handled by Biome at 2.2.5, and a toml-sort.toml file suggests the Cargo manifests are kept sorted by a tool rather than by hand.

GPL-3.0, release cadence and what the tags mean

The licence field on the repository says GPL-3.0. That is a strong copyleft licence, and for a chain implementation the practical reading is that derived works carry the same licence obligations. The repository root also contains a package.json whose license field reads ISC, which applies to the JavaScript workspace tooling rather than to the Rust node. Neither statement is legal advice, and anyone embedding the code in a product should read the LICENSE file itself.

Release history shows paired tags. The newest listed releases are runtime-4401 and v0.52.3, both dated 2026-06-15, with v0.52.2 on 2026-06-04. The pairing is the signal: a runtime version tag and a node version tag are cut together, because a node binary and the runtime it executes have to agree. The runtime tag name is a numeric identifier of the runtime logic itself.

The last push was on 2026-10-14, so the tree is receiving work well after the June tags. The version numbering has moved through the 0.5x line, which for a pre-1.0 project usually signals the API surface is still moving. The repository also carries AUTOMATION.md, RELEASE.md, PERF.md, CONTRIBUTIONS.md and a bug-bounty.md, so the process around releases is documented separately from the code, and there is a runtime-diffs directory for comparing runtime behaviour across versions.

Editorial conclusion

moonbeam suits an engineer who needs to build and test Ethereum style contracts against a real parachain runtime without touching mainnet, and the three-runtime layout means the same codebase is testable against Moonbeam, Moonriver and Moonbase before you commit to a network. It does not suit a team that wants a quick development chain with no relay chain behind it and no interest in Substrate tooling, since the Zombienet path pulls in Polkadot, a bridge relay and the Zombienet binary itself. Before building, pin a tag rather than the master branch, since the README warns that cloning master may produce an unstable build, and note that the newest tagged release is v0.52.3 from 2026-06-15 while the last push was on 2026-10-14.

Frequently asked questions

How do I run a local Moonbeam development node?

Use the Docker image in dev mode, for example docker run --network="host" moonbeamfoundation/moonbeam:v0.52.0 --dev. It starts in instant seal mode, creating a block when a transaction arrives, and needs no relay chain behind it.

What is the difference between moonbeam, moonriver and moonbase in the repository?

They are three runtimes built from the same tree: runtime/moonbeam, runtime/moonriver and runtime/moonbase, each with its own xcm-emulator-tests. The lazy-loading node takes a RUNTIME variable that accepts moonbeam, moonriver or moonbase, defaulting to moonbeam.

What are the prefunded addresses in the moonbeam dev node for?

Running Moonbeam in development mode pre-funds well known addresses whose names mostly contain the letters th, derived from Substrate's canonical mnemonic, so developers can deploy contracts without a faucet. The documentation also lists a prefunded default account for testing named Gerald.

When would I use a lazy-loading node instead of a full sync?

Lazy-loading fetches state from a remote archive node on demand instead of syncing the full chain state, which the README presents as useful for development and testing against production state with custom runtime changes. You build your runtime with make release-build and start it with make start-lazy-loading-node.

Official sources

  1. License: GPL-3.0
  2. moonbeam-foundation/moonbeam on GitHub
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/moonbeam-foundation-moonbeam.svg)](https://hysenlabs.com/projects/moonbeam-foundation-moonbeam)

Was this useful?