As a Substrate builder, I don't see any reason of still implementing custom RPCs as runtime API seems superior to me. So I was wondering about any arguments for still adding custom RPCs to the client.

Runtime APIs come with many upsides:

  • Versioning support
  • Soon™️ part of metadata
  • Part of the runtime per definition, does not require node upgrades
  • Does not require applying a plurality of serde attribute rewiring to all RPC associated types such as
#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "std", serde(bound = ""))]
#[cfg_attr(feature = "std", serde(rename_all = "camelCase"))]`

https://github.com/polkadot-js/api/issues/5529#issuecomment-1465271895 sums up my wariness about RPCs:

TL:DR It seems you are missing the #[serde(rename_all = "camelCase")] attribute in your type - sadly this is just a standard that needs to be followed, since encoding enums different would make the world break (aka it is applied everywhere in Substrate, so the base JS API encoding for any enums follows that de-facto standard)

PS: You are actually better off not doing RPCs and doing all via decl_runtime - lots of reasons, but basically the former cannot be supported on light clients and the former will never appear in the metadata, so it will always be manual (for the latter, both are on the radar for Substrate) and they are actually versioned, unlike RPCs where changing params is a nightmare.

  • I would say that if you have an already running client that calls a bunch of specific RPC methods and you just don't want to update every call to use/handle state_call (eg Ethereum clients and their eth_xxxxx methods). But for the long run it would be indeed way better to avoid that. Jul 18, 2023 at 12:20

1 Answer 1


I would always prefer to add a Runtime API over a custom RPC call.

Runtime API call information is included in the metadata from V15 (which was recently stabilised), which means that tools (like subxt) will be able to automatically provide a nice interface for interacting with them. They can also be versioned and updated via runtime updates without requiring updated binaries to be distributed.

Finally, we will eventually move towards a new set of RPC APIs in Substrate (see https://github.com/paritytech/json-rpc-interface-spec/) which, unlike the current RPC methods, will have zero calls that are just wrappers around Runtime API methods (eg State_getMetadata). So, working with Runtime APIs over custom RPC calls is very much the direction we're heading in :)

Your light client point is also very much a good one; Runtime calls will be available from alternate node implementations by default, too, which is a big win!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.