diff --git a/.babelrc b/.babelrc
new file mode 100644
index 0000000..a52de11
--- /dev/null
+++ b/.babelrc
@@ -0,0 +1,8 @@
+{
+ "presets": ["es2015-node"],
+ "plugins": [
+ "transform-async-to-generator",
+ "syntax-async-functions",
+ "add-module-exports"
+ ]
+}
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index e920c16..20a8ec8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -31,3 +31,4 @@ node_modules
# Optional REPL history
.node_repl_history
+typings
diff --git a/README.md b/README.md
index b52e971..b98bd8e 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,62 @@
-# koa2-async-example
\ No newline at end of file
+# koa2-example
+
+## 准备
+
+```
+npm i -g coden
+npm i -g typings
+```
+
+## 初始化
+
+```
+git clone https://github.com/17koa/koa2-example.git
+cd koa2-example
+npm i
+typings install
+npm start
+```
+
+## 实例
+
+1. 最简单的koa2.js
+1. koa2-example
+
+## Koa2-example说明
+
+```
+ "koa": "^2.0.0",
+ "koa-bodyparser": "^2.0.1",
+ "koa-convert": "^1.2.0",
+ "koa-json": "^1.1.1",
+ "koa-logger": "^1.3.0",
+ "koa-onerror": "^1.2.1",
+ "koa-router": "^7.0.0",
+ "koa-static": "^1.5.2",
+ "koa-views": "^5.0.1"
+```
+
+为了支持koa2,下面组件要注意和1.x不一样
+
+```
+ "koa": "^2.0.0",
+ "koa-router": "^7.0.0",
+ "koa-views": "^5.0.1"
+```
+
+## 语法提示
+
+```
+typings install node koa --ambient --save
+```
+
+强制提示
+
+```
+///
+///
+```
+
+## 调试
+
+http://i5ting.github.io/vsc/#107
diff --git a/app.js b/app.js
new file mode 100644
index 0000000..eae473e
--- /dev/null
+++ b/app.js
@@ -0,0 +1,46 @@
+
+const Koa = require('koa');
+const app = new Koa();
+const router = require('koa-router')();
+const views = require('koa-views');
+const co = require('co');
+const convert = require('koa-convert');
+const json = require('koa-json');
+const onerror = require('koa-onerror');
+const bodyparser = require('koa-bodyparser')();
+const logger = require('koa-logger');
+
+const index = require('./routes/index');
+const users = require('./routes/users');
+
+// middlewares
+app.use(convert(bodyparser));
+app.use(convert(json()));
+app.use(convert(logger()));
+app.use(convert(require('koa-static')(__dirname + '/public')));
+
+app.use(views(__dirname + '/views', {
+ extension: 'jade'
+}));
+
+// logger
+app.use((ctx, next) => {
+ const start = new Date();
+ return next().then(() => {
+ const ms = new Date() - start;
+ console.log(`${ctx.method} ${ctx.url} - ${ms}ms`);
+ });
+});
+
+router.use('/', index.routes());
+router.use('/users', users.routes());
+
+app.use(router.routes(), router.allowedMethods());
+// response
+
+app.on('error', function(err, ctx){
+ console.log(err)
+ logger.error('server error', err, ctx);
+});
+
+module.exports = app
diff --git a/bin/www b/bin/www
new file mode 100755
index 0000000..31c60e9
--- /dev/null
+++ b/bin/www
@@ -0,0 +1,93 @@
+#!/usr/bin/env node
+
+/**
+ * Module dependencies.
+ */
+
+require("babel-register");
+var app = require('../app');
+console.dir(app)
+
+var debug = require('debug')('demo:server');
+var http = require('http');
+
+/**
+ * Get port from environment and store in Express.
+ */
+
+var port = normalizePort(process.env.PORT || '3000');
+// app.set('port', port);
+
+/**
+ * Create HTTP server.
+ */
+
+var server = http.createServer(app.callback());
+
+/**
+ * Listen on provided port, on all network interfaces.
+ */
+
+server.listen(port);
+server.on('error', onError);
+server.on('listening', onListening);
+
+/**
+ * Normalize a port into a number, string, or false.
+ */
+
+function normalizePort(val) {
+ var port = parseInt(val, 10);
+
+ if (isNaN(port)) {
+ // named pipe
+ return val;
+ }
+
+ if (port >= 0) {
+ // port number
+ return port;
+ }
+
+ return false;
+}
+
+/**
+ * Event listener for HTTP server "error" event.
+ */
+
+function onError(error) {
+ if (error.syscall !== 'listen') {
+ throw error;
+ }
+
+ var bind = typeof port === 'string'
+ ? 'Pipe ' + port
+ : 'Port ' + port;
+
+ // handle specific listen errors with friendly messages
+ switch (error.code) {
+ case 'EACCES':
+ console.error(bind + ' requires elevated privileges');
+ process.exit(1);
+ break;
+ case 'EADDRINUSE':
+ console.error(bind + ' is already in use');
+ process.exit(1);
+ break;
+ default:
+ throw error;
+ }
+}
+
+/**
+ * Event listener for HTTP server "listening" event.
+ */
+
+function onListening() {
+ var addr = server.address();
+ var bind = typeof addr === 'string'
+ ? 'pipe ' + addr
+ : 'port ' + addr.port;
+ debug('Listening on ' + bind);
+}
diff --git a/koa2.js b/koa2.js
new file mode 100644
index 0000000..6eda168
--- /dev/null
+++ b/koa2.js
@@ -0,0 +1,8 @@
+const Koa = require('koa');
+const app = new Koa();
+
+app.use(ctx => {
+ return ctx.body = "hello Koa"
+});
+
+app.listen(3001);
\ No newline at end of file
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..e3add2e
--- /dev/null
+++ b/package.json
@@ -0,0 +1,33 @@
+{
+ "name": "koa2-example",
+ "version": "0.1.0",
+ "private": true,
+ "scripts": {
+ "start": "./node_modules/.bin/nodemon bin/www",
+ "pm2": "pm2 start bin/www",
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "dependencies": {
+ "co": "^4.6.0",
+ "debug": "^2.2.0",
+ "jade": "~1.11.0",
+ "koa": "^2.0.0",
+ "koa-bodyparser": "^2.0.1",
+ "koa-convert": "^1.2.0",
+ "koa-json": "^1.1.1",
+ "koa-logger": "^1.3.0",
+ "koa-onerror": "^1.2.1",
+ "koa-router": "^7.0.0",
+ "koa-static": "^1.5.2",
+ "koa-views": "^5.0.1"
+ },
+ "devDependencies": {
+ "babel-core": "^6.7.5",
+ "babel-plugin-add-module-exports": "^0.1.2",
+ "babel-polyfill": "^6.1.4",
+ "babel-preset-es2015": "^6.6.0",
+ "babel-preset-es2015-node": "^6.0.1",
+ "babel-preset-stage-3": "^6.5.0",
+ "nodemon": "^1.8.1"
+ }
+}
diff --git a/public/stylesheets/style.css b/public/stylesheets/style.css
new file mode 100644
index 0000000..9453385
--- /dev/null
+++ b/public/stylesheets/style.css
@@ -0,0 +1,8 @@
+body {
+ padding: 50px;
+ font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;
+}
+
+a {
+ color: #00B7FF;
+}
diff --git a/routes/index.js b/routes/index.js
new file mode 100644
index 0000000..2b1d04c
--- /dev/null
+++ b/routes/index.js
@@ -0,0 +1,9 @@
+var router = require('koa-router')();
+
+router.get('/', async (ctx, next) => {
+
+ await ctx.render('index', {
+ title:'Hello Koa'
+ })
+})
+module.exports = router;
diff --git a/routes/users.js b/routes/users.js
new file mode 100644
index 0000000..62cdd13
--- /dev/null
+++ b/routes/users.js
@@ -0,0 +1,7 @@
+var router = require('koa-router')();
+
+router.get('/', function (ctx, next) {
+ ctx.body = 'this a users response!';
+});
+
+module.exports = router;
diff --git a/typings.json b/typings.json
new file mode 100644
index 0000000..65f3fd5
--- /dev/null
+++ b/typings.json
@@ -0,0 +1,6 @@
+{
+ "ambientDependencies": {
+ "koa": "registry:dt/koa#2.0.0+20160317120654",
+ "node": "registry:dt/node#4.0.0+20160423143914"
+ }
+}
diff --git a/views/error.jade b/views/error.jade
new file mode 100644
index 0000000..51ec12c
--- /dev/null
+++ b/views/error.jade
@@ -0,0 +1,6 @@
+extends layout
+
+block content
+ h1= message
+ h2= error.status
+ pre #{error.stack}
diff --git a/views/index.jade b/views/index.jade
new file mode 100644
index 0000000..3d63b9a
--- /dev/null
+++ b/views/index.jade
@@ -0,0 +1,5 @@
+extends layout
+
+block content
+ h1= title
+ p Welcome to #{title}
diff --git a/views/layout.jade b/views/layout.jade
new file mode 100644
index 0000000..15af079
--- /dev/null
+++ b/views/layout.jade
@@ -0,0 +1,7 @@
+doctype html
+html
+ head
+ title= title
+ link(rel='stylesheet', href='/stylesheets/style.css')
+ body
+ block content