diff --git a/.config/example.yml b/.config/example.yml
index 1e7f7d89e8..a9289dfd4f 100644
--- a/.config/example.yml
+++ b/.config/example.yml
@@ -41,10 +41,6 @@ redis:
   port: 6379
   pass: example-pass
 
-recaptcha:
-  site_key: example-site-key
-  secret_key: example-secret-key
-
 # If enabled:
 #  Server will not cache remote files (Using direct link instead).
 #  You can save your storage.
@@ -67,6 +63,11 @@ preventCache: false
 #   port: 9200
 #   pass: null
 
+# reCAPTCHA
+# recaptcha:
+#   site_key: example-site-key
+#  secret_key: example-secret-key
+
 # ServiceWorker
 # sw:
 #   # Public key of VAPID
diff --git a/docs/setup.en.md b/docs/setup.en.md
index 5e986d8035..5a277f19bd 100644
--- a/docs/setup.en.md
+++ b/docs/setup.en.md
@@ -48,9 +48,9 @@ In root :
 4. `git checkout $(git tag -l | grep -v 'rc[0-9]*$' | sort -V | tail -n 1)` Checkout to the [latest release](https://github.com/syuilo/misskey/releases/latest)
 5. `npm install` Install misskey dependencies.
 
-*5.* reCAPTCHA tokens
+*(optional)* reCAPTCHA tokens
 ----------------------------------------------------------------
-Misskey requires reCAPTCHA tokens.
+If you want to enable reCAPTCHA, you need to generate reCAPTCHA tokens:
 Please visit https://www.google.com/recaptcha/intro/ and generate keys.
 
 *(optional)* Generating VAPID keys
@@ -63,13 +63,12 @@ npm install web-push -g
 web-push generate-vapid-keys
 ```
 
-
-*6.* Make configuration file
+*5.* Make configuration file
 ----------------------------------------------------------------
 1. `cp .config/example.yml .config/default.yml` Copy the `.config/example.yml` and rename it to `default.yml`.
 2. Edit `default.yml`
 
-*7.* Build Misskey
+*6.* Build Misskey
 ----------------------------------------------------------------
 
 Build misskey with the following:
@@ -85,7 +84,7 @@ If you're still encountering errors about some modules, use node-gyp:
 3. `node-gyp build`
 4. `npm run build`
 
-*8.* That is it.
+*7.* That is it.
 ----------------------------------------------------------------
 Well done! Now, you have an environment that run to Misskey.
 
diff --git a/docs/setup.ja.md b/docs/setup.ja.md
index a8289aeb9e..aa8d8d99fc 100644
--- a/docs/setup.ja.md
+++ b/docs/setup.ja.md
@@ -47,10 +47,10 @@ adduser --disabled-password --disabled-login misskey
 4. `git checkout $(git tag -l | grep -v 'rc[0-9]*$' | sort -V | tail -n 1)` [最新のリリース](https://github.com/syuilo/misskey/releases/latest)を確認
 5. `npm install` Misskeyの依存パッケージをインストール
 
-*5.* reCAPTCHAトークン
+*(オプション)* reCAPTCHAトークン
 ----------------------------------------------------------------
-MisskeyはreCAPTCHAトークンを必要とします。
-https://www.google.com/recaptcha/intro/ にアクセスしてトークンを生成してください。
+reCAPTCHAを有効にする場合、reCAPTCHAトークンを取得する必要があります。
+https://www.google.com/recaptcha/intro/ にアクセスしてトークンを取得してください。
 
 *(オプション)* VAPIDキーペアの生成
 ----------------------------------------------------------------
@@ -61,12 +61,12 @@ npm install web-push -g
 web-push generate-vapid-keys
 ```
 
-*6.* Make configuration file
+*5.* 設定ファイルを作成する
 ----------------------------------------------------------------
 1. `cp .config/example.yml .config/default.yml` `.config/example.yml`をコピーし名前を`default.yml`にする。
 2. `default.yml` を編集する。
 
-*7.* Misskeyのビルド
+*6.* Misskeyのビルド
 ----------------------------------------------------------------
 
 次のコマンドでMisskeyをビルドしてください:
@@ -81,8 +81,7 @@ Debianをお使いであれば、`build-essential`パッケージをインスト
 3. `node-gyp build`
 4. `npm run build`
 
-
-*6.* 以上です!
+*7.* 以上です!
 ----------------------------------------------------------------
 お疲れ様でした。これでMisskeyを動かす準備は整いました。
 
diff --git a/src/client/app/common/views/components/signup.vue b/src/client/app/common/views/components/signup.vue
index 62373a59ec..8b422268e8 100644
--- a/src/client/app/common/views/components/signup.vue
+++ b/src/client/app/common/views/components/signup.vue
@@ -29,7 +29,7 @@
 			<p slot="text" v-if="passwordRetypeState == 'not-match'" style="color:#FF1161">%fa:exclamation-triangle .fw% %i18n:@password-not-matched%</p>
 		</div>
 	</ui-input>
-	<div class="g-recaptcha" :data-sitekey="recaptchaSitekey" style="margin: 16px 0;"></div>
+	<div v-if="recaptchaSitekey != null" class="g-recaptcha" :data-sitekey="recaptchaSitekey" style="margin: 16px 0;"></div>
 	<label class="agree-tou" style="display: block; margin: 16px 0;">
 		<input name="agree-tou" type="checkbox" required/>
 		<p><a :href="touUrl" target="_blank">利用規約</a>に同意する</p>
@@ -115,7 +115,7 @@ export default Vue.extend({
 			(this as any).api('signup', {
 				username: this.username,
 				password: this.password,
-				'g-recaptcha-response': (window as any).grecaptcha.getResponse()
+				'g-recaptcha-response': recaptchaSitekey != null ? (window as any).grecaptcha.getResponse() : null
 			}).then(() => {
 				(this as any).api('signin', {
 					username: this.username,
@@ -126,15 +126,19 @@ export default Vue.extend({
 			}).catch(() => {
 				alert('%i18n:@some-error%');
 
-				(window as any).grecaptcha.reset();
+				if (recaptchaSitekey != null) {
+					(window as any).grecaptcha.reset();
+				}
 			});
 		}
 	},
 	mounted() {
-		const head = document.getElementsByTagName('head')[0];
-		const script = document.createElement('script');
-		script.setAttribute('src', 'https://www.google.com/recaptcha/api.js');
-		head.appendChild(script);
+		if (recaptchaSitekey != null) {
+			const head = document.getElementsByTagName('head')[0];
+			const script = document.createElement('script');
+			script.setAttribute('src', 'https://www.google.com/recaptcha/api.js');
+			head.appendChild(script);
+		}
 	}
 });
 </script>
diff --git a/src/config/types.ts b/src/config/types.ts
index 28eaa50346..aa4357aa55 100644
--- a/src/config/types.ts
+++ b/src/config/types.ts
@@ -40,7 +40,7 @@ export type Source = {
 		port: number;
 		pass: string;
 	};
-	recaptcha: {
+	recaptcha?: {
 		site_key: string;
 		secret_key: string;
 	};
diff --git a/src/server/api/private/signup.ts b/src/server/api/private/signup.ts
index 023a36586f..2346222b6f 100644
--- a/src/server/api/private/signup.ts
+++ b/src/server/api/private/signup.ts
@@ -7,14 +7,16 @@ import generateUserToken from '../common/generate-native-user-token';
 import config from '../../../config';
 import Meta from '../../../models/meta';
 
-recaptcha.init({
-	secret_key: config.recaptcha.secret_key
-});
+if (config.recaptcha) {
+	recaptcha.init({
+		secret_key: config.recaptcha.secret_key
+	});
+}
 
 export default async (ctx: Koa.Context) => {
 	// Verify recaptcha
 	// ただしテスト時はこの機構は障害となるため無効にする
-	if (process.env.NODE_ENV !== 'test') {
+	if (process.env.NODE_ENV !== 'test' && config.recaptcha != null) {
 		const success = await recaptcha(ctx.request.body['g-recaptcha-response']);
 
 		if (!success) {
diff --git a/webpack.config.ts b/webpack.config.ts
index 5cb2696447..e60eb8347e 100644
--- a/webpack.config.ts
+++ b/webpack.config.ts
@@ -72,7 +72,7 @@ const output = {
 
 //#region Define consts
 const consts = {
-	_RECAPTCHA_SITEKEY_: config.recaptcha.site_key,
+	_RECAPTCHA_SITEKEY_: config.recaptcha ? config.recaptcha.site_key : null,
 	_SW_PUBLICKEY_: config.sw ? config.sw.public_key : null,
 	_THEME_COLOR_: constants.themeColor,
 	_COPYRIGHT_: constants.copyright,