diff --git a/cheap-ruler/cheap-ruler-tests.ts b/cheap-ruler/cheap-ruler-tests.ts
new file mode 100644
index 0000000000..67388e52fd
--- /dev/null
+++ b/cheap-ruler/cheap-ruler-tests.ts
@@ -0,0 +1,60 @@
+///
+
+import * as cheapRuler from 'cheap-ruler'
+
+// -- Fixtures --
+const unit = 'miles'
+const lineString: GeoJSON.Feature = {
+ "type": "Feature",
+ "properties": {},
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [-77.031669, 38.878605],
+ [-77.029609, 38.881946],
+ [-77.020339, 38.884084],
+ [-77.025661, 38.885821],
+ [-77.021884, 38.889563],
+ [-77.019824, 38.892368]
+ ]
+ }
+}
+const line = lineString.geometry.coordinates
+const polygon = [[
+ [-67.031, 50.458], [-67.031, 50.534], [-66.929, 50.534],
+ [-66.929, 50.458], [-67.031, 50.458]
+]]
+const points = [
+ [-67.031, 50.458], [-67.031, 50.534],
+ [-66.929, 50.534], [-66.929, 50.458]
+]
+
+// -- Test initiators --
+cheapRuler(35.05)
+cheapRuler(35.05, 'miles')
+cheapRuler(35.05, unit)
+cheapRuler.fromTile(1567, 12)
+cheapRuler.fromTile(1567, 12, 'miles')
+cheapRuler.fromTile(1567, 12, unit)
+
+// -- Test units --
+cheapRuler.units
+cheapRuler.units.miles
+cheapRuler.units.kilometers
+50 * cheapRuler.units.yards / cheapRuler.units.meters
+
+// -- Test cheapRuler --
+const ruler = cheapRuler(35.05, 'kilometers')
+
+console.log(ruler.distance([30.5, 50.5], [30.51, 50.49]))
+ruler.bearing([30.5, 50.5], [30.51, 50.49])
+ruler.destination([30.5, 50.5], 0.1, 90)
+ruler.lineDistance(points)
+ruler.area(polygon)
+ruler.along(line, 2.5)
+ruler.pointOnLine(line, [-67.04, 50.5]).point
+ruler.lineSlice([-67.04, 50.5], [-67.05, 50.56], line)
+ruler.lineSliceAlong(10, 20, line)
+ruler.bufferPoint([30.5, 50.5], 0.01)
+ruler.bufferBBox([30.5, 50.5, 31, 51], 0.2)
+ruler.insideBBox([30.5, 50.5], [30, 50, 31, 51])
\ No newline at end of file
diff --git a/cheap-ruler/cheap-ruler.d.ts b/cheap-ruler/cheap-ruler.d.ts
new file mode 100644
index 0000000000..97ad51730e
--- /dev/null
+++ b/cheap-ruler/cheap-ruler.d.ts
@@ -0,0 +1,226 @@
+// Type definitions for cheap-ruler 2.4.1
+// Project: https://github.com/mapbox/cheap-ruler
+// Definitions by: Denis Carriere
+// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
+
+///
+
+declare module "cheap-ruler" {
+ interface TemplateUnits {
+ kilometers: number
+ miles: number
+ nauticalmiles: number
+ meters: number
+ metres: number
+ yards: number
+ feet: number
+ inches: number
+ }
+ interface InterfacePointOnLine {
+ point: Array
+ index: number
+ t: number
+ }
+ class CheapRuler {
+ /**
+ * Given two points of the form [longitude, latitude], returns the distance.
+ *
+ * @name distance
+ * @param {Array} a point [longitude, latitude]
+ * @param {Array} b point [longitude, latitude]
+ * @returns {number} distance
+ * @example
+ * var distance = ruler.distance([30.5, 50.5], [30.51, 50.49]);
+ * //=distance
+ */
+ distance(a: Array, b: Array): number;
+
+ /**
+ * Returns the bearing between two points in angles.
+ *
+ * @name bearing
+ * @param {Array} a point [longitude, latitude]
+ * @param {Array} b point [longitude, latitude]
+ * @returns {number} bearing
+ * @example
+ * var bearing = ruler.bearing([30.5, 50.5], [30.51, 50.49]);
+ * //=bearing
+ */
+ bearing(a: Array, b: Array): number;
+
+ /**
+ * Returns a new point given distance and bearing from the starting point.
+ *
+ * @name destination
+ * @param {Array} p point [longitude, latitude]
+ * @param {number} dist distance
+ * @param {number} bearing
+ * @returns {Array} point [longitude, latitude]
+ * @example
+ * var point = ruler.destination([30.5, 50.5], 0.1, 90);
+ * //=point
+ */
+ destination(p: Array, dist: number, bearing: number): Array;
+
+ /**
+ * Given a line (an array of points), returns the total line distance.
+ *
+ * @name lineDistance
+ * @param {Array>} points [longitude, latitude]
+ * @returns {number} total line distance
+ * @example
+ * var length = ruler.lineDistance([
+ * [-67.031, 50.458], [-67.031, 50.534],
+ * [-66.929, 50.534], [-66.929, 50.458]
+ * ]);
+ * //=length
+ */
+ lineDistance(points: Array>): number;
+
+ /**
+ * Given a polygon (an array of rings, where each ring is an array of points), returns the area.
+ *
+ * @name area
+ * @param {Array>>} polygon
+ * @returns {number} area value in the specified units (square kilometers by default)
+ * @example
+ * var area = ruler.area([[
+ * [-67.031, 50.458], [-67.031, 50.534], [-66.929, 50.534],
+ * [-66.929, 50.458], [-67.031, 50.458]
+ * ]]);
+ * //=area
+ */
+ area(polygon: Array>>): number;
+
+ /**
+ * Returns the point at a specified distance along the line.
+ *
+ * @name along
+ * @param {Array>} line
+ * @param {number} dist distance
+ * @returns {Array} point [longitude, latitude]
+ * @example
+ * var point = ruler.along(line, 2.5);
+ * //=point
+ */
+ along(line: Array>, dist: number): Array
+
+ /**
+ * Returns an object of the form {point, index} where point is closest point on the line from the given point, and index is the start index of the segment with the closest point.
+ *
+ * @pointOnLine
+ * @param {Array>} line
+ * @param {Array} p point [longitude, latitude]
+ * @returns {Object} {point, index}
+ * @example
+ * var point = ruler.pointOnLine(line, [-67.04, 50.5]).point;
+ * //=point
+ */
+ pointOnLine(line: Array>, p: Array): InterfacePointOnLine
+
+ /**
+ * Returns a part of the given line between the start and the stop points (or their closest points on the line).
+ *
+ * @name lineSlice
+ * @param {Array} start point [longitude, latitude]
+ * @param {Array} stop point [longitude, latitude]
+ * @param {Array>} line
+ * @returns {Array>} line part of a line
+ * @example
+ * var line2 = ruler.lineSlice([-67.04, 50.5], [-67.05, 50.56], line1);
+ * //=line2
+ */
+ lineSlice(start: Array, stop: Array, line: Array>): Array>
+
+ /**
+ * Returns a part of the given line between the start and the stop points indicated by distance along the line.
+ *
+ * @name lineSliceAlong
+ * @param {number} start distance
+ * @param {number} stop distance
+ * @param {Array>} line
+ * @returns {Array>} line part of a line
+ * @example
+ * var line2 = ruler.lineSliceAlong(10, 20, line1);
+ * //=line2
+ */
+ lineSliceAlong(start: number, stop: number, line: Array>): Array>
+
+ /**
+ * Given a point, returns a bounding box object ([w, s, e, n]) created from the given point buffered by a given distance.
+ *
+ * @name bufferPoint
+ * @param {Array} p point [longitude, latitude]
+ * @param {number} buffer
+ * @returns {Array} box object ([w, s, e, n])
+ * @example
+ * var bbox = ruler.bufferPoint([30.5, 50.5], 0.01);
+ * //=bbox
+ */
+ bufferPoint(p: Array, buffer: number): Array
+
+ /**
+ * Given a bounding box, returns the box buffered by a given distance.
+ *
+ * @name bufferBBox
+ * @param {Array} box object ([w, s, e, n])
+ * @param {number} buffer
+ * @returns {Array} box object ([w, s, e, n])
+ * @example
+ * var bbox = ruler.bufferBBox([30.5, 50.5, 31, 51], 0.2);
+ * //=bbox
+ */
+ bufferBBox(bbox: Array, buffer: number): Array
+
+ /**
+ * Returns true if the given point is inside in the given bounding box, otherwise false.
+ *
+ * @name insideBBox
+ * @param {Array} p point [longitude, latitude]
+ * @param {Array} box object ([w, s, e, n])
+ * @returns {boolean}
+ * @example
+ * var inside = ruler.insideBBox([30.5, 50.5], [30, 50, 31, 51]);
+ * //=inside
+ */
+ insideBBox(p: Array, bbox: Array): boolean
+ }
+ /**
+ * A collection of very fast approximations to common geodesic measurements. Useful for performance-sensitive code that measures things on a city scale.
+ *
+ * @name cheapRuler
+ * @param {number} lat latitude
+ * @param {string} [units='kilometers']
+ * @returns {Object} CheapRuler
+ * @example
+ * var ruler = cheapRuler(35.05, 'miles');
+ * //=ruler
+ */
+ function cheapRuler(lat: number, units?: string): CheapRuler;
+ namespace cheapRuler {
+ /**
+ * Multipliers for converting between units.
+ *
+ * @name units
+ * @example
+ * // convert 50 meters to yards
+ * 50 * cheapRuler.units.yards / cheapRuler.units.meters;
+ */
+ const units: TemplateUnits
+
+ /**
+ * Creates a ruler object from tile coordinates (y and z). Convenient in tile-reduce scripts.
+ *
+ * @name fromTile
+ * @param {number} y
+ * @param {number} z
+ * @param {string} [units='kilometers']
+ * @returns {Object} CheapRuler
+ * @example
+ * var ruler = cheapRuler.fromTile(1567, 12);
+ * //=ruler
+ */
+ function fromTile(y: number, z: number, units?: string)
+ }
+ export = cheapRuler
+}
\ No newline at end of file