diff --git a/assets-with-umi-ts/.autod.conf.js b/assets-with-umi-ts/.autod.conf.js
new file mode 100644
index 0000000..cd4bc15
--- /dev/null
+++ b/assets-with-umi-ts/.autod.conf.js
@@ -0,0 +1,28 @@
+'use strict';
+
+module.exports = {
+  write: true,
+  plugin: 'autod-egg',
+  prefix: '^',
+  devprefix: '^',
+  exclude: [
+    'test/fixtures',
+    'coverage',
+  ],
+  dep: [
+    'egg',
+    'egg-scripts',
+  ],
+  devdep: [
+    'autod',
+    'autod-egg',
+    'egg-bin',
+    'tslib',
+    'typescript',
+  ],
+  keep: [
+  ],
+  semver: [
+  ],
+  test: 'scripts',
+};
diff --git a/assets-with-umi-ts/.editorconfig b/assets-with-umi-ts/.editorconfig
new file mode 100644
index 0000000..7e3649a
--- /dev/null
+++ b/assets-with-umi-ts/.editorconfig
@@ -0,0 +1,16 @@
+# http://editorconfig.org
+root = true
+
+[*]
+indent_style = space
+indent_size = 2
+end_of_line = lf
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
+
+[*.md]
+trim_trailing_whitespace = false
+
+[Makefile]
+indent_style = tab
diff --git a/assets-with-umi-ts/.env b/assets-with-umi-ts/.env
new file mode 100644
index 0000000..847f6f8
--- /dev/null
+++ b/assets-with-umi-ts/.env
@@ -0,0 +1,2 @@
+BROWSER=none
+ESLINT=1
diff --git a/assets-with-umi-ts/.eslintignore b/assets-with-umi-ts/.eslintignore
new file mode 100644
index 0000000..8dd2546
--- /dev/null
+++ b/assets-with-umi-ts/.eslintignore
@@ -0,0 +1,4 @@
+#coverage
+coverage/*
+#node_modules
+node_modules/*
diff --git a/assets-with-umi-ts/.eslintrc b/assets-with-umi-ts/.eslintrc
new file mode 100644
index 0000000..6f04cfa
--- /dev/null
+++ b/assets-with-umi-ts/.eslintrc
@@ -0,0 +1,11 @@
+{
+  "extends": "eslint-config-umi",
+  "parserOptions": {
+    "ecmaVersion": 2017,
+    "ecmaFeatures": {
+      "arrowFunctions": true,
+      "generators": true,
+      "jsx": true
+    }
+  }
+}
diff --git a/assets-with-umi-ts/.gitignore b/assets-with-umi-ts/.gitignore
new file mode 100644
index 0000000..7d50fdf
--- /dev/null
+++ b/assets-with-umi-ts/.gitignore
@@ -0,0 +1,18 @@
+# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
+
+# dependencies
+/node_modules
+/npm-debug.log*
+/yarn-error.log
+/yarn.lock
+/package-lock.json
+
+# production
+/dist
+
+# misc
+.DS_Store
+
+# umi
+.umi
+.umi-production
diff --git a/assets-with-umi-ts/.prettierignore b/assets-with-umi-ts/.prettierignore
new file mode 100644
index 0000000..2098c78
--- /dev/null
+++ b/assets-with-umi-ts/.prettierignore
@@ -0,0 +1,7 @@
+**/*.md
+**/*.svg
+**/*.ejs
+**/*.html
+package.json
+.umi
+.umi-production
diff --git a/assets-with-umi-ts/.prettierrc b/assets-with-umi-ts/.prettierrc
new file mode 100644
index 0000000..d3698d4
--- /dev/null
+++ b/assets-with-umi-ts/.prettierrc
@@ -0,0 +1,11 @@
+{
+  "singleQuote": true,
+  "trailingComma": "all",
+  "printWidth": 100,
+  "overrides": [
+    {
+      "files": ".prettierrc",
+      "options": { "parser": "json" }
+    }
+  ]
+}
diff --git a/assets-with-umi-ts/.travis.yml b/assets-with-umi-ts/.travis.yml
new file mode 100644
index 0000000..b735efc
--- /dev/null
+++ b/assets-with-umi-ts/.travis.yml
@@ -0,0 +1,10 @@
+sudo: false
+language: node_js
+node_js:
+  - '8'
+install:
+  - npm i npminstall && npminstall
+script:
+  - npm run ci
+after_script:
+  - npminstall codecov && codecov
diff --git a/assets-with-umi-ts/.umirc.local.ts b/assets-with-umi-ts/.umirc.local.ts
new file mode 100644
index 0000000..7b57a60
--- /dev/null
+++ b/assets-with-umi-ts/.umirc.local.ts
@@ -0,0 +1,13 @@
+import { IConfig } from 'umi-types';
+
+// ref: https://umijs.org/config/
+const config: IConfig = {
+  proxy: {
+    '/restapi': {
+      target: 'http://127.0.0.1:7001/',
+      changeOrigin: true,
+    },
+  },
+};
+
+export default config;
diff --git a/assets-with-umi-ts/.umirc.prod.ts b/assets-with-umi-ts/.umirc.prod.ts
new file mode 100644
index 0000000..790ba1c
--- /dev/null
+++ b/assets-with-umi-ts/.umirc.prod.ts
@@ -0,0 +1,14 @@
+import { IConfig } from 'umi-types';
+
+// ref: https://umijs.org/config/
+// tslint:disable-next-line:no-multi-spaces
+const config: IConfig =  {
+  hash: true,
+  publicPath: '',
+  outputPath: './app/public',
+  manifest: {
+    fileName: '../../config/manifest.json',
+  },
+};
+
+export default config;
diff --git a/assets-with-umi-ts/.umirc.ts b/assets-with-umi-ts/.umirc.ts
new file mode 100644
index 0000000..3eff314
--- /dev/null
+++ b/assets-with-umi-ts/.umirc.ts
@@ -0,0 +1,31 @@
+import { IConfig } from 'umi-types';
+
+// ref: https://umijs.org/config/
+const config: IConfig =  {
+  plugins: [
+    // ref: https://umijs.org/plugin/umi-plugin-react.html
+    [ 'umi-plugin-react', {
+      antd: true,
+      dva: true,
+      title: 'assets-with-umi-ts',
+      dll: false,
+      dynamicImport: {
+        webpackChunkName: true,
+      },
+      routes: {
+        exclude: [
+          /models\//,
+          /services\//,
+          /model\.(t|j)sx?$/,
+          /service\.(t|j)sx?$/,
+          /components\//,
+        ],
+      },
+    }],
+  ],
+  runtimePublicPath: true,
+  disableCSSModules: false,
+  cssModulesWithAffix: false,
+};
+
+export default config;
diff --git a/assets-with-umi-ts/README.md b/assets-with-umi-ts/README.md
new file mode 100644
index 0000000..41f87ea
--- /dev/null
+++ b/assets-with-umi-ts/README.md
@@ -0,0 +1,34 @@
+# assets-with-umi-ts
+
+showcase for egg&umi with typescript
+
+## QuickStart
+
+### Development
+
+```bash
+$ npm i
+$ npm run dev
+$ open http://localhost:7001/
+```
+
+Don't tsc compile at development mode, if you had run `tsc` then you need to `npm run clean` before `npm run dev`.
+
+### Deploy
+
+```bash
+$ npm run build:umi
+$ npm run tsc
+$ npm start
+```
+
+### Npm Scripts
+
+- Use `npm run lint` to check code style
+- Use `npm test` to run unit test
+- se `npm run clean` to clean compiled js at development mode once
+
+### Requirement
+
+- Node.js 8.x
+- Typescript 2.8+
diff --git a/assets-with-umi-ts/app/controller/home.ts b/assets-with-umi-ts/app/controller/home.ts
new file mode 100644
index 0000000..24645ba
--- /dev/null
+++ b/assets-with-umi-ts/app/controller/home.ts
@@ -0,0 +1,23 @@
+import { Controller } from 'egg';
+import { RequestOptions2 } from 'urllib';
+
+export default class HomeController extends Controller {
+   async index() {
+    await this.ctx.render('index.html');
+  }
+
+   async api() {
+    const ctx = this.ctx;
+
+    const url = 'https://h5.ele.me' + ctx.path.replace(/^\/api/, '') + '?' + ctx.querystring;
+
+    console.log(url);
+    const options: RequestOptions2 = {
+      // @ts-ignore
+      method: this.ctx.method,
+    };
+    const res = await this.ctx.curl(url, options) ;
+    ctx.body = res.data;
+    ctx.status = res.status;
+  }
+}
diff --git a/assets-with-umi-ts/app/router.ts b/assets-with-umi-ts/app/router.ts
new file mode 100644
index 0000000..9af0eb0
--- /dev/null
+++ b/assets-with-umi-ts/app/router.ts
@@ -0,0 +1,7 @@
+import { Application } from 'egg';
+
+export default (app: Application) => {
+  const { router, controller } = app;
+  router.all('/restapi/*', controller.home.api);
+  router.get('*', controller.home.index);
+};
diff --git a/assets-with-umi-ts/app/service/Test.ts b/assets-with-umi-ts/app/service/Test.ts
new file mode 100644
index 0000000..86f5cb2
--- /dev/null
+++ b/assets-with-umi-ts/app/service/Test.ts
@@ -0,0 +1,11 @@
+import { Service } from 'egg';
+
+/**
+ * Test Service
+ */
+export default class Test extends Service {
+
+  async sayHi(name: string): Promise<string> {
+    return `hi, ${name}`;
+  }
+}
diff --git a/assets-with-umi-ts/app/view/index.html b/assets-with-umi-ts/app/view/index.html
new file mode 100644
index 0000000..46eecbd
--- /dev/null
+++ b/assets-with-umi-ts/app/view/index.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<html>
+<head>
+<meta charset="utf-8" />
+<meta name="apple-mobile-web-app-capable" content="yes"/>
+<meta name="apple-mobile-web-app-status-bar-style" content="black"/>
+<meta name="format-detection" content="telephone=no"/>
+<meta name="format-detection" content="email=no"/>
+<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no" />
+<title></title>
+{% if ctx.app.config.env !== 'local' -%}
+  {{ helper.assets.getStyle('umi.css') | safe }}
+{%- endif %}
+</head>
+<body>
+
+<div id="root"></div>
+
+<script>
+  window.routerBase = '/';
+  window.resourceBaseUrl = '{{ helper.assets.resourceBase }}';
+</script>
+{{ helper.assets.getScript('umi.js') | safe }}
+</body>
+</html>
diff --git a/assets-with-umi-ts/appveyor.yml b/assets-with-umi-ts/appveyor.yml
new file mode 100644
index 0000000..c274b7d
--- /dev/null
+++ b/assets-with-umi-ts/appveyor.yml
@@ -0,0 +1,14 @@
+environment:
+  matrix:
+    - nodejs_version: '8'
+
+install:
+  - ps: Install-Product node $env:nodejs_version
+  - npm i npminstall && node_modules\.bin\npminstall
+
+test_script:
+  - node --version
+  - npm --version
+  - npm run test
+
+build: off
diff --git a/assets-with-umi-ts/config/config.default.ts b/assets-with-umi-ts/config/config.default.ts
new file mode 100644
index 0000000..b31f315
--- /dev/null
+++ b/assets-with-umi-ts/config/config.default.ts
@@ -0,0 +1,55 @@
+import { EggAppConfig, EggAppInfo, PowerPartial } from 'egg';
+
+export default (appInfo: EggAppInfo) => {
+  const config = {} as PowerPartial<EggAppConfig>;
+
+  // override config from framework / plugin
+  // use for cookie sign key, should change to your own and keep security
+  config.keys = appInfo.name + '_1559730819165_5307';
+
+  // add your egg config in here
+  config.middleware = [];
+
+  config.view = {
+    mapping: {
+      '.html': 'nunjucks',
+    },
+  };
+
+  config.assets = {
+    publicPath: '/public/',
+    devServer: {
+      debug: true,
+      command: 'umi dev',
+      port: 8000,
+      env: {
+        APP_ROOT: process.cwd(),
+        BROWSER: 'none',
+        ESLINT: 'none',
+        SOCKET_SERVER: 'http://127.0.0.1:8000',
+        PUBLIC_PATH: 'http://127.0.0.1:8000',
+      },
+    },
+  };
+
+  config.security = {
+    csrf: false,
+  };
+
+  config.logger = {
+    level: 'INFO',
+    consoleLevel: 'INFO',
+    allowDebugAtProd: true,
+  };
+
+  // add your special config in here
+  const bizConfig = {
+    sourceUrl: `https://github.com/eggjs/examples/tree/master/${appInfo.name}`,
+  };
+
+  // the return config will combines to EggAppConfig
+  return {
+    ...config,
+    ...bizConfig,
+  };
+};
diff --git a/assets-with-umi-ts/config/config.local.ts b/assets-with-umi-ts/config/config.local.ts
new file mode 100644
index 0000000..dcb3cc9
--- /dev/null
+++ b/assets-with-umi-ts/config/config.local.ts
@@ -0,0 +1,11 @@
+import { EggAppConfig, PowerPartial } from 'egg';
+
+export default () => {
+  const config: PowerPartial<EggAppConfig> = {};
+  config.logger = {
+    level: 'INFO',
+    consoleLevel: 'INFO',
+    allowDebugAtProd: true,
+  };
+  return config;
+};
diff --git a/assets-with-umi-ts/config/config.prod.ts b/assets-with-umi-ts/config/config.prod.ts
new file mode 100644
index 0000000..dcb3cc9
--- /dev/null
+++ b/assets-with-umi-ts/config/config.prod.ts
@@ -0,0 +1,11 @@
+import { EggAppConfig, PowerPartial } from 'egg';
+
+export default () => {
+  const config: PowerPartial<EggAppConfig> = {};
+  config.logger = {
+    level: 'INFO',
+    consoleLevel: 'INFO',
+    allowDebugAtProd: true,
+  };
+  return config;
+};
diff --git a/assets-with-umi-ts/config/plugin.ts b/assets-with-umi-ts/config/plugin.ts
new file mode 100644
index 0000000..2d6d1cc
--- /dev/null
+++ b/assets-with-umi-ts/config/plugin.ts
@@ -0,0 +1,14 @@
+import { EggPlugin } from 'egg';
+
+const plugin: EggPlugin = {
+  nunjucks: {
+    enable: true,
+    package: 'egg-view-nunjucks',
+  },
+  assets : {
+    enable: true,
+    package: 'egg-view-assets',
+  },
+};
+
+export default plugin;
diff --git a/assets-with-umi-ts/mock/.gitkeep b/assets-with-umi-ts/mock/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/assets-with-umi-ts/package.json b/assets-with-umi-ts/package.json
new file mode 100644
index 0000000..1b70fac
--- /dev/null
+++ b/assets-with-umi-ts/package.json
@@ -0,0 +1,97 @@
+{
+  "name": "assets-with-umi-ts",
+  "version": "1.0.0",
+  "description": "",
+  "private": true,
+  "egg": {
+    "typescript": true,
+    "declarations": true
+  },
+  "scripts": {
+    "start": "egg-scripts start  --title=egg-server-assets-with-umi-ts",
+    "stop": "egg-scripts stop --title=egg-server-assets-with-umi-ts",
+    "dev": "egg-bin dev",
+    "debug": "egg-bin debug",
+    "test-local": "egg-bin test",
+    "test": "npm run lint -- --fix && npm run test-local",
+    "cov": "egg-bin cov",
+    "tsc": "ets && tsc -p tsconfig.json",
+    "ci": "npm run lint && npm run cov && npm run tsc",
+    "autod": "autod",
+    "lint": "tslint --project . -c tslint.json",
+    "clean": "ets clean",
+    "start:umi": "umi dev",
+    "build:umi": "UMI_ENV=prod CI=true  umi build",
+    "test:umi": "umi test",
+    "lint:es": "eslint --ext .js src mock tests",
+    "lint:ts": "tslint \"src/**/*.ts\" \"src/**/*.tsx\""
+  },
+  "dependencies": {
+    "antd": "^3.19.2",
+    "dva": "^2.6.0-beta.4",
+    "egg": "^2.6.1",
+    "egg-scripts": "^2.6.0",
+    "egg-view-assets": "^1.5.0",
+    "egg-view-nunjucks": "^2.2.0",
+    "react": "^16.8.6",
+    "react-dom": "^16.8.6"
+  },
+  "devDependencies": {
+    "@types/mocha": "^2.2.40",
+    "@types/node": "^7.0.12",
+    "@types/supertest": "^2.0.0",
+    "autod": "^3.0.1",
+    "autod-egg": "^1.1.0",
+    "egg-ci": "^1.8.0",
+    "egg-bin": "^4.11.0",
+    "egg-mock": "^3.16.0",
+    "tslib": "^1.9.0",
+    "tslint-config-egg": "^1.0.0",
+    "typescript": "^3.0.0",
+    "@types/jest": "^23.3.12",
+    "@types/react": "^16.7.18",
+    "@types/react-dom": "^16.0.11",
+    "@types/react-test-renderer": "^16.0.3",
+    "babel-eslint": "^9.0.0",
+    "eslint": "^5.4.0",
+    "eslint-config-umi": "^1.4.0",
+    "eslint-plugin-flowtype": "^2.50.0",
+    "eslint-plugin-import": "^2.14.0",
+    "eslint-plugin-jsx-a11y": "^5.1.1",
+    "eslint-plugin-react": "^7.11.1",
+    "husky": "^0.14.3",
+    "lint-staged": "^7.2.2",
+    "react-test-renderer": "^16.7.0",
+    "tslint": "^5.12.0",
+    "tslint-eslint-rules": "^5.4.0",
+    "tslint-react": "^3.6.0",
+    "umi": "^2.7.0",
+    "umi-plugin-react": "^1.8.0",
+    "umi-types": "^0.2.0"
+  },
+  "lint-staged": {
+    "*.{ts,tsx}": [
+      "tslint --fix",
+      "git add"
+    ],
+    "*.{js,jsx}": [
+      "eslint --fix",
+      "git add"
+    ]
+  },
+  "engines": {
+    "node": ">=8.9.0"
+  },
+  "ci": {
+    "version": "8"
+  },
+  "repository": {
+    "type": "git",
+    "url": ""
+  },
+  "eslintIgnore": [
+    "coverage"
+  ],
+  "author": "",
+  "license": "MIT"
+}
diff --git a/assets-with-umi-ts/src/app.ts b/assets-with-umi-ts/src/app.ts
new file mode 100644
index 0000000..e7a98d7
--- /dev/null
+++ b/assets-with-umi-ts/src/app.ts
@@ -0,0 +1,9 @@
+
+export const dva = {
+  config: {
+    onError(err: ErrorEvent) {
+      err.preventDefault();
+      console.error(err.message);
+    },
+  },
+};
diff --git a/assets-with-umi-ts/src/assets/yay.jpg b/assets-with-umi-ts/src/assets/yay.jpg
new file mode 100644
index 0000000..e72bd8f
Binary files /dev/null and b/assets-with-umi-ts/src/assets/yay.jpg differ
diff --git a/assets-with-umi-ts/src/global.css b/assets-with-umi-ts/src/global.css
new file mode 100644
index 0000000..140b316
--- /dev/null
+++ b/assets-with-umi-ts/src/global.css
@@ -0,0 +1,8 @@
+
+html, body, #root {
+  height: 100%;
+}
+
+body {
+  margin: 0;
+}
diff --git a/assets-with-umi-ts/src/layouts/__tests__/index.test.tsx b/assets-with-umi-ts/src/layouts/__tests__/index.test.tsx
new file mode 100644
index 0000000..c21be6c
--- /dev/null
+++ b/assets-with-umi-ts/src/layouts/__tests__/index.test.tsx
@@ -0,0 +1,16 @@
+import 'jest';
+import BasicLayout from '../index';
+import React from 'react';
+import renderer, { ReactTestInstance, ReactTestRenderer } from 'react-test-renderer';
+
+describe('Layout: BasicLayout', () => {
+  it('Render correctly', () => {
+    const wrapper: ReactTestRenderer = renderer.create(<BasicLayout />);
+    expect(wrapper.root.children.length).toBe(1);
+    const outerLayer = wrapper.root.children[0] as ReactTestInstance;
+    expect(outerLayer.type).toBe('div');
+    const title = outerLayer.children[0] as ReactTestInstance;
+    expect(title.type).toBe('h1');
+    expect(title.children[0]).toBe('Yay! Welcome to umi!');
+  });
+});
diff --git a/assets-with-umi-ts/src/layouts/index.css b/assets-with-umi-ts/src/layouts/index.css
new file mode 100644
index 0000000..f4307be
--- /dev/null
+++ b/assets-with-umi-ts/src/layouts/index.css
@@ -0,0 +1,15 @@
+
+.normal {
+  font-family: Georgia, sans-serif;
+  text-align: center;
+}
+
+.title {
+  font-size: 2.5rem;
+  font-weight: normal;
+  letter-spacing: -1px;
+  background: darkslateblue;
+  padding: .6em 0;
+  color: white;
+  margin: 0;
+}
diff --git a/assets-with-umi-ts/src/layouts/index.tsx b/assets-with-umi-ts/src/layouts/index.tsx
new file mode 100644
index 0000000..04223a4
--- /dev/null
+++ b/assets-with-umi-ts/src/layouts/index.tsx
@@ -0,0 +1,13 @@
+import React from 'react';
+import styles from './index.css';
+
+const BasicLayout: React.FC = props => {
+  return (
+    <div className={styles.normal}>
+      <h1 className={styles.title}>Yay! Welcome to umi!</h1>
+      {props.children}
+    </div>
+  );
+};
+
+export default BasicLayout;
diff --git a/assets-with-umi-ts/src/models/.gitkeep b/assets-with-umi-ts/src/models/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/assets-with-umi-ts/src/pages/__tests__/index.test.tsx b/assets-with-umi-ts/src/pages/__tests__/index.test.tsx
new file mode 100644
index 0000000..ec41a0c
--- /dev/null
+++ b/assets-with-umi-ts/src/pages/__tests__/index.test.tsx
@@ -0,0 +1,15 @@
+import 'jest';
+import Index from '../index';
+import React from 'react';
+import renderer, { ReactTestInstance, ReactTestRenderer } from 'react-test-renderer';
+
+describe('Page: index', () => {
+  it('Render correctly', () => {
+    const wrapper: ReactTestRenderer = renderer.create(<Index />);
+    expect(wrapper.root.children.length).toBe(1);
+    const outerLayer = wrapper.root.children[0] as ReactTestInstance;
+    expect(outerLayer.type).toBe('div');
+    expect(outerLayer.children.length).toBe(2);
+
+  });
+});
diff --git a/assets-with-umi-ts/src/pages/home/index.less b/assets-with-umi-ts/src/pages/home/index.less
new file mode 100644
index 0000000..4d78813
--- /dev/null
+++ b/assets-with-umi-ts/src/pages/home/index.less
@@ -0,0 +1,5 @@
+.container {
+  .userName{
+    width:100px;
+  }
+}
diff --git a/assets-with-umi-ts/src/pages/home/index.tsx b/assets-with-umi-ts/src/pages/home/index.tsx
new file mode 100644
index 0000000..ec3a096
--- /dev/null
+++ b/assets-with-umi-ts/src/pages/home/index.tsx
@@ -0,0 +1,13 @@
+import * as React from 'react';
+import styles from './index.less';
+export default class Index extends React.Component {
+  state = {
+    userName: 'egg-umi-ts',
+  };
+  render(): React.ReactElement<any, string | React.JSXElementConstructor<any>> | string | number | {} | React.ReactNodeArray | React.ReactPortal | boolean | null | undefined {
+    const { userName } = this.state;
+    return (
+        <span className={styles.userName}>{userName}</span>
+      );
+    }
+}
diff --git a/assets-with-umi-ts/src/pages/index.css b/assets-with-umi-ts/src/pages/index.css
new file mode 100644
index 0000000..f8e6876
--- /dev/null
+++ b/assets-with-umi-ts/src/pages/index.css
@@ -0,0 +1,23 @@
+
+.normal {
+  font-family: Georgia, sans-serif;
+  margin-top: 4em;
+  text-align: center;
+}
+
+.welcome {
+  height: 328px;
+  background: url(../assets/yay.jpg) no-repeat center 0;
+  background-size: 388px 328px;
+}
+
+.list {
+  font-size: 1.2em;
+  margin-top: 1.8em;
+  list-style: none;
+  line-height: 1.5em;
+}
+
+.list code {
+  background: #f7f7f7;
+}
diff --git a/assets-with-umi-ts/src/pages/index.tsx b/assets-with-umi-ts/src/pages/index.tsx
new file mode 100644
index 0000000..a13a716
--- /dev/null
+++ b/assets-with-umi-ts/src/pages/index.tsx
@@ -0,0 +1,18 @@
+import React from 'react';
+import styles from './index.css';
+
+export default function() {
+  return (
+    <div className={styles.normal}>
+      <div className={styles.welcome} />
+      <ul className={styles.list}>
+        <li>To get started, edit <code>src/pages/index.js</code> and save to reload.</li>
+        <li>
+          <a href="https://umijs.org/guide/getting-started.html">
+            Getting Started
+          </a>
+        </li>
+      </ul>
+    </div>
+  );
+}
diff --git a/assets-with-umi-ts/test/app/controller/home.test.ts b/assets-with-umi-ts/test/app/controller/home.test.ts
new file mode 100644
index 0000000..c551697
--- /dev/null
+++ b/assets-with-umi-ts/test/app/controller/home.test.ts
@@ -0,0 +1,10 @@
+import assert from 'assert';
+import { app } from 'egg-mock/bootstrap';
+
+describe('test/app/controller/home.test.ts', () => {
+  it('should GET /', async () => {
+    const result = await app.httpRequest().get('/').expect(200);
+    // tslint:disable-next-line:no-empty-character-class
+    assert(/<div id="root"><\/div>/u.test(result.text));
+  });
+});
diff --git a/assets-with-umi-ts/test/app/service/Test.test.ts b/assets-with-umi-ts/test/app/service/Test.test.ts
new file mode 100644
index 0000000..a8d72df
--- /dev/null
+++ b/assets-with-umi-ts/test/app/service/Test.test.ts
@@ -0,0 +1,16 @@
+import assert from 'assert';
+import { Context } from 'egg';
+import { app } from 'egg-mock/bootstrap';
+
+describe('test/app/service/Test.test.js', () => {
+  let ctx: Context;
+
+  before(async () => {
+    ctx = app.mockContext();
+  });
+
+  it('sayHi', async () => {
+    const result = await ctx.service.test.sayHi('egg');
+    assert(result === 'hi, egg');
+  });
+});
diff --git a/assets-with-umi-ts/tsconfig.json b/assets-with-umi-ts/tsconfig.json
new file mode 100644
index 0000000..75d1c2b
--- /dev/null
+++ b/assets-with-umi-ts/tsconfig.json
@@ -0,0 +1,38 @@
+{
+  "compileOnSave": true,
+  "compilerOptions": {
+    "target": "esnext",
+    "module": "commonjs",
+    "importHelpers": true,
+    "jsx": "react",
+    "esModuleInterop": true,
+    "baseUrl": ".",
+    "strict": true,
+    "paths": {
+      "@/*": ["src/*"]
+    },
+    "noImplicitAny": false,
+    "experimentalDecorators": true,
+    "emitDecoratorMetadata": true,
+    "charset": "utf8",
+    "allowJs": true,
+    "pretty": true,
+    "noEmitOnError": false,
+    "noUnusedLocals": true,
+    "noUnusedParameters": true,
+    "allowUnreachableCode": false,
+    "allowUnusedLabels": false,
+    "strictPropertyInitialization": false,
+    "noFallthroughCasesInSwitch": true,
+    "skipLibCheck": true,
+    "skipDefaultLibCheck": true,
+    "inlineSourceMap": true,
+    "allowSyntheticDefaultImports": true
+  },
+  "exclude": [
+    "app/public",
+    "app/views",
+    "node_modules*",
+    "coverage"
+  ]
+}
diff --git a/assets-with-umi-ts/tslint.json b/assets-with-umi-ts/tslint.json
new file mode 100644
index 0000000..17be9df
--- /dev/null
+++ b/assets-with-umi-ts/tslint.json
@@ -0,0 +1,8 @@
+{
+  "extends": ["tslint-config-egg"],
+  "linterOptions": {
+    "exclude": [
+      "coverage/**/*.js"
+    ]
+  }
+}
diff --git a/assets-with-umi-ts/tslint.yml b/assets-with-umi-ts/tslint.yml
new file mode 100644
index 0000000..28413b5
--- /dev/null
+++ b/assets-with-umi-ts/tslint.yml
@@ -0,0 +1,11 @@
+defaultSeverity: error
+extends:
+  - tslint-react
+  - tslint-eslint-rules
+jsRules:
+rules:
+  eofline: true
+  no-console: true
+  no-construct: true
+  no-debugger: true
+  no-reference: true
diff --git a/assets-with-umi-ts/typings.d.ts b/assets-with-umi-ts/typings.d.ts
new file mode 100644
index 0000000..22dc054
--- /dev/null
+++ b/assets-with-umi-ts/typings.d.ts
@@ -0,0 +1,3 @@
+declare module '*.css';
+declare module '*.png';
+declare module '*.less';
diff --git a/assets-with-umi-ts/typings/app/controller/index.d.ts b/assets-with-umi-ts/typings/app/controller/index.d.ts
new file mode 100644
index 0000000..9b37aba
--- /dev/null
+++ b/assets-with-umi-ts/typings/app/controller/index.d.ts
@@ -0,0 +1,11 @@
+// This file is created by egg-ts-helper@1.25.3
+// Do not modify this file!!!!!!!!!
+
+import 'egg';
+import ExportHome from '../../../app/controller/home';
+
+declare module 'egg' {
+  interface IController {
+    home: ExportHome;
+  }
+}
diff --git a/assets-with-umi-ts/typings/app/index.d.ts b/assets-with-umi-ts/typings/app/index.d.ts
new file mode 100644
index 0000000..6aadf25
--- /dev/null
+++ b/assets-with-umi-ts/typings/app/index.d.ts
@@ -0,0 +1,6 @@
+// This file is created by egg-ts-helper@1.25.3
+// Do not modify this file!!!!!!!!!
+
+import 'egg';
+export * from 'egg';
+export as namespace Egg;
diff --git a/assets-with-umi-ts/typings/app/service/index.d.ts b/assets-with-umi-ts/typings/app/service/index.d.ts
new file mode 100644
index 0000000..e7782a5
--- /dev/null
+++ b/assets-with-umi-ts/typings/app/service/index.d.ts
@@ -0,0 +1,11 @@
+// This file is created by egg-ts-helper@1.25.3
+// Do not modify this file!!!!!!!!!
+
+import 'egg';
+import ExportTest from '../../../app/service/Test';
+
+declare module 'egg' {
+  interface IService {
+    test: ExportTest;
+  }
+}
diff --git a/assets-with-umi-ts/typings/config/index.d.ts b/assets-with-umi-ts/typings/config/index.d.ts
new file mode 100644
index 0000000..54aa5ee
--- /dev/null
+++ b/assets-with-umi-ts/typings/config/index.d.ts
@@ -0,0 +1,11 @@
+// This file is created by egg-ts-helper@1.25.3
+// Do not modify this file!!!!!!!!!
+
+import 'egg';
+import { EggAppConfig } from 'egg';
+import ExportConfigDefault from '../../config/config.default';
+type ConfigDefault = ReturnType<typeof ExportConfigDefault>;
+declare module 'egg' {
+  type NewEggAppConfig = ConfigDefault;
+  interface EggAppConfig extends NewEggAppConfig { }
+}
\ No newline at end of file
diff --git a/assets-with-umi-ts/typings/config/plugin.d.ts b/assets-with-umi-ts/typings/config/plugin.d.ts
new file mode 100644
index 0000000..2b783e6
--- /dev/null
+++ b/assets-with-umi-ts/typings/config/plugin.d.ts
@@ -0,0 +1,37 @@
+// This file is created by egg-ts-helper@1.25.3
+// Do not modify this file!!!!!!!!!
+
+import 'egg';
+import 'egg-onerror';
+import 'egg-session';
+import 'egg-i18n';
+import 'egg-watcher';
+import 'egg-multipart';
+import 'egg-security';
+import 'egg-development';
+import 'egg-logrotator';
+import 'egg-schedule';
+import 'egg-static';
+import 'egg-jsonp';
+import 'egg-view';
+import 'egg-view-nunjucks';
+import 'egg-view-assets';
+import { EggPluginItem } from 'egg';
+declare module 'egg' {
+  interface EggPlugin {
+    onerror?: EggPluginItem;
+    session?: EggPluginItem;
+    i18n?: EggPluginItem;
+    watcher?: EggPluginItem;
+    multipart?: EggPluginItem;
+    security?: EggPluginItem;
+    development?: EggPluginItem;
+    logrotator?: EggPluginItem;
+    schedule?: EggPluginItem;
+    static?: EggPluginItem;
+    jsonp?: EggPluginItem;
+    view?: EggPluginItem;
+    nunjucks?: EggPluginItem;
+    assets?: EggPluginItem;
+  }
+}
\ No newline at end of file
diff --git a/assets-with-umi-ts/typings/index.d.ts b/assets-with-umi-ts/typings/index.d.ts
new file mode 100644
index 0000000..e696bfe
--- /dev/null
+++ b/assets-with-umi-ts/typings/index.d.ts
@@ -0,0 +1,5 @@
+import 'egg';
+
+declare module 'egg' {
+
+}
diff --git a/custom-env/README.md b/custom-env/README.md
index 0795671..8d8a9f3 100644
--- a/custom-env/README.md
+++ b/custom-env/README.md
@@ -1,6 +1,6 @@
 # custom environment
 
-Egg will load different config file in different env, in this example we create `config.default.js`, `config.sit.js` and `config.prod.js`.
+Egg will load different config file in different env, in this example we create `config.default.js`, `config.sit.js` and `config.prod.ts`.
 
 Egg will load `config.sit.js` when lanched by `EGG_SERVER_ENV=sit npm run dev`. You can get see the response
 
diff --git a/passport/.gitignore b/passport/.gitignore
index ac022f4..bfdc548 100644
--- a/passport/.gitignore
+++ b/passport/.gitignore
@@ -1 +1 @@
-config/config.local.js
+config/config.local.ts