diff --git a/components/docs-src/src/docs/en/o-icon.md b/components/docs-src/src/docs/en/o-icon.md
new file mode 100644
index 000000000..03c4490fe
--- /dev/null
+++ b/components/docs-src/src/docs/en/o-icon.md
@@ -0,0 +1,51 @@
+## OIcon
+
+SVG Icon
+
+
+
+## Import
+
+```js
+import '@omiu/o-icon'
+```
+
+Or use script tag to ref it.
+
+
+```html
+
+```
+
+## Usage
+
+```html
+
+```
+
+## API
+
+### Props
+
+```tsx
+{
+ path?: string,
+ paths?: object,
+ view?: number,
+ scale?: number,
+ color?: string,
+ rotate?: boolean
+}
+```
+
+### 默认属性
+
+```tsx
+{
+ view: 1024,
+ scale: 2
+)
+```
diff --git a/components/docs-src/src/docs/zh-cn/o-icon.md b/components/docs-src/src/docs/zh-cn/o-icon.md
new file mode 100644
index 000000000..00831c368
--- /dev/null
+++ b/components/docs-src/src/docs/zh-cn/o-icon.md
@@ -0,0 +1,51 @@
+## OIcon 矢量图标
+
+SVG 矢量图标
+
+
+
+## 导入
+
+```js
+import '@omiu/o-icon'
+```
+
+或者直接 script 标签引入。
+
+
+```html
+
+```
+
+## 使用
+
+```html
+
+```
+
+
+## API
+
+### 属性
+
+```tsx
+{
+ path?: string,
+ paths?: object,
+ view?: number,
+ scale?: number,
+ color?: string,
+ rotate?: boolean
+}
+```
+
+### 默认属性
+```tsx
+{
+ view: 1024,
+ scale: 2
+)
+```
diff --git a/components/o-icon/README.md b/components/o-icon/README.md
new file mode 100644
index 000000000..4471e408d
--- /dev/null
+++ b/components/o-icon/README.md
@@ -0,0 +1,48 @@
+## OIcon
+
+SVG Icon
+
+* [→ CodePen](https://codepen.io/omijs/pen/QWjgapY)
+
+## Import
+
+```js
+import '@omiu/o-icon'
+```
+
+Or use script tag to ref it.
+
+
+```html
+
+```
+
+## Usage
+
+```html
+
+```
+
+## API
+
+### Props
+
+```tsx
+{
+ path?: string,
+ paths?: object,
+ view?: number,
+ scale?: number,
+ color?: string,
+ rotate?: boolean
+}
+```
+
+### 默认属性
+
+```tsx
+{
+ view: 1024,
+ scale: 2
+)
+```
diff --git a/components/o-icon/demos/js-demo/index.html b/components/o-icon/demos/js-demo/index.html
new file mode 100644
index 000000000..2af607f69
--- /dev/null
+++ b/components/o-icon/demos/js-demo/index.html
@@ -0,0 +1,84 @@
+
+
+
+
+
+
+ Omiu ActionSheet
+
+
+
+
+
+
+
+
+
+
+
+
+ Scale=2
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Scale=3
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/components/o-icon/package.json b/components/o-icon/package.json
new file mode 100644
index 000000000..ff9395243
--- /dev/null
+++ b/components/o-icon/package.json
@@ -0,0 +1,101 @@
+{
+ "name": "@omiu/o-icon",
+ "version": "0.0.1",
+ "description": "SVG Icon",
+ "docsExtend": {
+ "cnName": "矢量图标",
+ "cnDescription": "SVG 矢量图标",
+ "codepen": "QWjgapY",
+ "codepenHeight": 351,
+ "codepenDefaultTab": "html,result"
+ },
+ "main": "src/index.js",
+ "module": "src/index.esm.js",
+ "types": "src/index.d.ts",
+ "scripts": {
+ "docs": "node ./scripts/docs-gen.js",
+ "start": "node ./scripts/webpack.build.js -- demo",
+ "build": "node ./scripts/webpack.build.js -- build && rollup -c scripts/rollup.config.js && node ./scripts/rollup.end.js"
+ },
+ "typings": "./dist/index.d.ts",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/Tencent/omi.git"
+ },
+ "files": [
+ "src",
+ "dist",
+ "typings.json"
+ ],
+ "keywords": [
+ "omiu",
+ "omi",
+ "omio",
+ "preact",
+ "react",
+ "virtual dom",
+ "vdom",
+ "components",
+ "virtual",
+ "dom"
+ ],
+ "author": "dntzhang ",
+ "license": "MIT",
+ "bugs": {
+ "url": "https://github.com/Tencent/omi/issues"
+ },
+ "homepage": "http://omijs.org",
+ "devDependencies": {
+ "@rollup/plugin-commonjs": "^11.1.0",
+ "css": "^2.2.4",
+ "css-loader": "^1.0.1",
+ "file": "^0.2.2",
+ "file-loader": "^2.0.0",
+ "html-webpack-plugin": "^3.2.0",
+ "less": "^3.9.0",
+ "less-loader": "^4.1.0",
+ "mini-css-extract-plugin": "^0.4.5",
+ "node-sass": "^4.12.0",
+ "omi": "latest",
+ "omio": "latest",
+ "optimize-css-assets-webpack-plugin": "^5.0.1",
+ "progress-bar-webpack-plugin": "^2.1.0",
+ "resolve-url-loader": "^3.1.0",
+ "rollup": "^2.7.1",
+ "rollup-plugin-license": "^2.0.0",
+ "rollup-plugin-node-resolve": "^5.2.0",
+ "rollup-plugin-scss": "^2.4.0",
+ "rollup-plugin-typescript": "^1.0.1",
+ "sass-loader": "^7.1.0",
+ "style-loader": "^0.23.1",
+ "to-string-loader": "^1.1.5",
+ "ts-loader": "^5.4.4",
+ "typescript": "^3.2.1",
+ "url": "^0.11.0",
+ "url-loader": "^1.1.2",
+ "webpack": "^4.42.1",
+ "webpack-cli": "^3.3.1",
+ "webpack-dev-server": "^3.1.10",
+ "webpack-merge": "^4.1.4"
+ },
+ "greenkeeper": {
+ "ignore": [
+ "babel-cli",
+ "babel-core",
+ "babel-eslint",
+ "babel-loader",
+ "jscodeshift",
+ "rollup-plugin-babel"
+ ]
+ },
+ "prettier": {
+ "singleQuote": true,
+ "semi": false,
+ "tabWidth": 2,
+ "useTabs": false
+ },
+ "dependencies": {
+ "@omiu/common": "latest",
+ "omi": "latest"
+ }
+}
diff --git a/components/o-icon/scripts/docs-gen.js b/components/o-icon/scripts/docs-gen.js
new file mode 100644
index 000000000..b3b4af1c7
--- /dev/null
+++ b/components/o-icon/scripts/docs-gen.js
@@ -0,0 +1,134 @@
+//自动扫描 index.tsx 生成 readme
+const fs = require('fs')
+
+const content = fs.readFileSync('./src/index.tsx', 'utf-8')
+
+const props = content.match(new RegExp('interface Props \\{[\\s\\S]*?}'))[0].replace('interface Props ', '')
+
+const defaultPropsContext = content.match(new RegExp('static defaultProps = \\{[\\s\\S]*?}'))
+let defaultProps
+
+if (defaultPropsContext) {
+
+ defaultProps = defaultPropsContext[0].replace('static defaultProps = ', '').replace(/ /g, ' ').replace(/ }/g, ')')
+}
+
+
+const eventContexts = content.match(new RegExp('this.fire\\([\\s\\S]*?[,|)]', 'g'))
+const package = require('../package.json')
+const packageName = package.name
+const name = packageName.split('/')[1]
+
+const upperCaseName = name.split('-').map(item => {
+ return item.charAt(0).toUpperCase() + item.slice(1)
+}).join('')
+const tagName = 'o-' + name
+
+//fire 附近打标标记 event.detail 类型?
+let events, eventMap
+if (eventContexts) {
+
+ events = eventContexts.map(event => {
+ return event.replace('this.fire(\'', '').replace('\',', '').replace('\')', '')
+ })
+ eventMap = {}
+ events.forEach(event => {
+ eventMap[event] = 1
+ })
+}
+
+const cnContent = `## ${upperCaseName} ${package.docsExtend.cnName}
+
+${package.docsExtend.cnDescription}
+
+
+
+## 导入
+
+\`\`\`js
+import '${packageName}'
+\`\`\`
+
+或者直接 script 标签引入。
+
+
+\`\`\`html
+
+\`\`\`
+
+## 使用
+
+\`\`\`html
+<${tagName}> ${tagName}>
+\`\`\`
+
+
+## API
+
+### 属性
+
+\`\`\`tsx
+${props}
+\`\`\`
+
+${defaultProps ? '### 默认属性\n' : ''}${defaultProps ? '\`\`\`tsx\n' : ''}${defaultProps ? defaultProps : ''}
+${defaultProps ? '\`\`\`\n' : ''}${eventMap ? '### 事件\n' : ''}${eventMap ? Object.keys(eventMap).map(event => {
+ return `* ${event}\n`
+}).join('') : ''}`
+
+fs.writeFileSync(`../docs-src/src/docs/zh-cn/${name}.md`, cnContent)
+
+
+
+const enContent = `## ${upperCaseName}
+
+${package.description}
+
+
+
+## Import
+
+\`\`\`js
+import '${packageName}'
+\`\`\`
+
+Or use script tag to ref it.
+
+
+\`\`\`html
+
+\`\`\`
+
+## Usage
+
+\`\`\`html
+<${tagName}>${tagName}>
+\`\`\`
+
+## API
+
+### Props
+
+\`\`\`tsx
+${props}
+\`\`\`
+
+${defaultProps ? '### 默认属性\n\n' : ''}${defaultProps ? '\`\`\`tsx\n' : ''}${defaultProps ? defaultProps : ''}
+${defaultProps ? '\`\`\`\n' : ''}${eventMap ? '### Events\n\n' : ''}${eventMap ? Object.keys(eventMap).map(event => {
+ return `* ${event}\n`
+}).join('') : ''}`
+
+
+fs.writeFileSync(`../docs-src/src/docs/en/${name}.md`, enContent)
+
+
+fs.writeFileSync(`../${name}/README.md`, enContent.replace(/