diff --git a/docs/guide/plugin-develop.md b/docs/guide/plugin-develop.md
new file mode 100644
index 000000000000..f043ee2372f5
--- /dev/null
+++ b/docs/guide/plugin-develop.md
@@ -0,0 +1,229 @@
+---
+translateHelp: true
+---
+
+# 插件开发
+
+在 Umi 中,插件实际上就是一个 JS 模块,你需要定义一个插件的初始化方法并默认导出。如下示例:
+
+```js
+export default (api) => {
+ // your plugin code here
+};
+```
+
+需要注意的是,如果你的插件需要发布为 npm 包,那么你需要发布之前做编译,确保发布的代码里面是 ES5 的代码。
+
+该初始化方法会收到 `api` 参数,Umi 提供给插件的接口都是通过它暴露出来的。
+
+## 插件示例
+
+以下我们通过完成一个简单的需求,来进一步了解 Umi 的插件开发
+
+### 需求
+
+Umi 约定式路由中的表现是主路由,对应到 `index` 路由,即访问 `http://localhost:8000` 实际上访问到的页面是 `src/pages/index`,有时候我们在开发过程中会遇到,希望修改主路由的情况,比如希望路由 `/` 访问的是 `src/pages/home`。
+
+### 初始化插件
+
+你可以通过 [create-umi](https://github.com/umijs/create-umi) 直接创建一个 Umi 插件的脚手架:
+
+```shell
+yarn create umi --plugin
+? Select the boilerplate type plugin
+? What's the plugin name? umi-plugin-main-path
+? What's your plugin used for? config umi main path
+? What's your email? 448627663@qq.com
+? What's your name? xiaohuoni
+? Which organization is your plugin stored under github? alitajs
+? Select the development language TypeScript
+? Does your plugin have ui interaction(umi ui)? No
+ create package.json
+ create .editorconfig
+ create .fatherrc.ts
+ create .gitignore
+ create .prettierignore
+ create .prettierrc
+ create CONTRIBUTING.md
+ create example/.gitignore
+ create example/.umirc.ts
+ create example/app.jsx
+ create example/app.tsx
+ create example/package.json
+ create example/pages/index.css
+ create example/pages/index.jsx
+ create example/pages/index.tsx
+ create example/tsconfig.json
+ create example/typing.d.ts
+ create README.md
+ create src/index.ts
+ create test/fixtures/normal/pages/index.css
+ create tsconfig.json
+✨ File Generate Done
+```
+
+### 安装 node 模块
+
+```shell
+$ yarn
+```
+
+> 你也可以使用 npm install ,因为有编写测试,所以安装了 puppetee,如果你安装失败,可能需要科学上网,或者使用淘宝源。
+
+### Umi@3 插件命名特性
+
+在 Umi@3 中,当插件使用 `@umijs` 或者 `umi-plugin` 开头,只要安装就会被默认使用,所以如果你的插件名以上述规则命名,你就不需要在 config 文件中显式使用你的插件,如果你的插件命名不满足上述规则,那你只需要在 config 中显示使用即可。
+
+```ts
+import { defineConfig } from 'umi';
+
+export default defineConfig({
+ plugins: ['you-plugin-name'],
+});
+```
+
+> 此次示例中我们的插件名是 umi-plugin-main-path 。
+
+### 实战演练
+
+首先我们先看一下,初始化脚手架中的代码,如果使用这个插件,那么就会打印日志 `use plugin`,然后使用 `modifyHTML` api 在 `body` 上添加了 `h1` 的内容。更多插件 api ,请查阅[Plugins Api](/plugins/api)。
+
+```ts
+export default function (api: IApi) {
+ api.logger.info('use plugin');
+
+ api.modifyHTML(($) => {
+ $('body').prepend(`
hello umi plugin
`);
+ return $;
+ });
+
+}
+```
+
+为我们的插件增加一个配,使用 [describe](/plugins/api#describe-id-string-key-string-config--default-schema-onchange--) 注册配置。
+
+```ts
+ api.describe({
+ key: 'mainPath',
+ config: {
+ schema(joi) {
+ return joi.string();
+ },
+ },
+ });
+```
+
+增加我们插件的主逻辑
+
+```ts
+ if (api.userConfig.mainPath) {
+ api.modifyRoutes((routes: any[]) => {
+ return resetMainPath(routes, api.config.mainPath);
+ });
+ }
+```
+
+> 这里需要注意的是,我们在判断是取的是 api.userConfig,而在 api 的回调中使用的是 api.config,你可以理解为 api.userConfig 是配置中的值, api.config 是插件修改后的值,这里可以是任意插件修改。
+
+在演示中使用我们的插件:
+
+在 `example/.umirc.ts` 中增加配置
+
+```ts
+import { defineConfig } from 'umi';
+
+export default defineConfig({
+ plugins: [require.resolve('../lib')],
+ mainPath:'/home'
+});
+```
+
+新建 page 页面,新建 `example/pages/home.tsx`
+
+```tsx
+import React from 'react';
+import styles from './index.css';
+
+export default () => (
+
+
Home Page!
+
+);
+```
+
+查看效果
+
+```shell
+yarn start
+Starting the development server...
+
+✔ Webpack
+ Compiled successfully in 20.73s
+
+ App running at:
+ - Local: http://localhost:8000 (copied to clipboard)
+ - Network: http://192.168.50.236:8000
+```
+
+浏览器访问 `http://localhost:8000` 就可以访问到 `home` ,要访问之前的 `index` 页面,要通过 `http://localhost:8000/index`。
+
+### 为插件编写测试
+
+一般 Umi 插件的测试,我们都是采用结果测试的方案,只看最终运行效果。这里我们使用的是 [`test-umi-plugin`](https://github.com/umijs/test-umi-plugin),它也有一定的约定,指定 `fixtures` 之后,他会自动执行文件夹下的 test 文件。
+
+在 `test/fixtures/normal/.umirc.ts` 中增加配置
+
+```ts
+export default {
+ plugins: [require.resolve('../../../lib')],
+ mainPath: '/home'
+}
+```
+
+新建 page 页面,新建 `test/fixtures/normal/pages/home.tsx`
+
+```tsx
+import React from 'react';
+import styles from './index.css';
+
+export default () => (
+
+
Home Page!
+
+);
+```
+
+修改测试用例 `test/fixtures/normal/test.ts`
+
+```diff
+export default async function ({ page, host }) {
+ await page.goto(`${host}/`, {
+ waitUntil: 'networkidle2',
+ });
+ const text = await page.evaluate(
+ () => document.querySelector('h1').innerHTML,
+ );
+ expect(text).toEqual('Home Page');
+};
+```
+
+执行测试
+
+```
+$ yarn test
+$ umi-test
+ console.log
+ [normal] Running at http://localhost:12401
+
+ PASS test/index.e2e.ts (10.219s)
+ ✓ normal (1762ms)
+
+Test Suites: 1 passed, 1 total
+Tests: 1 passed, 1 total
+Snapshots: 0 total
+Time: 11.057s
+Ran all test suites.
+✨ Done in 14.01s.
+```
+
+本次示例的完整代码在 [umi-plugin-main-path](https://github.com/alitajs/umi-plugin-main-path)。
diff --git a/docs/guide/plugin-develop.zh-CN.md b/docs/guide/plugin-develop.zh-CN.md
new file mode 100644
index 000000000000..b7ca04fbd15d
--- /dev/null
+++ b/docs/guide/plugin-develop.zh-CN.md
@@ -0,0 +1,225 @@
+# 插件开发
+
+在 Umi 中,插件实际上就是一个 JS 模块,你需要定义一个插件的初始化方法并默认导出。如下示例:
+
+```js
+export default (api) => {
+ // your plugin code here
+};
+```
+
+需要注意的是,如果你的插件需要发布为 npm 包,那么你需要发布之前做编译,确保发布的代码里面是 ES5 的代码。
+
+该初始化方法会收到 `api` 参数,Umi 提供给插件的接口都是通过它暴露出来的。
+
+## 插件示例
+
+以下我们通过完成一个简单的需求,来进一步了解 Umi 的插件开发
+
+### 需求
+
+Umi 约定式路由中的表现是主路由,对应到 `index` 路由,即访问 `http://localhost:8000` 实际上访问到的页面是 `src/pages/index`,有时候我们在开发过程中会遇到,希望修改主路由的情况,比如希望路由 `/` 访问的是 `src/pages/home`。
+
+### 初始化插件
+
+你可以通过 [create-umi](https://github.com/umijs/create-umi) 直接创建一个 Umi 插件的脚手架:
+
+```shell
+yarn create umi --plugin
+? Select the boilerplate type plugin
+? What's the plugin name? umi-plugin-main-path
+? What's your plugin used for? config umi main path
+? What's your email? 448627663@qq.com
+? What's your name? xiaohuoni
+? Which organization is your plugin stored under github? alitajs
+? Select the development language TypeScript
+? Does your plugin have ui interaction(umi ui)? No
+ create package.json
+ create .editorconfig
+ create .fatherrc.ts
+ create .gitignore
+ create .prettierignore
+ create .prettierrc
+ create CONTRIBUTING.md
+ create example/.gitignore
+ create example/.umirc.ts
+ create example/app.jsx
+ create example/app.tsx
+ create example/package.json
+ create example/pages/index.css
+ create example/pages/index.jsx
+ create example/pages/index.tsx
+ create example/tsconfig.json
+ create example/typing.d.ts
+ create README.md
+ create src/index.ts
+ create test/fixtures/normal/pages/index.css
+ create tsconfig.json
+✨ File Generate Done
+```
+
+### 安装 node 模块
+
+```shell
+$ yarn
+```
+
+> 你也可以使用 npm install ,因为有编写测试,所以安装了 puppetee,如果你安装失败,可能需要科学上网,或者使用淘宝源。
+
+### Umi@3 插件命名特性
+
+在 Umi@3 中,当插件使用 `@umijs` 或者 `umi-plugin` 开头,只要安装就会被默认使用,所以如果你的插件名以上述规则命名,你就不需要在 config 文件中显式使用你的插件,如果你的插件命名不满足上述规则,那你只需要在 config 中显示使用即可。
+
+```ts
+import { defineConfig } from 'umi';
+
+export default defineConfig({
+ plugins: ['you-plugin-name'],
+});
+```
+
+> 此次示例中我们的插件名是 umi-plugin-main-path 。
+
+### 实战演练
+
+首先我们先看一下,初始化脚手架中的代码,如果使用这个插件,那么就会打印日志 `use plugin`,然后使用 `modifyHTML` api 在 `body` 上添加了 `h1` 的内容。更多插件 api ,请查阅[Plugins Api](/plugins/api)。
+
+```ts
+export default function (api: IApi) {
+ api.logger.info('use plugin');
+
+ api.modifyHTML(($) => {
+ $('body').prepend(`hello umi plugin
`);
+ return $;
+ });
+
+}
+```
+
+为我们的插件增加一个配,使用 [describe](/plugins/api#describe-id-string-key-string-config--default-schema-onchange--) 注册配置。
+
+```ts
+ api.describe({
+ key: 'mainPath',
+ config: {
+ schema(joi) {
+ return joi.string();
+ },
+ },
+ });
+```
+
+增加我们插件的主逻辑
+
+```ts
+ if (api.userConfig.mainPath) {
+ api.modifyRoutes((routes: any[]) => {
+ return resetMainPath(routes, api.config.mainPath);
+ });
+ }
+```
+
+> 这里需要注意的是,我们在判断是取的是 api.userConfig,而在 api 的回调中使用的是 api.config,你可以理解为 api.userConfig 是配置中的值, api.config 是插件修改后的值,这里可以是任意插件修改。
+
+在演示中使用我们的插件:
+
+在 `example/.umirc.ts` 中增加配置
+
+```ts
+import { defineConfig } from 'umi';
+
+export default defineConfig({
+ plugins: [require.resolve('../lib')],
+ mainPath:'/home'
+});
+```
+
+新建 page 页面,新建 `example/pages/home.tsx`
+
+```tsx
+import React from 'react';
+import styles from './index.css';
+
+export default () => (
+
+
Home Page!
+
+);
+```
+
+查看效果
+
+```shell
+yarn start
+Starting the development server...
+
+✔ Webpack
+ Compiled successfully in 20.73s
+
+ App running at:
+ - Local: http://localhost:8000 (copied to clipboard)
+ - Network: http://192.168.50.236:8000
+```
+
+浏览器访问 `http://localhost:8000` 就可以访问到 `home` ,要访问之前的 `index` 页面,要通过 `http://localhost:8000/index`。
+
+### 为插件编写测试
+
+一般 Umi 插件的测试,我们都是采用结果测试的方案,只看最终运行效果。这里我们使用的是 [`test-umi-plugin`](https://github.com/umijs/test-umi-plugin),它也有一定的约定,指定 `fixtures` 之后,他会自动执行文件夹下的 test 文件。
+
+在 `test/fixtures/normal/.umirc.ts` 中增加配置
+
+```ts
+export default {
+ plugins: [require.resolve('../../../lib')],
+ mainPath: '/home'
+}
+```
+
+新建 page 页面,新建 `test/fixtures/normal/pages/home.tsx`
+
+```tsx
+import React from 'react';
+import styles from './index.css';
+
+export default () => (
+
+
Home Page!
+
+);
+```
+
+修改测试用例 `test/fixtures/normal/test.ts`
+
+```diff
+export default async function ({ page, host }) {
+ await page.goto(`${host}/`, {
+ waitUntil: 'networkidle2',
+ });
+ const text = await page.evaluate(
+ () => document.querySelector('h1').innerHTML,
+ );
+ expect(text).toEqual('Home Page');
+};
+```
+
+执行测试
+
+```
+$ yarn test
+$ umi-test
+ console.log
+ [normal] Running at http://localhost:12401
+
+ PASS test/index.e2e.ts (10.219s)
+ ✓ normal (1762ms)
+
+Test Suites: 1 passed, 1 total
+Tests: 1 passed, 1 total
+Snapshots: 0 total
+Time: 11.057s
+Ran all test suites.
+✨ Done in 14.01s.
+```
+
+本次示例的完整代码在 [umi-plugin-main-path](https://github.com/alitajs/umi-plugin-main-path)。