Open-source project
polkadot-evm/frontier avatar
polkadot-evm/frontier

Frontier: the EVM compatibility layer under Polkadot

Ethereum and EVM compatibility layer for Polkadot and Substrate.

613 stars541 forksRustApache-2.0

At a glance

What is it?
Frontier is the EVM backbone of Polkadot, a compatibility layer that lets unmodified Ethereum dapps run on a Substrate chain, with the Ethereum RPC APIs developers already know. It is also a migration framework, with a Pre-Log Wrapper Block feature aimed at zero-downtime live migration, and it is a large Rust workspace rather than a single crate.
Who is it for?
Frontier suits a team building Ethereum applications that need to land on a Substrate chain, and it suits a chain team that wants Ethereum tooling to keep working, because the RPC surface and the dapp compatibility are the point of the project. It is a poor fit if you want a small dependency, since it is a full runtime workspace with pallets, a client and a template node, and a poor fit if you are on a chain whose runtime cannot host the EVM pallet.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 11 days ago.
What is it written in?
Mainly Rust, according to GitHub's language statistics.

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

Editorial analysis

Run Ethereum dapps on Polkadot without changing them

Frontier is described as the EVM backbone of Polkadot, and it provides a compatibility layer of EVM so that you can run any Ethereum dapps on Polkadot, unmodified.

The second half of that sentence is the whole pitch. Using Frontier gives you access to all the Ethereum RPC APIs you are already familiar with, which means you can continue to develop your dapps in your favourite Ethereum developer tools. A team that has already written a contract, wired up a library and tested against a local node is not asked to rewrite any of it. That is a much bigger deal than the novelty of running an EVM somewhere new, because the cost of blockchain development is dominated by the parts that would otherwise have to be redone.

There is a second consequence that the readme mentions as a bonus: you can even run many Ethereum L2s inside Frontier. A layer 2 is, in the end, a system that executes EVM bytecode and talks to a settlement layer, and Frontier is a layer 2 shaped environment in its own right.

The project points newcomers at two places: the documentation in the `docs` directory, and a template node in the `template` directory, described as available to support a fuller technical exploration. There is also published API documentation generated as rustdoc for the `pallet_evm` pallet, which is where the runtime side of the system is defined.

The workspace shows the architecture

The Cargo workspace manifest is the most informative file in the repository, because the member list is the system design.

The `frame` directory holds the runtime pallets, and the list reads like a map of what an EVM chain needs. There is `frame/evm` for the core virtual machine pallet, `frame/ethereum` for the Ethereum transaction format, `frame/base-fee` and `frame/dynamic-fee` for the two fee models, `frame/evm-chain-id` for the chain identifier, `frame/hotfix-sufficients` for the suffixed account hotfix, and `frame/evm-polkavm`, which appears in three parts, a proc-macro, a uapi directory and the pallet itself.

The `precompiles` directory contains the crypto primitives that Ethereum contracts expect to find at fixed addresses, and the `frame/evm/precompile` tree carries the implementations, one crate each for sha3fips, simple, modexp, ed25519, bn128, blake2, bw6761, bls12377, bls12381, dispatch and curve25519, with benchmarking sub-crates for two of them.

The `client` directory is the node side, with `client/api`, `client/consensus`, `client/rpc-core`, `client/rpc`, a `client/rpc-v2` with its own api and types, `client/db`, `client/storage` and `client/mapping-sync`. The `primitives` directory holds the shared types for accounts, consensus, dynamic fees, the EVM itself, RPC and self-contained bundles.

And there is a `template` directory with a node, a runtime and a fuzz target, which is the piece that turns the library into something you can actually start.

The precompile set is where compatibility is won or lost

A compatibility layer lives or dies on the details, and the precompile list is where those details live in Frontier.

The set covers what Ethereum contracts actually call. There is sha3fips and keccak-style hashing, modexp for modular exponentiation, bn128 for the pairing friendly curve used by precompiled contracts, blake2, ed25519 and curve25519 for signatures, the two BLS curves bls12377 and bls12381, bw6761 for another pairing curve, plus `simple` and `dispatch`, which are not cryptographic at all but provide the simple precompile and the dispatch mechanism for calling into runtime code from a contract.

Two of them carry benchmarking sub-crates, which tells you they are heavy enough that the weight of a call has to be measured properly rather than guessed.

The structure also separates the implementations from the publishing mechanism. There is a top level `precompiles` crate, a `precompiles/macro` crate, and `precompiles/tests-external`, which is a test suite that runs against the implementations rather than inside them. A project that wants a precompile set that matches Ethereum's exactly has to keep that list in step with upstream, and the fact that the implementations are split into many small crates is what makes that comparison practical.

The `frame/evm` pallet sits above all of this, and its generated API documentation is the reference for how a runtime is expected to wire the whole thing together.

The client crates carry the RPC and the state mapping

The `client` directory is where a node's behaviour lives, and the crate names describe the layering.

`client/api` defines the interfaces the other components talk to, `client/consensus` handles the block production and finalisation side, and `client/rpc-core` holds the shared RPC machinery. On top of that sit `client/rpc` for the RPC implementation and `client/rpc-v2`, which has its own `api` and `types` sub-crates, suggesting a second generation of RPC surface developed alongside the first rather than replacing it.

Storage is separated into `client/db` and `client/storage`, and there is a `client/mapping-sync` crate, whose name suggests keeping a mapping in step with the chain state. That is the interesting one for an EVM compatibility layer, because the mapping between Ethereum account and storage state and the Substrate storage model is exactly where a compatibility layer has to do its own work rather than delegate.

The `primitives` directory mirrors that split for types, with `primitives/account`, `primitives/consensus`, `primitives/dynamic-fee`, `primitives/evm`, `primitives/rpc` and `primitives/self-contained`.

Testing the client side is done outside Rust. The `ts-tests` directory holds TypeScript integration tests, with their own npm scripts including a format check, and the Makefile runs them through an `integration-test-lint` target.

A migration framework, not just a compatibility layer

The second half of the readme is about something different from running dapps. Frontier is also a migration framework.

The common strategies for moving a chain are direct state export and import, and transaction level replays. Both have obvious costs: an export and import is a stop-the-world operation, and a transaction level replay is a re-execution of history that takes as long as the history did. Frontier adds a third option, the Pre-Log Wrapper Block feature, described as providing a possible method for a zero-downtime live migration.

The mechanism implied by the name is worth spelling out. A log wrapper block carries an extra payload alongside the block's normal content, which gives a migrating system somewhere to put state or instructions that the EVM itself has no concept of. Because the payload travels with the chain's own blocks, a live migration can be staged rather than performed as one large operation, and the downtime can be reduced to the moment the two systems are switched over.

That is a different requirement from the dapp compatibility story, and it is the one that would decide adoption for a chain team. The readme is careful with the wording, calling it a possible method rather than a guaranteed procedure, and the documentation directory is where the detail lives.

A template node is offered to make the exploration less abstract, and there is a `template/fuzz` crate in the workspace, which suggests the migration path is expected to be exercised against adversarial input.

Building and testing it through the Makefile

The Makefile is the entry point for development, and its targets describe the workflow.

Setting up a development environment is one command:

make
setup:
	bash ./scripts/setup-dev.sh

Formatting is split between two tools, because the repository contains both Rust and TOML:

make
fmt-check:
	taplo fmt --check
	cargo fmt --all -- --check

The clippy targets are where the Substrate specific environment variables show up. Both the debug and release variants set `SKIP_WASM_BUILD=1`, run clippy over all targets with the `runtime-benchmarks` and `try-runtime` features enabled, and turn warnings into errors with `-D warnings`.

The build targets set `WASM_BUILD_TYPE` to debug or release before invoking cargo, because a Substrate runtime is compiled to WebAssembly as well as to native code, and the two builds have different requirements. The test targets run the library tests twice, once plain and once with the `runtime-benchmarks` feature, and then run the fc-mapping-sync tests with the SQL feature so that both backends are covered.

The TypeScript integration tests are handled separately, with an `integration-test-lint` target that installs the npm dependencies in `ts-tests` and runs the format check:

make
integration-test-lint:
	cd ts-tests && npm install && npm run fmt-check

Other files at the root support that workflow: a `rust-toolchain.toml` pinning the toolchain, a `rustfmt.toml`, a `taplo.toml` for the TOML formatting, a `shell.nix` for a reproducible shell, and a `Makefile` target that cleans with `cargo clean`.

Two licences, one repository

The licence situation is unusual and worth reading carefully. The repository carries `LICENSE-APACHE2` and `LICENSE-GPL3` side by side, along with `HEADER-APACHE2` and `HEADER-GPL3` files that are presumably applied per file, and the project metadata records the licence as Apache-2.0.

Two things follow. First, this is a dual licensing setup rather than a single one, and a downstream user needs to check which terms apply to which part of the code before assuming the Apache grant covers everything. Second, the header files suggest the project expects contributions to carry the right header, which is how dual licensed projects keep the two sets of terms consistent across a large contributor base.

The rest of the repository housekeeping is thorough. There is a `SECURITY.md` for reporting vulnerabilities, a `CODEOWNERS` file, a `.coderabbit.yaml` configuration for the automated review bot, a `.editorconfig`, and a `docs` directory that holds the official documentation, with the published site at polkadot-evm.github.io/frontier.

On releases, the repository has no GitHub releases, and the last push was on 2026-10-12 on the default branch `master`. The project communicates on a Matrix channel named `#frontier` on matrix.org. For a component this central to the Polkadot stack, the absence of tagged releases means you should pin by commit and read the changelog in the repository rather than expect version numbers.

Editorial conclusion

Frontier suits a team building Ethereum applications that need to land on a Substrate chain, and it suits a chain team that wants Ethereum tooling to keep working, because the RPC surface and the dapp compatibility are the point of the project. It is a poor fit if you want a small dependency, since it is a full runtime workspace with pallets, a client and a template node, and a poor fit if you are on a chain whose runtime cannot host the EVM pallet. Before you evaluate it, read the `docs` directory and the pallet API docs, run the template node to see the stack end to end, and check the licence choice, since the repository ships both Apache 2.0 and GPL 3.0 with separate header files for each.

Frequently asked questions

What is Frontier used for?

Frontier is the EVM backbone of Polkadot. It provides an EVM compatibility layer so unmodified Ethereum dapps can run on Polkadot, and exposes the Ethereum RPC APIs developers already know, so existing Ethereum tooling keeps working.

Can Frontier run Ethereum layer 2s?

Yes. The readme states that as a bonus you can even run many Ethereum L2s inside Frontier, since a layer 2 is a system executing EVM bytecode and settling against a layer 1.

What is the Pre-Log Wrapper Block feature for?

It is Frontier's answer to live migration. Alongside the common approaches of direct state export and import and transaction level replays, it provides a possible method for a zero-downtime live migration by carrying extra payload with the chain's own blocks.

Which precompiles does Frontier implement?

The workspace lists crates for sha3fips, simple, modexp, ed25519, bn128, blake2, bw6761, bls12377, bls12381, dispatch and curve25519, with benchmarking sub-crates for some of them. The implementations sit under frame/evm/precompile and the publishing machinery under the top level precompiles directory.

How do I set up a development environment for Frontier?

The Makefile has a setup target that runs the development setup script, and the project ships a template node, a template runtime and a fuzz target so you can run the stack locally. Tests are run through cargo with the runtime-benchmarks feature, and the TypeScript integration tests in the ts-tests directory are installed and linted with npm.

Official sources

  1. Issues
  2. License: Apache-2.0
  3. polkadot-evm/frontier on GitHub
  4. Project website
  5. README
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/polkadot-evm-frontier.svg)](https://hysenlabs.com/projects/polkadot-evm-frontier)

Was this useful?