diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile
index 34f0d04..33cb6b4 100644
--- a/.devcontainer/Dockerfile
+++ b/.devcontainer/Dockerfile
@@ -1,3 +1 @@
-FROM local/nodejs/dev:18
-
-USER node
\ No newline at end of file
+FROM local/nodejs/dev:18
\ No newline at end of file
diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
index fe2606c..a0a8dea 100644
--- a/.devcontainer/devcontainer.json
+++ b/.devcontainer/devcontainer.json
@@ -3,7 +3,7 @@
 	"workspaceFolder": "/home/project/seedling",
 	"dockerComposeFile": "docker-compose.yml",
 	"service": "seedling",
-	"postCreateCommand": "sudo chown node:node -R /home/project",
+	"postCreateCommand": "sudo chown iamuser:iamuser -R /home/project",
 	"customizations": {
 		"vscode": {
 			"extensions": [
diff --git a/.eslintignore b/.eslintignore
new file mode 100644
index 0000000..56f0bce
--- /dev/null
+++ b/.eslintignore
@@ -0,0 +1 @@
+source/
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 3a75e5c..6ab99f9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,6 +4,7 @@ app/
 node_modules/
 
 .vscode/
+.idea/
 
 .pnpm/
 .pnpm-store/
\ No newline at end of file
diff --git a/create.js b/create.js
index 9134556..814923f 100644
--- a/create.js
+++ b/create.js
@@ -7,14 +7,14 @@ const argv = require('minimist')(process.argv.slice(2));
 const appName = argv.name ?? 'app';
 const appPort = argv.port ?? '0';
 
-const defaultContextDir = './';
+const defaultContextDir = '.';
 const rootDir = __dirname;
-const contextDir = `${argv._[0]}/` ?? defaultContextDir;
+const contextDir = `${argv._[0] ?? defaultContextDir}`;
 
 // create app folder
 const appsDir = `${contextDir}/apps`;
 const uiDir = `${contextDir}/apps/${appName}-ui`;
-const apiDir = `${contextDir}/apps/${appName}-rest`;
+const restDir = `${contextDir}/apps/${appName}-rest`;
 
 // prepare structure folders
 if (!fs.existsSync(uiDir)) {
@@ -24,8 +24,8 @@ if (!fs.existsSync(uiDir)) {
 	fs.mkdirSync(appsDir);
 	fs.mkdirSync(uiDir);
 	fs.mkdirSync(`${uiDir}/src`);
-	fs.mkdirSync(apiDir);
-	fs.mkdirSync(`${apiDir}/src`);
+	fs.mkdirSync(restDir);
+	fs.mkdirSync(`${restDir}/src`);
 }
 
 // copy folder content
@@ -38,7 +38,7 @@ try {
 		force: true,
 		recursive: true,
 	});
-	fs.cpSync(`${rootDir}/source/rest/`, apiDir, {
+	fs.cpSync(`${rootDir}/source/rest/`, restDir, {
 		force: true,
 		recursive: true,
 	});
@@ -55,29 +55,29 @@ fs.renameSync(`${contextDir}/gitignore`, `${contextDir}/.gitignore`);
 fs.renameSync(`${contextDir}/prettierrc`, `${contextDir}/.prettierrc`);
 fs.renameSync(`${contextDir}/.tsconfig.json`, `${contextDir}/tsconfig.json`);
 fs.renameSync(`${uiDir}/.tsconfig.json`, `${uiDir}/tsconfig.json`);
-fs.renameSync(`${apiDir}/.tsconfig.json`, `${apiDir}/tsconfig.json`);
+fs.renameSync(`${restDir}/.tsconfig.json`, `${restDir}/tsconfig.json`);
 
 // replace in files
 replaceInFiles.sync({
-	files: `./${contextDir}/**/*.{ts,tsx}`,
-	from: /\/\/.\@ts\-nocheck\n/gm,
+	files: [`${contextDir}/**/*`, `${contextDir}/.devcontainer/*`],
+	from: /\/\/.@ts-nocheck\n/gm,
 	to: '',
 });
 replaceInFiles.sync({
-	files: `./${contextDir}/**/*`,
+	files: [`${contextDir}/**/*`, `${contextDir}/.devcontainer/*`],
 	from: /\$\(appName\)/gm,
 	to: appName,
 });
 replaceInFiles.sync({
-	files: `./${contextDir}/**/*`,
+	files: [`${contextDir}/**/*`, `${contextDir}/.devcontainer/*`],
 	from: /\$\(AppName\)/gm,
 	to: appName.charAt(0).toUpperCase() + appName.slice(1),
 });
 replaceInFiles.sync({
-	files: `./${contextDir}/**/*`,
+	files: [`${contextDir}/**/*`, `${contextDir}/.devcontainer/*`],
 	from: /\$\(appPort\)/gm,
 	to: appPort,
 });
 
 // install deps
-execSync(`pnpm i`, { cwd: `./${contextDir}` })
+execSync(`pnpm i`, { cwd: `${contextDir}` });
diff --git a/package.json b/package.json
index 8f16713..04d6ea4 100644
--- a/package.json
+++ b/package.json
@@ -12,7 +12,6 @@
     "release": "pnpm version --no-git-tag-version"
   },
   "dependencies": {
-    "app": "link:app",
     "minimist": "1.2.8",
     "replace-in-file": "7.0.2"
   },
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 91cb4fd..dbd0a23 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -5,9 +5,6 @@ settings:
   excludeLinksFromLockfile: false
 
 dependencies:
-  app:
-    specifier: link:app
-    version: link:app
   minimist:
     specifier: 1.2.8
     version: 1.2.8
diff --git a/source/common/.devcontainer/Dockerfile b/source/common/.devcontainer/Dockerfile
new file mode 100644
index 0000000..33cb6b4
--- /dev/null
+++ b/source/common/.devcontainer/Dockerfile
@@ -0,0 +1 @@
+FROM local/nodejs/dev:18
\ No newline at end of file
diff --git a/source/common/.devcontainer/devcontainer.json b/source/common/.devcontainer/devcontainer.json
new file mode 100644
index 0000000..db3804d
--- /dev/null
+++ b/source/common/.devcontainer/devcontainer.json
@@ -0,0 +1,7 @@
+{
+	"name": "$(appName)",
+	"workspaceFolder": "/home/project/$(appName)",
+	"dockerComposeFile": "docker-compose.yml",
+	"service": "$(appName)",
+	"postCreateCommand": "sudo chown iamuser:iamuser -R /home/project",
+}
\ No newline at end of file
diff --git a/source/common/.devcontainer/docker-compose.yml b/source/common/.devcontainer/docker-compose.yml
new file mode 100644
index 0000000..f34d878
--- /dev/null
+++ b/source/common/.devcontainer/docker-compose.yml
@@ -0,0 +1,18 @@
+version: "3"
+
+name: $(appName)
+
+volumes:
+  node_modules:
+  pnpm-store:
+
+services:
+  seedling:
+    build:
+      context: .
+    container_name: $(appName)
+    volumes:
+      - ../:/home/project/$(appName)
+      - node_modules:/home/project/seedling/node_modules
+      - pnpm-store:/home/project/seedling/.pnpm-store
+    command: sleep infinity
\ No newline at end of file
diff --git a/source/common/.env b/source/common/.env
new file mode 100644
index 0000000..cccead9
--- /dev/null
+++ b/source/common/.env
@@ -0,0 +1 @@
+COMPOSE_PROJECT_NAME=$(appName)
\ No newline at end of file
diff --git a/source/ui/config/local/.env b/source/ui/config/tests/.env.ci
similarity index 100%
rename from source/ui/config/local/.env
rename to source/ui/config/tests/.env.ci
diff --git a/source/ui/config/prod/.env b/source/ui/config/tests/.env.local
similarity index 100%
rename from source/ui/config/prod/.env
rename to source/ui/config/tests/.env.local
diff --git a/source/ui/scripts/webpack-dev.js b/source/ui/scripts/webpack-dev.js
index 6797b2d..57098e0 100644
--- a/source/ui/scripts/webpack-dev.js
+++ b/source/ui/scripts/webpack-dev.js
@@ -1,7 +1,7 @@
 const { merge } = require('webpack-merge');
 
 const common = require('./webpack-common');
-const myEnv = require('dotenv').config({ path: 'config/local/.env' }).parsed;
+const myEnv = require('dotenv').config({ path: 'config/app/.env.local' }).parsed;
 
 module.exports = (env, args) => {
 	return merge(common(env, args, myEnv), {
diff --git a/source/ui/scripts/webpack-prod.js b/source/ui/scripts/webpack-prod.js
index f567085..a085800 100644
--- a/source/ui/scripts/webpack-prod.js
+++ b/source/ui/scripts/webpack-prod.js
@@ -1,6 +1,6 @@
 const { merge } = require('webpack-merge');
 
-const myEnv = require('dotenv').config({ path: 'config/prod/.env' }).parsed;
+const myEnv = require('dotenv').config({ path: 'config/app/.env.prod' }).parsed;
 const common = require('./webpack-common');
 
 // const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
diff --git a/source/ui/src/types/global.ts b/source/ui/src/types/global.ts
index e69de29..1538850 100644
--- a/source/ui/src/types/global.ts
+++ b/source/ui/src/types/global.ts
@@ -0,0 +1,13 @@
+declare global {
+	interface Window {
+		__REDUX_DEVTOOLS_EXTENSION_COMPOSE__: any;
+	}
+
+	namespace NodeJS {
+		interface ProcessEnv {
+			ENDPOINT_BASE_URL: string;
+		}
+	}
+}
+
+export default global;