diff --git a/universal-router/universal-router-tests.ts b/universal-router/universal-router-tests.ts
new file mode 100644
index 0000000000..922ca137ad
--- /dev/null
+++ b/universal-router/universal-router-tests.ts
@@ -0,0 +1,99 @@
+///
+
+import {ActionContext, Params, resolve } from "universal-router";
+
+// Test 1
+const routes1 = [
+ {
+ path: "/one",
+ action: () => "Page One"
+ },
+ {
+ path: "/two",
+ action: () => "Page Two"
+ }
+];
+
+resolve(routes1, { path: "/one" })
+ .then(result => console.log(result));
+
+// Test 2
+const routes2 = [
+ {
+ path: "/hello/:username",
+ action: (context: ActionContext) => `Welcome, ${context.params["username"]}!`
+ }
+];
+
+resolve(routes2, { path: "/hello/john" })
+ .then(result => console.log(result));
+
+
+// Test 3
+const routes3 = [
+ {
+ path: "/hello/:username",
+ action: (ctx: ActionContext, { username }: Params) => `Welcome, ${username}!`
+ }
+];
+
+resolve(routes3, { path: "/hello/john" })
+ .then(result => console.log(result));
+
+
+// Test 4
+const routes4 = [
+ {
+ path: "/hello",
+ action: () => new Promise(resolve => {
+ setTimeout(() => resolve("Welcome!"), 1000);
+ })
+ }
+];
+
+resolve(routes4, { path: "/hello" })
+ .then(result => console.log(result));
+
+// Test 5
+const routes5 = [
+ {
+ path: "/hello/:username",
+ async action(ctx: ActionContext, { username }: Params) {
+ const waitable = async (name: string) => {
+ console.log(`Welcome ${name}`);
+ }
+ await waitable(username);
+ }
+ }
+];
+
+resolve(routes5, { path: "/hello/john" })
+ .then(result => console.log(result));
+
+// Test 6
+const routes6 = [
+ { path: "/one", action: () => "
Page One
" },
+ { path: "/two", action: () => "Page Two
" }
+];
+
+resolve(routes6, { path: "/one" }).then(result => {
+ document.body.innerHTML = result || "Not Found
";
+});
+
+// Test 7
+interface Render {
+ render: typeof render;
+}
+
+const routes7 = [
+ { path: "/one", action: ({ render: func }: ActionContext & Render) => func("Page One
") },
+ { path: "/two", action: ({ render: func }: ActionContext & Render) => func("Page Two
") }
+];
+
+function render(component: string) {
+ return new Promise(resolve => {
+ console.log(`Rendering... ${component}`);
+ });
+}
+
+resolve>(routes7, { path: "/one", render });
diff --git a/universal-router/universal-router.d.ts b/universal-router/universal-router.d.ts
new file mode 100644
index 0000000000..3ddac31265
--- /dev/null
+++ b/universal-router/universal-router.d.ts
@@ -0,0 +1,70 @@
+// Type definitions for universal-router
+// Project: https://github.com/kriasoft/universal-router
+// Definitions by: Jack Moore
+// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
+
+declare module "universal-router" {
+ /**
+ * Params is a key/value object that represents extracted URL paramters. Each
+ * URL parameter resolves to a string.
+ */
+ export interface Params {
+ [key: string]: string;
+ }
+
+ /**
+ * Context represents the context that is passed as the second argument
+ * passed to resolve. By default, it only is require to contain a path, but
+ * can be extended by the way of generics.
+ */
+ export interface Context {
+ path: string;
+ }
+
+ /**
+ * ActionContext is similar to Context, with the exception of an added params
+ * object. ActionContext is passed as the first argument to the action
+ * function.
+ */
+ export interface ActionContext extends Context {
+ params: Params;
+ }
+
+ /**
+ * A Route is a singular route in your application. It contains a path, an
+ * action function, and optional children which are an array of Route.
+ *
+ * @template C User context that is made union with ActionContext.
+ * @template R Result that every action function resolves to. If the action
+ * returns a Promise, R can be the type the Promise resolves to.
+ */
+ export interface Route {
+ path: string,
+ action: (ctx: ActionContext & C, params: Params) => R | Promise | undefined,
+ children?: Routes
+ }
+
+ /**
+ * Routes in an array of type Route.
+ * @template C User context that is made union with ActionContext.
+ * @template R Result that every action function resolves to. If the action
+ * returns a Promise, R can be the type the Promise resolves to.
+ */
+ export type Routes = Route[];
+
+ /**
+ * Resolve function that is given routes and a path or context object.
+ * Returns a Promise that resolves to result of the action function of the
+ * matched route.
+ *
+ * @template C User context that is made union with Context.
+ * @template R Result that every action function resolves to. If the action
+ * returns a Promise, R can be the type the Promise resolves to.
+ *
+ * @param {Routes | Route} routes - Single route or array of routes.
+ * @param {string | String | Context & C} pathOrContext - path to resolve or
+ * context object that contains the path along with other data.
+ * @return {Promise} - Result of matched action function wrapped in a Promsie.
+ */
+ export function resolve(routes: Routes | Route, pathOrContext: string | String | Context & C): Promise
+}
\ No newline at end of file