diff --git a/substrate/Cargo.lock b/substrate/Cargo.lock
index 59b1a41506421c974283b1291377998ffbe2b0a2..bae34ae36746f43adde824a7f002483e8ae85557 100644
--- a/substrate/Cargo.lock
+++ b/substrate/Cargo.lock
@@ -3066,7 +3066,6 @@ dependencies = [
  "parity-codec 2.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-hex 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)",
  "sr-primitives 0.1.0",
  "sr-version 0.1.0",
  "substrate-client 0.1.0",
diff --git a/substrate/core/rpc/Cargo.toml b/substrate/core/rpc/Cargo.toml
index 10c91cc8b8e719939f50c7babdbc05df70afebee..e1ac0a34aa713099b24c8724aeeb73ab02433555 100644
--- a/substrate/core/rpc/Cargo.toml
+++ b/substrate/core/rpc/Cargo.toml
@@ -18,7 +18,6 @@ substrate-primitives = { path = "../primitives" }
 sr-primitives = { path = "../sr-primitives" }
 sr-version = { path = "../sr-version" }
 tokio = "0.1.7"
-serde_json = "1.0"
 
 [dev-dependencies]
 assert_matches = "1.1"
diff --git a/substrate/core/rpc/src/lib.rs b/substrate/core/rpc/src/lib.rs
index 882a341c606face47b01e9e7d31c4bb40bb887c3..cad9f80d8b2e8aae340eb200c39715dae146a405 100644
--- a/substrate/core/rpc/src/lib.rs
+++ b/substrate/core/rpc/src/lib.rs
@@ -30,7 +30,6 @@ extern crate substrate_primitives as primitives;
 extern crate sr_primitives as runtime_primitives;
 extern crate sr_version as runtime_version;
 extern crate tokio;
-extern crate serde_json;
 
 #[macro_use]
 extern crate error_chain;
diff --git a/substrate/core/rpc/src/state/error.rs b/substrate/core/rpc/src/state/error.rs
index de65e466c08b91ea8bca2a5f3608826ba70195b6..587937ea607ab38f6f6d6184c699642eba47f11d 100644
--- a/substrate/core/rpc/src/state/error.rs
+++ b/substrate/core/rpc/src/state/error.rs
@@ -19,17 +19,11 @@ use rpc;
 
 use errors;
 
-use serde_json;
-
 error_chain! {
 	links {
 		Client(client::error::Error, client::error::ErrorKind) #[doc = "Client error"];
 	}
 
-	foreign_links {
-		Json(serde_json::Error);
-	}
-
 	errors {
 		/// Provided block range couldn't be resolved to a list of blocks.
 		InvalidBlockRange(from: String, to: String, details: String) {
diff --git a/substrate/core/rpc/src/state/mod.rs b/substrate/core/rpc/src/state/mod.rs
index 7572cc42d053e4030e420b1a3b66a3252a1ad204..0e90198ffa5445ae1fd2aef0ba0bc1ab8e4f212f 100644
--- a/substrate/core/rpc/src/state/mod.rs
+++ b/substrate/core/rpc/src/state/mod.rs
@@ -33,7 +33,6 @@ use rpc::futures::{stream, Future, Sink, Stream};
 use runtime_primitives::generic::BlockId;
 use runtime_primitives::traits::{Block as BlockT, Header};
 use tokio::runtime::TaskExecutor;
-use serde_json;
 
 use subscriptions::Subscriptions;
 
@@ -66,7 +65,7 @@ build_rpc_trait! {
 
 		/// Returns the runtime metadata as JSON.
 		#[rpc(name = "state_getMetadata")]
-		fn metadata(&self, Trailing<Hash>) -> Result<serde_json::Value>;
+		fn metadata(&self, Trailing<Hash>) -> Result<Vec<u8>>;
 
 		/// Query historical storage entries (by key) starting from a block given as the second parameter.
 		///
@@ -143,10 +142,9 @@ impl<B, E, Block> StateApi<Block::Hash> for State<B, E, Block> where
 		Ok(self.storage(key, block)?.map(|x| x.0.len() as u64))
 	}
 
-	fn metadata(&self, block: Trailing<Block::Hash>) -> Result<serde_json::Value> {
+	fn metadata(&self, block: Trailing<Block::Hash>) -> Result<Vec<u8>> {
 		let block = self.unwrap_or_best(block)?;
-		let metadata = self.client.metadata(&BlockId::Hash(block))?;
-		serde_json::to_value(metadata).map_err(Into::into)
+		self.client.metadata(&BlockId::Hash(block)).map_err(Into::into)
 	}
 
 	fn query_storage(&self, keys: Vec<StorageKey>, from: Block::Hash, to: Trailing<Block::Hash>) -> Result<Vec<StorageChangeSet<Block::Hash>>> {