diff --git a/rust/radix20/Cargo.toml b/rust/radix20/Cargo.toml
new file mode 100644
--- /dev/null
+++ b/rust/radix20/Cargo.toml
@@ -0,0 +1,12 @@
+[package]
+name = "radix20"
+version = "0.1.0"
+
+[dependencies]
+error-chain = "0.11"
+
+[dev-dependencies]
+quickcheck = "0.4"
+rand = "0.3"
+rand_derive = "0.3"
+rustc-test = "0.2"
diff --git a/rust/radix20/README.md b/rust/radix20/README.md
new file mode 100644
--- /dev/null
+++ b/rust/radix20/README.md
@@ -0,0 +1,8 @@
+# radix20
+
+20-byte keys to integers mapping using a radix tree stored on plain buffers.
+
+There are 2 plain buffers:
+
+  - Key buffer: A list of 20-bytes keys and other associated information. Keys are indexed by offsets. Not written by o the library.
+  - Index buffer: One or more radix trees mapping keys to their offsets. Written by the library.
diff --git a/rust/radix20/src/errors.rs b/rust/radix20/src/errors.rs
new file mode 100644
--- /dev/null
+++ b/rust/radix20/src/errors.rs
@@ -0,0 +1,13 @@
+// Copyright 2017 Facebook, Inc.
+//
+// This software may be used and distributed according to the terms of the
+// GNU General Public License version 2 or any later version.
+
+error_chain! {
+    errors {
+        OffsetOverflow(offset: u64) {
+            description("offset overflow")
+            display("offset {} is out of range", offset)
+        }
+    }
+}
diff --git a/rust/radix20/src/lib.rs b/rust/radix20/src/lib.rs
new file mode 100644
--- /dev/null
+++ b/rust/radix20/src/lib.rs
@@ -0,0 +1,17 @@
+// Copyright 2017 Facebook, Inc.
+//
+// This software may be used and distributed according to the terms of the
+// GNU General Public License version 2 or any later version.
+
+#[macro_use]
+extern crate error_chain;
+
+#[cfg(test)]
+extern crate rand;
+
+#[cfg(test)]
+#[macro_use]
+extern crate rand_derive;
+
+pub mod types;
+pub mod errors;
diff --git a/rust/radix20/src/types.rs b/rust/radix20/src/types.rs
new file mode 100644
--- /dev/null
+++ b/rust/radix20/src/types.rs
@@ -0,0 +1,61 @@
+// Copyright 2017 Facebook, Inc.
+//
+// This software may be used and distributed according to the terms of the
+// GNU General Public License version 2 or any later version.
+
+use std::borrow::Borrow;
+use std::cell::RefCell;
+use std::rc::Rc;
+use std::ops::Deref;
+use std::convert::{From, Into};
+pub type Shared<B> = Rc<RefCell<B>>;
+
+/// Fixed 20 bytes. Typically it's a hash used in source control.
+#[cfg(not(test))]
+#[derive(Debug, Eq, PartialEq, PartialOrd, Ord, Clone, Copy, Default, Hash)]
+pub struct Key([u8; 20]);
+
+#[cfg(test)]
+#[derive(Debug, Eq, PartialEq, PartialOrd, Ord, Clone, Copy, Default, Hash, Rand)]
+pub struct Key([u8; 20]);
+
+impl Key {
+    #[inline]
+    pub fn fixed_len() -> usize { 20 }
+}
+
+impl<T: Borrow<[u8; 20]>> From<T> for Key {
+    #[inline]
+    fn from(v: T) -> Self { Key(*v.borrow()) }
+}
+
+impl Deref for Key {
+    type Target = [u8; 20];
+
+    #[inline]
+    fn deref(&self) -> &Self::Target { &self.0 }
+}
+
+#[derive(Debug, Eq, PartialEq, PartialOrd, Ord, Clone, Copy, Default)]
+pub struct KeyId(u64);
+
+/// An integer that maps to a `Key`. Typically self-incremental.
+impl From<u64> for KeyId {
+    #[inline]
+    fn from(v: u64) -> Self { KeyId(v) }
+}
+
+impl Into<u64> for KeyId {
+    #[inline]
+    fn into(self) -> u64 { self.0 }
+}
+
+/// Support `resize` in-place.
+pub trait Resize<T> {
+    fn resize(&mut self, new_len: usize, value: T);
+}
+
+impl<T: Copy> Resize<T> for Vec<T> {
+    #[inline]
+    fn resize(&mut self, new_len: usize, value: T) { Vec::resize(self, new_len, value) }
+}
\ No newline at end of file