diff --git a/assets/icons/128.png b/assets/icons/128.png
new file mode 100644
index 0000000000..0bfa5aeb3e
Binary files /dev/null and b/assets/icons/128.png differ
diff --git a/assets/icons/16.png b/assets/icons/16.png
new file mode 100644
index 0000000000..9d3226d37a
Binary files /dev/null and b/assets/icons/16.png differ
diff --git a/assets/icons/192.png b/assets/icons/192.png
new file mode 100644
index 0000000000..3fa9b0dab7
Binary files /dev/null and b/assets/icons/192.png differ
diff --git a/assets/icons/256.png b/assets/icons/256.png
new file mode 100644
index 0000000000..b3c4be42af
Binary files /dev/null and b/assets/icons/256.png differ
diff --git a/assets/icons/32.png b/assets/icons/32.png
new file mode 100644
index 0000000000..29b3876cb8
Binary files /dev/null and b/assets/icons/32.png differ
diff --git a/assets/icons/64.png b/assets/icons/64.png
new file mode 100644
index 0000000000..ab35f8fec1
Binary files /dev/null and b/assets/icons/64.png differ
diff --git a/locales/en.yml b/locales/en.yml
index 3290b9642c..535bb2fcea 100644
--- a/locales/en.yml
+++ b/locales/en.yml
@@ -47,7 +47,7 @@ common:
   ok: "OK"
   update-available: "A new version of Misskey is now available({newer}, the current version is {current}). Reload the page to apply updates."
   my-token-regenerated: "Your token has been renewed so you will be signed out."
-  i-like-sushi: "私は(プリンよりむしろ)寿司が好き"
+  i-like-sushi: "I like sushi rather than pudding"
   widgets:
     analog-clock: "Analog clock"
     profile: "Profile"
diff --git a/locales/ja.yml b/locales/ja.yml
index 29decefe68..f2a85eb4e6 100644
--- a/locales/ja.yml
+++ b/locales/ja.yml
@@ -52,6 +52,7 @@ common:
   ok: "わかった"
   update-available: "Misskeyの新しいバージョンがあります({newer}。現在{current}を利用中)。ページを再度読み込みすると更新が適用されます。"
   my-token-regenerated: "あなたのトークンが更新されたのでサインアウトします。"
+  i-like-sushi: "私は(プリンよりむしろ)寿司が好き"
 
   widgets:
     analog-clock: "アナログ時計"
diff --git a/package.json b/package.json
index 6691723386..9961782c9d 100644
--- a/package.json
+++ b/package.json
@@ -1,8 +1,8 @@
 {
 	"name": "misskey",
 	"author": "syuilo <i@syuilo.com>",
-	"version": "4.1.1",
-	"clientVersion": "1.0.6542",
+	"version": "4.3.0",
+	"clientVersion": "1.0.6630",
 	"codename": "nighthike",
 	"main": "./built/index.js",
 	"private": true,
@@ -215,9 +215,7 @@
 		"webpack-cli": "2.1.4",
 		"websocket": "1.0.26",
 		"ws": "5.2.0",
-		"xev": "2.0.1"
-	},
-	"devDependencies": {
+		"xev": "2.0.1",
 		"@types/file-type": "5.2.1",
 		"@types/jsdom": "11.0.5"
 	}
diff --git a/src/client/app/common/views/components/reaction-icon.vue b/src/client/app/common/views/components/reaction-icon.vue
index 7d24f4f9e9..2d5391a21e 100644
--- a/src/client/app/common/views/components/reaction-icon.vue
+++ b/src/client/app/common/views/components/reaction-icon.vue
@@ -8,7 +8,10 @@
 	<img v-if="reaction == 'congrats'" src="/assets/reactions/congrats.png" alt="%i18n:common.reactions.congrats%">
 	<img v-if="reaction == 'angry'" src="/assets/reactions/angry.png" alt="%i18n:common.reactions.angry%">
 	<img v-if="reaction == 'confused'" src="/assets/reactions/confused.png" alt="%i18n:common.reactions.confused%">
-	<img v-if="reaction == 'pudding'" src="/assets/reactions/pudding.png" alt="%i18n:common.reactions.pudding%">
+	<template v-if="reaction == 'pudding'">
+		<img v-if="$store.getters.isSignedIn && $store.state.settings.iLikeSushi" src="/assets/reactions/sushi.png" alt="%i18n:common.reactions.pudding%">
+		<img v-else src="/assets/reactions/pudding.png" alt="%i18n:common.reactions.pudding%">
+	</template>
 </span>
 </template>
 
diff --git a/src/client/app/desktop/views/components/settings.vue b/src/client/app/desktop/views/components/settings.vue
index c660c2869a..536d270dce 100644
--- a/src/client/app/desktop/views/components/settings.vue
+++ b/src/client/app/desktop/views/components/settings.vue
@@ -45,6 +45,7 @@
 				<mk-switch v-model="darkmode" text="%i18n:@dark-mode%"/>
 				<mk-switch v-model="$store.state.settings.circleIcons" @change="onChangeCircleIcons" text="%i18n:@circle-icons%"/>
 				<mk-switch v-model="$store.state.settings.gradientWindowHeader" @change="onChangeGradientWindowHeader" text="%i18n:@gradient-window-header%"/>
+				<mk-switch v-model="$store.state.settings.iLikeSushi" @change="onChangeILikeSushi" text="%i18n:common.i-like-sushi%"/>
 			</div>
 			<mk-switch v-model="$store.state.settings.showPostFormOnTopOfTl" @change="onChangeShowPostFormOnTopOfTl" text="%i18n:@post-form-on-timeline%"/>
 			<mk-switch v-model="$store.state.settings.showReplyTarget" @change="onChangeShowReplyTarget" text="%i18n:@show-reply-target%"/>
@@ -362,6 +363,12 @@ export default Vue.extend({
 				value: v
 			});
 		},
+		onChangeILikeSushi(v) {
+			this.$store.dispatch('settings/set', {
+				key: 'iLikeSushi',
+				value: v
+			});
+		},
 		onChangeGradientWindowHeader(v) {
 			this.$store.dispatch('settings/set', {
 				key: 'gradientWindowHeader',
diff --git a/src/client/app/desktop/views/pages/welcome.vue b/src/client/app/desktop/views/pages/welcome.vue
index 70fa0123af..029e44e27c 100644
--- a/src/client/app/desktop/views/pages/welcome.vue
+++ b/src/client/app/desktop/views/pages/welcome.vue
@@ -13,7 +13,7 @@
 					<h1 v-else><img :src="$store.state.device.darkmode ? 'assets/title.dark.svg' : 'assets/title.light.svg'" alt="Misskey"></h1>
 					<p class="powerd-by" v-if="name">powerd by <b>Misskey</b></p>
 					<p class="desc" v-html="description || '%i18n:common.about%'"></p>
-					<a ref="signup" @click="signup">%i18n:@signup%</a>
+					<a ref="signup" @click="signup">📦 %i18n:@signup%</a>
 				</div>
 				<div class="login">
 					<mk-signin/>
diff --git a/src/client/app/mobile/views/pages/settings.vue b/src/client/app/mobile/views/pages/settings.vue
index 1c5a43ede4..34482fccba 100644
--- a/src/client/app/mobile/views/pages/settings.vue
+++ b/src/client/app/mobile/views/pages/settings.vue
@@ -12,6 +12,7 @@
 
 				<ui-switch v-model="darkmode">%i18n:@dark-mode%</ui-switch>
 				<ui-switch v-model="$store.state.settings.circleIcons" @change="onChangeCircleIcons">%i18n:@circle-icons%</ui-switch>
+				<ui-switch v-model="$store.state.settings.iLikeSushi" @change="onChangeILikeSushi">%i18n:common.i-like-sushi%</ui-switch>
 
 				<div>
 					<div>%i18n:@timeline%</div>
@@ -174,6 +175,13 @@ export default Vue.extend({
 			});
 		},
 
+		onChangeILikeSushi(v) {
+			this.$store.dispatch('settings/set', {
+				key: 'iLikeSushi',
+				value: v
+			});
+		},
+
 		onChangeShowReplyTarget(v) {
 			this.$store.dispatch('settings/set', {
 				key: 'showReplyTarget',
diff --git a/src/client/app/store.ts b/src/client/app/store.ts
index 267c804fbd..1bc39ae66d 100644
--- a/src/client/app/store.ts
+++ b/src/client/app/store.ts
@@ -18,7 +18,8 @@ const defaultSettings = {
 	showRenotedMyNotes: true,
 	loadRemoteMedia: true,
 	disableViaMobile: false,
-	memo: null
+	memo: null,
+	iLikeSushi: false
 };
 
 const defaultDeviceSettings = {
diff --git a/src/client/assets/manifest.json b/src/client/assets/manifest.json
index 25be82fdc6..dcd1e26790 100644
--- a/src/client/assets/manifest.json
+++ b/src/client/assets/manifest.json
@@ -6,33 +6,33 @@
 	"background_color": "#313a42",
 	"icons": [
 		{
-			"src": "/assets/favicon/16.png",
-			"size": "16x16",
+			"src": "/assets/icons/16.png",
+			"sizes": "16x16",
 			"type": "image/png"
 		},
 		{
-			"src": "/assets/favicon/32.png",
-			"size": "32x32",
+			"src": "/assets/icons/32.png",
+			"sizes": "32x32",
 			"type": "image/png"
 		},
 		{
-			"src": "/assets/favicon/64.png",
-			"size": "64x64",
+			"src": "/assets/icons/64.png",
+			"sizes": "64x64",
 			"type": "image/png"
 		},
 		{
-			"src": "/assets/favicon/128.png",
-			"size": "128x128",
+			"src": "/assets/icons/128.png",
+			"sizes": "128x128",
 			"type": "image/png"
 		},
 		{
-			"src": "/assets/favicon/192.png",
-			"size": "192x192",
+			"src": "/assets/icons/192.png",
+			"sizes": "192x192",
 			"type": "image/png"
 		},
 		{
-			"src": "/assets/favicon/256.png",
-			"size": "256x256",
+			"src": "/assets/icons/256.png",
+			"sizes": "256x256",
 			"type": "image/png"
 		}
 	],
diff --git a/src/client/assets/reactions/sushi.png b/src/client/assets/reactions/sushi.png
new file mode 100644
index 0000000000..c30d44eb15
Binary files /dev/null and b/src/client/assets/reactions/sushi.png differ
diff --git a/src/server/web/index.ts b/src/server/web/index.ts
index d38d9165d4..4400fc1024 100644
--- a/src/server/web/index.ts
+++ b/src/server/web/index.ts
@@ -49,9 +49,7 @@ const router = new Router();
 //#region static assets
 
 router.get('/assets/*', async ctx => {
-	// 互換性のため
-	const path = ctx.path.replace('.raw.js', '.js').replace('.min.js', '.js');
-	await send(ctx, path, {
+	await send(ctx, ctx.path, {
 		root: client,
 		maxage: ms('7 days'),
 		immutable: true