diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 5c54fb6ef1ce4..000943bf62d8e 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -5,6 +5,10 @@
# The #CC# prefix delineates Code Coverage,
# used for the 'team' designator within Kibana Stats
+# Tech leads
+/dev_docs @elastic/kibana-tech-leads
+/packages/kbn-docs-utils/ @elastic/kibana-tech-leads @elastic/kibana-operations
+
# App
/x-pack/plugins/discover_enhanced/ @elastic/kibana-app
/x-pack/plugins/lens/ @elastic/kibana-app
@@ -201,6 +205,7 @@
/test/functional/services/remote @elastic/kibana-qa
# Core
+/examples/hello_world/ @elastic/kibana-core
/src/core/ @elastic/kibana-core
/src/plugins/saved_objects_tagging_oss @elastic/kibana-core
/config/kibana.yml @elastic/kibana-core
diff --git a/dev_docs/dev_welcome.mdx b/dev_docs/dev_welcome.mdx
deleted file mode 100644
index cc185e689fa43..0000000000000
--- a/dev_docs/dev_welcome.mdx
+++ /dev/null
@@ -1,17 +0,0 @@
----
-id: kibDevDocsWelcome
-slug: /kibana-dev-docs/welcome
-title: Welcome
-summary: Build custom solutions and applications on top of Kibana.
-date: 2021-01-02
-tags: ['kibana','dev', 'contributor']
----
-
-Welcome to Kibana's plugin developer documentation!
-
-Did you know that the vast majority of functionality built inside of Kibana is a plugin? A handful of core services hold the system together,
-but it's our vast system of plugin developers that provide the amazing, out of the box, functionality you can use when building your own set of
-custom utilities and applications.
-
-Browse the `Services` section to view all the plugins that offer functionality you can take advantage of, or check out the
-`API documentation` to dig into the nitty gritty details of every public plugin API.
diff --git a/dev_docs/getting_started/dev_welcome.mdx b/dev_docs/getting_started/dev_welcome.mdx
new file mode 100644
index 0000000000000..3d645b4e54d66
--- /dev/null
+++ b/dev_docs/getting_started/dev_welcome.mdx
@@ -0,0 +1,20 @@
+---
+id: kibDevDocsWelcome
+slug: /kibana-dev-docs/welcome
+title: Welcome
+summary: Build custom solutions and applications on top of Kibana.
+date: 2021-01-02
+tags: ['kibana', 'dev', 'contributor']
+---
+
+[Kibana](https://www.elastic.co/what-is/kibana) is a pluggable platform that allows users to search, visualize and analyze data in Elasticsearch.
+
+Kibana ships with many out-of-the-box capabilities that can be extended and enhanced by custom javascript plugins. Developers can also write their own custom applications.
+
+Recommended next reading:
+
+1.
+2. Create a simple .
+
+Check out our to dig into the nitty gritty details of
+every public plugin API.
diff --git a/dev_docs/getting_started/hello_world_generated.png b/dev_docs/getting_started/hello_world_generated.png
new file mode 100644
index 0000000000000..57f389389b794
Binary files /dev/null and b/dev_docs/getting_started/hello_world_generated.png differ
diff --git a/dev_docs/getting_started/hello_world_manual.png b/dev_docs/getting_started/hello_world_manual.png
new file mode 100644
index 0000000000000..bb36aab32f392
Binary files /dev/null and b/dev_docs/getting_started/hello_world_manual.png differ
diff --git a/dev_docs/getting_started/hello_world_plugin.mdx b/dev_docs/getting_started/hello_world_plugin.mdx
new file mode 100644
index 0000000000000..d3b30b240dedc
--- /dev/null
+++ b/dev_docs/getting_started/hello_world_plugin.mdx
@@ -0,0 +1,157 @@
+---
+id: kibHelloWorldApp
+slug: /kibana-dev-docs/hello-world-app
+title: Hello World
+summary: Build a very basic plugin that registers an application that says "Hello World!".
+date: 2021-08-03
+tags: ['kibana', 'dev', 'contributor', 'tutorials']
+---
+
+This tutorial walks you through two ways to create a plugin that registers an application that says "Hello World!".
+
+You can view the tested example plugin at [examples/hello_world](https://github.com/elastic/kibana/tree/master/examples/hello_world).
+
+## 1. Set up your development environment
+
+Read through to get your development environment set up.
+
+## 2. Option 1 - Write it manually
+
+This is a good option if you want to understand the bare minimum needed to register a "Hello world" application. The example plugin is based off of this option.
+
+1. Create your plugin folder. Start off in the `kibana` folder.
+
+```
+$ cd examples
+$ mkdir hello_world
+$ cd hello_world
+```
+
+2. Create the .
+
+```
+$ touch kibana.json
+```
+
+and add the following:
+
+```
+{
+ "id": "helloWorld",
+ "version": "1.0.0",
+ "kibanaVersion": "kibana",
+ "ui": true
+}
+```
+
+3. Create a `tsconfig.json` file.
+
+```
+$ touch tsconfig.json
+```
+
+And add the following to it:
+
+```
+{
+ "extends": "../../tsconfig.json",
+ "compilerOptions": {
+ "outDir": "./target",
+ "skipLibCheck": true
+ },
+ "include": [
+ "index.ts",
+ "common/**/*.ts",
+ "public/**/*.ts",
+ "public/**/*.tsx",
+ "server/**/*.ts",
+ "../../typings/**/*"
+ ],
+ "exclude": []
+}
+```
+
+4. Create a .
+
+```
+$ mkdir public
+$ touch plugin.tsx
+```
+
+And add the following to it:
+
+```ts
+import React from 'react';
+import ReactDOM from 'react-dom';
+import { AppMountParameters, CoreSetup, CoreStart, Plugin } from '../../../src/core/public';
+
+export class HelloWorldPlugin implements Plugin {
+ public setup(core: CoreSetup) {
+ // Register an application into the side navigation menu
+ core.application.register({
+ id: 'helloWorld',
+ title: 'Hello World',
+ async mount({ element }: AppMountParameters) {
+ ReactDOM.render(
Hello World!
, element);
+ return () => ReactDOM.unmountComponentAtNode(element);
+ },
+ });
+ }
+ public start(core: CoreStart) {
+ return {};
+ }
+ public stop() {}
+}
+```
+
+5. Create a .
+
+```
+$ touch index.ts
+```
+
+```ts
+import { HelloWorldPlugin } from './plugin';
+
+export function plugin() {
+ return new HelloWorldPlugin();
+}
+```
+
+## 2. Option 2 - Use the automatic plugin generator
+
+This is an easy option to get up and running ASAP and includes additional code.
+
+Use the Automatic plugin generator to get a basic structure for a new plugin. Plugins that are not part of the Kibana repo should be developed inside the plugins folder. If you are building a new plugin to check in to the Kibana repo, you will choose between a few locations:
+
+`x-pack/plugins` for plugins related to subscription features
+`src/plugins` for plugins related to free features
+`examples` for developer example plugins (these will not be included in the distributables)
+
+```
+% node scripts/generate_plugin hello_world
+? Plugin name (use camelCase) helloWorld
+? Will this plugin be part of the Kibana repository? Yes
+? What type of internal plugin would you like to create Kibana Example
+? Should an UI plugin be generated? Yes
+? Should a server plugin be generated? No
+ succ 🎉
+
+ Your plugin has been created in examples/hello_world
+```
+
+## 3. Build your new application
+
+Run `yarn kbn bootstrap`
+
+## 3. Start Kibana with examples and navigate to your new application
+
+In one terminal window, run `yarn es snapshot --license trial` to boot up Elasticsearch.
+
+In another terminal window, run `yarn start --run-examples` to boot up Kibana and include the example plugins. Your example plugin should show up in the navigation at the very bottom.
+
+If you build it manually it will look something like this:
+
+
+If you built it with the generator, it will look something like this:
+
diff --git a/dev_docs/tutorials/setting_up_a_development_env.mdx b/dev_docs/getting_started/setting_up_a_development_env.mdx
similarity index 87%
rename from dev_docs/tutorials/setting_up_a_development_env.mdx
rename to dev_docs/getting_started/setting_up_a_development_env.mdx
index 449e8b886a44d..04e0511e255b1 100644
--- a/dev_docs/tutorials/setting_up_a_development_env.mdx
+++ b/dev_docs/getting_started/setting_up_a_development_env.mdx
@@ -1,8 +1,8 @@
---
id: kibDevTutorialSetupDevEnv
slug: /kibana-dev-docs/tutorial/setup-dev-env
-title: Setting up a Development Environment
-summary: Learn how to setup a development environemnt for contributing to the Kibana repository
+title: Set up a Development Environment
+summary: Learn how to setup a development environment for contributing to the Kibana repository
date: 2021-04-26
tags: ['kibana', 'onboarding', 'dev', 'architecture', 'setup']
---
@@ -12,11 +12,11 @@ Setting up a development environment is pretty easy.
In order to support Windows development we currently require you to use one of the following:
- - [Git Bash](https://git-scm.com/download/win)
- - [Windows Subsystem for Linux](https://docs.microsoft.com/en-us/windows/wsl/about)
+- [Git Bash](https://git-scm.com/download/win)
+- [Windows Subsystem for Linux](https://docs.microsoft.com/en-us/windows/wsl/about)
+Before running the steps below, please make sure you have installed [Visual C++ Redistributable for Visual Studio 2015](https://www.microsoft.com/en-us/download/details.aspx?id=48145) and that you are running all commands in either Git Bash or WSL.
- Before running the steps below, please make sure you have installed [Visual C++ Redistributable for Visual Studio 2015](https://www.microsoft.com/en-us/download/details.aspx?id=48145) and that you are running all commands in either Git Bash or WSL.
## Get the code
diff --git a/examples/hello_world/README.md b/examples/hello_world/README.md
new file mode 100755
index 0000000000000..f43c12886f52d
--- /dev/null
+++ b/examples/hello_world/README.md
@@ -0,0 +1,5 @@
+## Hello World
+
+A very simple Hello World example plugin.
+
+If you are external, you can view the tutorial [here](../../dev_docs/getting_started/hello_world_plugin.mdx), if you are internal, you can view the tutorial [here](https://docs.elastic.dev/kibana-dev-docs/hello-world-app).
diff --git a/examples/hello_world/kibana.json b/examples/hello_world/kibana.json
new file mode 100644
index 0000000000000..d3de28c2cbd7a
--- /dev/null
+++ b/examples/hello_world/kibana.json
@@ -0,0 +1,12 @@
+{
+ "id": "helloWorld",
+ "version": "1.0.0",
+ "kibanaVersion": "kibana",
+ "ui": true,
+ "owner": {
+ "name": "Kibana core",
+ "githubTeam": "kibana-core"
+ },
+ "description": "A plugin which registers a very simple hello world application.",
+ "requiredPlugins": ["developerExamples"]
+}
diff --git a/examples/hello_world/public/index.ts b/examples/hello_world/public/index.ts
new file mode 100755
index 0000000000000..51a911493e9aa
--- /dev/null
+++ b/examples/hello_world/public/index.ts
@@ -0,0 +1,12 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+import { HelloWorldPlugin } from './plugin';
+
+export function plugin() {
+ return new HelloWorldPlugin();
+}
diff --git a/examples/hello_world/public/plugin.tsx b/examples/hello_world/public/plugin.tsx
new file mode 100755
index 0000000000000..cb648bffbb57c
--- /dev/null
+++ b/examples/hello_world/public/plugin.tsx
@@ -0,0 +1,40 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+import React from 'react';
+import ReactDOM from 'react-dom';
+import { AppMountParameters, CoreSetup, CoreStart, Plugin } from '../../../src/core/public';
+import { DeveloperExamplesSetup } from '../../developer_examples/public';
+
+interface SetupDeps {
+ developerExamples: DeveloperExamplesSetup;
+}
+
+export class HelloWorldPlugin implements Plugin {
+ public setup(core: CoreSetup, deps: SetupDeps) {
+ // Register an application into the side navigation menu
+ core.application.register({
+ id: 'helloWorld',
+ title: 'Hello World',
+ async mount({ element }: AppMountParameters) {
+ ReactDOM.render(Hello World!
, element);
+ return () => ReactDOM.unmountComponentAtNode(element);
+ },
+ });
+
+ // This section is only needed to get this example plugin to show up in our Developer Examples.
+ deps.developerExamples.register({
+ appId: 'helloWorld',
+ title: 'Hello World Application',
+ description: `Build a plugin that registers an application that simply says "Hello World"`,
+ });
+ }
+ public start(core: CoreStart) {
+ return {};
+ }
+ public stop() {}
+}
diff --git a/examples/hello_world/tsconfig.json b/examples/hello_world/tsconfig.json
new file mode 100644
index 0000000000000..7fa03739119b4
--- /dev/null
+++ b/examples/hello_world/tsconfig.json
@@ -0,0 +1,16 @@
+{
+ "extends": "../../tsconfig.json",
+ "compilerOptions": {
+ "outDir": "./target",
+ "skipLibCheck": true
+ },
+ "include": [
+ "index.ts",
+ "common/**/*.ts",
+ "public/**/*.ts",
+ "public/**/*.tsx",
+ "server/**/*.ts",
+ "../../typings/**/*"
+ ],
+ "exclude": []
+}
diff --git a/test/examples/hello_world/index.ts b/test/examples/hello_world/index.ts
new file mode 100644
index 0000000000000..d1a37968a9a6c
--- /dev/null
+++ b/test/examples/hello_world/index.ts
@@ -0,0 +1,31 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+import expect from '@kbn/expect';
+import { FtrProviderContext } from 'test/functional/ftr_provider_context';
+
+// eslint-disable-next-line import/no-default-export
+export default function ({ getService, getPageObjects, loadTestFile }: FtrProviderContext) {
+ const retry = getService('retry');
+ const testSubjects = getService('testSubjects');
+ const PageObjects = getPageObjects(['common']);
+
+ describe('Hello world', function () {
+ before(async () => {
+ this.tags('ciGroup2');
+ await PageObjects.common.navigateToApp('helloWorld');
+ });
+
+ it('renders hello world text', async () => {
+ await retry.try(async () => {
+ const message = await testSubjects.getVisibleText('helloWorldDiv');
+ expect(message).to.be('Hello World!');
+ });
+ });
+ });
+}