diff --git a/components/download-file-button/download-file-button.html.js b/components/download-file-button/download-file-button.html.js
deleted file mode 100644
--- a/components/download-file-button/download-file-button.html.js
+++ /dev/null
@@ -1,33 +0,0 @@
-const Component = require('../component.class');
-const fs = require('fs');
-const util = require('util');
-const path = require('path');
-
-const readFile = util.promisify(fs.readFile);
-
-class DownloadFileButton extends Component {
-	async renderFn(s, { text }) {
-		/* eslint-disable indent */
-		return /* HTML */ `
-			<a
-				href="${await s.addOutputFile({
-					relative_path: '/assets/images/',
-					base_name: 'example-file.png',
-					generator: async function() {
-						return await readFile(
-							path.resolve(__dirname, './example-file.png')
-						);
-					},
-					deps: [],
-				})}"
-				>${text}</a
-			>
-		`;
-		/* eslint-enable indent */
-	}
-	static propsControls() {
-		return { text: 'text' };
-	}
-}
-
-module.exports = DownloadFileButton;
diff --git a/components/download-file-button/download-file-button.js b/components/download-file-button/download-file-button.js
new file mode 100644
--- /dev/null
+++ b/components/download-file-button/download-file-button.js
@@ -0,0 +1,35 @@
+const Component = require('../component.class');
+
+class DownloadFileButton extends Component {
+	async renderFn(s, { text }) {
+		const fs = s.node_require('fs');
+		const util = s.node_require('util');
+		const path = s.node_require('path');
+
+		const readFile = util.promisify(fs.readFile);
+		/* eslint-disable indent */
+		return /* HTML */ `
+			<a
+				href="${
+					await s.addOutputFile({
+						output_subdir: './assets/images/',
+						base_name: 'example-file.png',
+						generator: async function() {
+							return await readFile(
+								path.resolve(__dirname, './example-file.png')
+							);
+						},
+						deps: [],
+					})
+				}"
+				>${text}</a
+			>
+		`;
+		/* eslint-enable indent */
+	}
+	static propsControls() {
+		return { text: 'text' };
+	}
+}
+
+module.exports = DownloadFileButton;
diff --git a/components/index.js b/components/index.js
--- a/components/index.js
+++ b/components/index.js
@@ -1,9 +1,11 @@
 const Markdown = require('./markdown/markdown.html');
 const Navbar = require('./navbar/navbar.html');
-const DownloadFileButton = require('./download-file-button/download-file-button.html');
+const DownloadFileButton = require('./download-file-button/download-file-button');
+const ResponsiveImage = require('./responsive-image/responsive-image');
 
 module.exports = {
 	Markdown,
 	Navbar,
 	DownloadFileButton,
+	ResponsiveImage,
 };
diff --git a/components/responsive-image/responsive-image.html.js b/components/responsive-image/responsive-image.html.js
deleted file mode 100644
--- a/components/responsive-image/responsive-image.html.js
+++ /dev/null
@@ -1,61 +0,0 @@
-const sharp = require('sharp');
-const path = require('path');
-const { promisify } = require('util');
-const locreq = require('locreq')(__dirname);
-const fs = require('fs');
-const hashFile = require('../../../lib/hash-file.js');
-const access = promisify(fs.access);
-
-/*
-    image_path: string
-	resolutions: array of sizes ie. [200, 150 ...]
-	quality: number, quality of the resized image
-    sizes_attr: string, sizes attribute for responsive img html tag
-    alt: string, img's alt attribute
-*/
-
-module.exports = async function({
-	image_path,
-	resolutions,
-	quality = 80,
-	sizes_attr,
-	alt = '',
-}) {
-	try {
-		const image_path_to_checksum = {};
-
-		const created_files = await Promise.all(
-			resolutions.map(async resolution => {
-				let image_basename = path.basename(image_path); //Extract file's name
-				const extension = path.extname(image_basename); //Get the file extension
-				image_basename = path.basename(image_path, extension);
-				if (!image_path_to_checksum[image_path]) {
-					image_path_to_checksum[image_path] = hashFile(
-						locreq.resolve(image_path)
-					).substring(0, 8);
-				}
-				const checksum = image_path_to_checksum[image_path];
-				const responsive_file_name = `${image_basename}-${checksum}-${resolution}w${extension}`;
-				const destination = `/assets/${responsive_file_name}`;
-				// If resized image already exists do not resize it again
-				await access(locreq.resolve(image_path), fs.constants.OK).catch(
-					() => {
-						return -1;
-					}
-				);
-				//Resize and save new, transformed file
-				await sharp(locreq.resolve(image_path))
-					.resize(resolution)
-					.jpeg({ quality })
-					.toFile(locreq.resolve(`public/${destination}`));
-				return `${destination} ${resolution}w`;
-			})
-		);
-		//Generate appropriate repsonsive img tag
-		return /* HTML  */ `<img src="${image_path}" srcset="${created_files.join(
-			',\n'
-		)}" sizes="${sizes_attr}" alt="${alt}"/>`;
-	} catch (error) {
-		throw new Error(error);
-	}
-};
diff --git a/components/responsive-image/responsive-image.js b/components/responsive-image/responsive-image.js
new file mode 100644
--- /dev/null
+++ b/components/responsive-image/responsive-image.js
@@ -0,0 +1,78 @@
+const Component = require('../component.class');
+
+/*
+    image_path: string
+	resolutions: array of sizes ie. [200, 150 ...]
+	quality: number, quality of the resized image
+    sizes_attr: string, sizes attribute for responsive img html tag
+    alt: string, img's alt attribute
+*/
+
+class ResponsiveImage extends Component {
+	async renderFn(
+		s,
+		{
+			image_path,
+			resolutions = [100, 400, 900, 1000, 1300],
+			quality = 80,
+			sizes_attr,
+			alt = '',
+		}
+	) {
+		const sharp = s.node_require('sharp');
+		const path = s.node_require('path');
+		const { promisify } = s.node_require('util');
+		const locreq = s.node_require('locreq')(__dirname);
+		const fs = s.node_require('fs');
+		const hashFile = s.node_require(
+			path.resolve(__dirname, '../../lib/hash-file.js')
+		);
+		if (!image_path) {
+			image_path = locreq.resolve('assets/sealpage-logo.png');
+		}
+		const readFile = promisify(fs.readFile);
+
+		let image_basename = path.basename(image_path); //Extract file's name
+		const extension = path.extname(image_basename); //Get the file extension
+		image_basename = path.basename(image_path, extension);
+
+		const file_hash = hashFile(locreq.resolve(image_path)).substring(0, 8);
+
+		const output_files = {};
+
+		for (let resolution of resolutions) {
+			const path = await s.addOutputFile({
+				output_subdir: 'images',
+				base_name: `${image_basename}-${resolution}.${extension}`,
+				generator: () =>
+					sharp(locreq.resolve(image_path))
+						.resize(resolution)
+						.jpeg({ quality })
+						.toBuffer(),
+				deps: [file_hash],
+			});
+			output_files[resolution] = path;
+		}
+
+		const median_resolution =
+			resolutions[Math.round((resolutions.length - 1) / 2)];
+
+		const srcset = resolutions
+			.map(resolution => `${output_files[resolution]} ${resolution}w`)
+			.join(',\n');
+
+		return /* HTML */ `
+			<img
+				src="${output_files[median_resolution]}"
+				srcset="${srcset}"
+				sizes="${sizes_attr}"
+				alt="${alt}"
+			/>
+		`;
+	}
+	static propsControls() {
+		return {};
+	}
+}
+
+module.exports = ResponsiveImage;
diff --git a/get-app.js b/get-app.js
--- a/get-app.js
+++ b/get-app.js
@@ -42,7 +42,8 @@
 	let output_dir = path.resolve(temporary_path);
 
 	const component_instances = {};
-	const s = new S({ output_dir });
+	const path_prefix = `/previews/${uuid}`;
+	const s = new S({ output_dir, path_prefix });
 
 	// creating componentsinstances
 	for (const component_name in components_map) {
@@ -58,7 +59,7 @@
 
 	await writeFile(`${output_dir}/index.html`, html);
 
-	return `/previews/${uuid}/index.html?${uuidv4()}`;
+	return `${path_prefix}/index.html?${uuidv4()}`;
 }
 
 module.exports = config => {
diff --git a/lib/s.js b/lib/s.js
--- a/lib/s.js
+++ b/lib/s.js
@@ -2,36 +2,60 @@
 const path = require('path');
 const util = require('util');
 
-const fileExists = util.promisify(fs.access);
+const access = util.promisify(fs.access);
 const writeFile = util.promisify(fs.writeFile);
 
 const md5 = require('md5');
+const makeDir = require('make-dir');
 
 class S {
-	constructor({ output_dir }) {
+	constructor({ output_dir, path_prefix }) {
 		this.output_dir = output_dir;
+		this.path_prefix = path_prefix; // for example: "/previews/92180392ueu093"
 	}
 
-	async addOutputFile({ relative_path, base_name, generator, deps }) {
+	async addOutputFile({ output_subdir, base_name, generator, deps }) {
 		const hash = md5(JSON.stringify(deps));
 
 		let output_filename = base_name.split('.');
 		output_filename.splice(output_filename.length - 1, 0, hash);
-		output_filename.join('.');
+		output_filename = output_filename.join('.');
+
+		if (output_subdir[0] === '/') {
+			output_subdir = '.' + output_subdir;
+		}
 
 		const output_path = path.resolve(
 			this.output_dir,
-			relative_path,
+			output_subdir,
 			output_filename
 		);
 
 		try {
-			await fileExists(output_path);
+			await access(path.resolve(output_path, '..'));
+		} catch (error) {
+			if (error.code === 'ENOENT') {
+				await makeDir(path.resolve(output_path, '..'));
+			} else throw error;
+		}
+
+		try {
+			await access(output_path);
 		} catch (error) {
 			await writeFile(output_path, await generator());
 		}
+		return path.join(this.path_prefix, output_subdir, output_filename);
+	}
 
-		return output_path;
+	node_require(module_name) {
+		try {
+			return require(module_name);
+		} catch (e) {
+			console.error(e);
+			throw new Error(
+				`Could not resolve module '${module_name}'. It might not be installed or you're running the s.node_require function in the browser, while it's only supposed to be called on backend side`
+			);
+		}
 	}
 }
 
diff --git a/package-lock.json b/package-lock.json
--- a/package-lock.json
+++ b/package-lock.json
@@ -6666,6 +6666,24 @@
 				"commondir": "^1.0.1",
 				"make-dir": "^2.0.0",
 				"pkg-dir": "^3.0.0"
+			},
+			"dependencies": {
+				"make-dir": {
+					"version": "2.1.0",
+					"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz",
+					"integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==",
+					"dev": true,
+					"requires": {
+						"pify": "^4.0.1",
+						"semver": "^5.6.0"
+					}
+				},
+				"pify": {
+					"version": "4.0.1",
+					"resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
+					"integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
+					"dev": true
+				}
 			}
 		},
 		"find-up": {
@@ -9776,20 +9794,17 @@
 			}
 		},
 		"make-dir": {
-			"version": "2.1.0",
-			"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz",
-			"integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==",
-			"dev": true,
+			"version": "3.0.0",
+			"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.0.0.tgz",
+			"integrity": "sha512-grNJDhb8b1Jm1qeqW5R/O63wUo4UXo2v2HMic6YT9i/HBlF93S8jkMgH7yugvY9ABDShH4VZMn8I+U8+fCNegw==",
 			"requires": {
-				"pify": "^4.0.1",
-				"semver": "^5.6.0"
+				"semver": "^6.0.0"
 			},
 			"dependencies": {
-				"pify": {
-					"version": "4.0.1",
-					"resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
-					"integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
-					"dev": true
+				"semver": {
+					"version": "6.1.1",
+					"resolved": "https://registry.npmjs.org/semver/-/semver-6.1.1.tgz",
+					"integrity": "sha512-rWYq2e5iYW+fFe/oPPtYJxYgjBm8sC4rmoGdUOgBB7VnwKt6HrL793l2voH1UlsyYZpJ4g0wfjnTEO1s1NP2eQ=="
 				}
 			}
 		},
@@ -10658,18 +10673,18 @@
 			}
 		},
 		"mongodb": {
-			"version": "3.2.3",
-			"resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.2.3.tgz",
-			"integrity": "sha512-jw8UyPsq4QleZ9z+t/pIVy3L++51vKdaJ2Q/XXeYxk/3cnKioAH8H6f5tkkDivrQL4PUgUOHe9uZzkpRFH1XtQ==",
+			"version": "3.2.7",
+			"resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.2.7.tgz",
+			"integrity": "sha512-2YdWrdf1PJgxcCrT1tWoL6nHuk6hCxhddAAaEh8QJL231ci4+P9FLyqopbTm2Z2sAU6mhCri+wd9r1hOcHdoMw==",
 			"requires": {
-				"mongodb-core": "^3.2.3",
+				"mongodb-core": "3.2.7",
 				"safe-buffer": "^5.1.2"
 			}
 		},
 		"mongodb-core": {
-			"version": "3.2.3",
-			"resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-3.2.3.tgz",
-			"integrity": "sha512-UyI0rmvPPkjOJV8XGWa9VCTq7R4hBVipimhnAXeSXnuAPjuTqbyfA5Ec9RcYJ1Hhu+ISnc8bJ1KfGZd4ZkYARQ==",
+			"version": "3.2.7",
+			"resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-3.2.7.tgz",
+			"integrity": "sha512-WypKdLxFNPOH/Jy6i9z47IjG2wIldA54iDZBmHMINcgKOUcWJh8og+Wix76oGd7EyYkHJKssQ2FAOw5Su/n4XQ==",
 			"requires": {
 				"bson": "^1.1.1",
 				"require_optional": "^1.0.1",
@@ -10694,9 +10709,9 @@
 			"integrity": "sha512-TghvYc72wlMGMVMluVo9WRJc0mB8KxxF/gZ4YYFy7V2ZQX9l7rgbPg7vjS9mt6U5HXODVFVI2bOduCzwOMv/lw=="
 		},
 		"nanoid": {
-			"version": "2.0.1",
-			"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-2.0.1.tgz",
-			"integrity": "sha512-k1u2uemjIGsn25zmujKnotgniC/gxQ9sdegdezeDiKdkDW56THUMqlz3urndKCXJxA6yPzSZbXx/QCMe/pxqsA=="
+			"version": "2.0.3",
+			"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-2.0.3.tgz",
+			"integrity": "sha512-NbaoqdhIYmY6FXDRB4eYtDVC9Z9eCbn8TyaiC16LNKtpPv/aqa0tOPD8y6gNE4yUNnaZ7LLhYtXOev/6+cBtfw=="
 		},
 		"nanomatch": {
 			"version": "1.2.13",
@@ -10975,11 +10990,6 @@
 			"resolved": "https://registry.npmjs.org/node-status-codes/-/node-status-codes-1.0.0.tgz",
 			"integrity": "sha1-WuVUHQJGRdMqWPzdyc7s6nrjrC8="
 		},
-		"node-uuid": {
-			"version": "1.4.8",
-			"resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz",
-			"integrity": "sha1-sEDrCSOWivq/jTL7HxfxFn/auQc="
-		},
 		"node-watch": {
 			"version": "0.5.9",
 			"resolved": "https://registry.npmjs.org/node-watch/-/node-watch-0.5.9.tgz",
@@ -14022,8 +14032,8 @@
 			}
 		},
 		"sealious": {
-			"version": "github:sealcode/sealious#e311447ce5ead8462a8150bd6f8c5ef1fcc783f0",
-			"from": "github:sealcode/sealious#e311447ce5ead8462a8150bd6",
+			"version": "github:sealcode/sealious#39b71ca55fa8b49aa548e8f0e995b01a5d36733d",
+			"from": "github:sealcode/sealious#39b71ca55fa8b49aa548e8f0e9",
 			"requires": {
 				"@3846masa/axios-cookiejar-support": "^0.1.4",
 				"@babel/polyfill": "^7.0.0",
@@ -14032,7 +14042,7 @@
 				"bluebird-events": "^2.0.0",
 				"boom": "^4.2.0",
 				"clone": "^1.0.2",
-				"color": "^3.1.1",
+				"color": "^3.1.2",
 				"deep-equal": "^1.0.1",
 				"dot-prop": "^4.2.0",
 				"escape-html": "^1.0.3",
@@ -14060,23 +14070,31 @@
 			},
 			"dependencies": {
 				"axios": {
-					"version": "0.18.0",
-					"resolved": "https://registry.npmjs.org/axios/-/axios-0.18.0.tgz",
-					"integrity": "sha1-MtU+SFHv3AoRmTts0AB4nXDAUQI=",
+					"version": "0.18.1",
+					"resolved": "https://registry.npmjs.org/axios/-/axios-0.18.1.tgz",
+					"integrity": "sha512-0BfJq4NSfQXd+SkFdrvFbG7addhYSBA2mQwISr46pD6E5iqkWg02RAs8vyTT/j0RTnoYmeXauBuSv1qKwR179g==",
 					"requires": {
-						"follow-redirects": "^1.3.0",
-						"is-buffer": "^1.1.5"
+						"follow-redirects": "1.5.10",
+						"is-buffer": "^2.0.2"
 					}
 				},
 				"color": {
-					"version": "3.1.1",
-					"resolved": "https://registry.npmjs.org/color/-/color-3.1.1.tgz",
-					"integrity": "sha512-PvUltIXRjehRKPSy89VnDWFKY58xyhTLyxIg21vwQBI6qLwZNPmC8k3C1uytIgFKEpOIzN4y32iPm8231zFHIg==",
+					"version": "3.1.2",
+					"resolved": "https://registry.npmjs.org/color/-/color-3.1.2.tgz",
+					"integrity": "sha512-vXTJhHebByxZn3lDvDJYw4lR5+uB3vuoHsuYA5AKuxRVn5wzzIfQKGLBmgdVRHKTJYeK5rvJcHnrd0Li49CFpg==",
 					"requires": {
 						"color-convert": "^1.9.1",
 						"color-string": "^1.5.2"
 					}
 				},
+				"debug": {
+					"version": "3.1.0",
+					"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+					"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+					"requires": {
+						"ms": "2.0.0"
+					}
+				},
 				"dot-prop": {
 					"version": "4.2.0",
 					"resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz",
@@ -14085,6 +14103,29 @@
 						"is-obj": "^1.0.0"
 					}
 				},
+				"follow-redirects": {
+					"version": "1.5.10",
+					"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz",
+					"integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==",
+					"requires": {
+						"debug": "=3.1.0"
+					}
+				},
+				"is-buffer": {
+					"version": "2.0.3",
+					"resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.3.tgz",
+					"integrity": "sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw=="
+				},
+				"ms": {
+					"version": "2.0.0",
+					"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+					"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+				},
+				"node-uuid": {
+					"version": "1.4.8",
+					"resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz",
+					"integrity": "sha1-sEDrCSOWivq/jTL7HxfxFn/auQc="
+				},
 				"qs": {
 					"version": "6.7.0",
 					"resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
diff --git a/package.json b/package.json
--- a/package.json
+++ b/package.json
@@ -25,6 +25,7 @@
 		"glob": "^7.1.3",
 		"http-server": "^0.11.1",
 		"locreq": "^1.1.0",
+		"make-dir": "^3.0.0",
 		"marked": "^0.6.2",
 		"md5": "^2.2.1",
 		"md5-file": "^4.0.0",
@@ -35,7 +36,7 @@
 		"react": "^16.8.6",
 		"react-dom": "^16.8.6",
 		"react-router-dom": "^5.0.0",
-		"sealious": "sealcode/sealious#e311447ce5ead8462a8150bd6",
+		"sealious": "sealcode/sealious#39b71ca55fa8b49aa548e8f0e9",
 		"sharp": "^0.21.3",
 		"uuid": "^3.3.2",
 		"yargs": "^13.2.2"