diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 83420f18283..e5411db2ce3 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -252,7 +252,7 @@ jobs:
 
     strategy:
       matrix:
-        node-version: [18.x]
+        node-version: [16.x]
 
     steps:
       - uses: actions/checkout@v3
@@ -261,7 +261,7 @@ jobs:
         with:
           node-version: ${{ matrix.node-version }}
       - name: Install dependencies
-        run: yarn install --frozen-lockfile --network-timeout 500000
+        run: yarn install --frozen-lockfile --ignore-engines --network-timeout 500000
       - name: Release packages
         env:
           CI: true
@@ -286,7 +286,7 @@ jobs:
         with:
           node-version: ${{ matrix.node-version }}
       - name: Install dependencies
-        run: yarn install --frozen-lockfile --network-timeout 500000
+        run: yarn install --frozen-lockfile --ignore-engines --network-timeout 500000
       - name: Build pages
         env:
           CI: true
diff --git a/docs/docs/snippets/configuration/bootstrap-with-node-config.ts b/docs/docs/snippets/configuration/bootstrap-with-node-config.ts
index 96ffe7e6846..93e1fd14b64 100644
--- a/docs/docs/snippets/configuration/bootstrap-with-node-config.ts
+++ b/docs/docs/snippets/configuration/bootstrap-with-node-config.ts
@@ -1,9 +1,13 @@
 import {$log} from "@tsed/common";
 import {PlatformExpress} from "@tsed/platform-express";
+import filedirname from "filedirname";
 import {Server} from "./server";
 
+// FIXME remove when esm is ready
+const [, rootDir] = filedirname();
+
 // /!\ configuration file must be outside of your src directory
-process.env["NODE_CONFIG_DIR"] = `${__dirname}/../config`;
+process.env["NODE_CONFIG_DIR"] = `${rootDir}/../config`;
 const config = require("config");
 
 async function bootstrap() {
diff --git a/docs/docs/snippets/controllers/observable-stream-buffer-controller.ts b/docs/docs/snippets/controllers/observable-stream-buffer-controller.ts
index 0e848a08233..93943d2e57d 100644
--- a/docs/docs/snippets/controllers/observable-stream-buffer-controller.ts
+++ b/docs/docs/snippets/controllers/observable-stream-buffer-controller.ts
@@ -1,9 +1,13 @@
 import {PlatformResponse, Res} from "@tsed/common";
-import {Get} from "@tsed/schema";
 import {Controller} from "@tsed/di";
+import {Get} from "@tsed/schema";
+import filedirname from "filedirname";
 import {createReadStream, ReadStream} from "fs";
 import {Observable, of} from "rxjs";
 
+// FIXME remove when esm is ready
+const [, rootDir] = filedirname();
+
 @Controller("/")
 export class KindOfResponseCtrl {
   @Get("/observable")
@@ -13,7 +17,7 @@ export class KindOfResponseCtrl {
 
   @Get("/stream")
   stream(): ReadStream {
-    return createReadStream(__dirname + "/response.txt");
+    return createReadStream(rootDir + "/response.txt");
   }
 
   @Get("/buffer")
diff --git a/package.json b/package.json
index 0fa1a45b1cd..3e253267f27 100644
--- a/package.json
+++ b/package.json
@@ -215,13 +215,15 @@
         "dir": "./docs/.vuepress/dist",
         "url": "https://github.com/tsedio/tsed",
         "branch": "gh-pages",
-        "cname": "tsed.io"
+        "cname": "tsed.io",
+        "if": "production"
       },
       {
         "dir": "./docs-references/.vuepress/dist",
         "url": "https://github.com/tsedio/api-docs.tsed.io.git",
         "branch": "main",
-        "cname": "api-docs.tsed.io"
+        "cname": "api-docs.tsed.io",
+        "if": "production"
       }
     ],
     "examples": {
diff --git a/packages/core/jest.config.js b/packages/core/jest.config.js
index 06252dcbefd..baab1dd225e 100644
--- a/packages/core/jest.config.js
+++ b/packages/core/jest.config.js
@@ -5,10 +5,10 @@ module.exports = {
   ...require("@tsed/jest-config"),
   coverageThreshold: {
     global: {
-      statements: 98.43,
-      branches: 90.67,
-      functions: 94.84,
-      lines: 98.68
+      statements: 98.85,
+      branches: 94.36,
+      functions: 95.63,
+      lines: 98.85
     }
   }
 };
diff --git a/packages/core/src/domain/AnyToPromise.spec.ts b/packages/core/src/domain/AnyToPromise.spec.ts
index 4b37f9b3311..3e5810899c7 100644
--- a/packages/core/src/domain/AnyToPromise.spec.ts
+++ b/packages/core/src/domain/AnyToPromise.spec.ts
@@ -1,9 +1,13 @@
+import filedirname from "filedirname";
 import {createReadStream} from "fs";
 import {of} from "rxjs";
 import {catchAsyncError} from "../utils/catchError";
 import {isStream} from "../utils/objects/isStream";
 import {AnyToPromise, AnyToPromiseStatus} from "./AnyToPromise";
 
+// FIXME remove when esm is ready
+const [, rootDir] = filedirname();
+
 describe("AnyToPromise", () => {
   it("should handle sync value", async () => {
     const resolver = new AnyToPromise();
@@ -98,7 +102,7 @@ describe("AnyToPromise", () => {
     const resolver = new AnyToPromise();
 
     const result = await resolver.call(() => {
-      return createReadStream(__dirname + "/__mock__/response.txt");
+      return createReadStream(rootDir + "/__mock__/response.txt");
     });
 
     expect(result.type).toBe("STREAM");
diff --git a/packages/di/jest.config.js b/packages/di/jest.config.js
index 183f6974aab..420f98a07b1 100644
--- a/packages/di/jest.config.js
+++ b/packages/di/jest.config.js
@@ -5,10 +5,10 @@ module.exports = {
   ...require("@tsed/jest-config"),
   coverageThreshold: {
     global: {
-      statements: 98.52,
-      branches: 92.95,
-      lines: 98.6,
-      functions: 98.11
+      statements: 98.62,
+      branches: 96.49,
+      lines: 98.62,
+      functions: 98.71
     }
   }
 };
diff --git a/packages/engines/package.json b/packages/engines/package.json
index 27da6b99e9a..2786846b423 100644
--- a/packages/engines/package.json
+++ b/packages/engines/package.json
@@ -23,7 +23,8 @@
   "private": false,
   "dependencies": {
     "fs-extra": "10.0.1",
-    "tslib": "2.5.0"
+    "tslib": "2.5.0",
+    "filedirname": "^2.7.0"
   },
   "devDependencies": {
     "@types/fs-extra": "^9.0.13",
diff --git a/packages/engines/src/components/VueEngine.ts b/packages/engines/src/components/VueEngine.ts
index d6fe96682f7..94c26f604c0 100644
--- a/packages/engines/src/components/VueEngine.ts
+++ b/packages/engines/src/components/VueEngine.ts
@@ -1,8 +1,11 @@
-import {Engine, EngineOptions, ViewEngineOptions} from "./Engine";
-import {ViewEngine} from "../decorators/viewEngine";
-import {getCachedEngine, importEngine} from "../utils/cache";
+import filedirname from "filedirname";
 import {join, resolve} from "path";
 import {promisify} from "util";
+import {ViewEngine} from "../decorators/viewEngine";
+import {getCachedEngine, importEngine} from "../utils/cache";
+import {Engine, EngineOptions} from "./Engine";
+// FIXME remove when esm is ready
+const [, rootDir] = filedirname();
 
 function requireFromString(src: string, filename: string) {
   const Module: any = module.constructor;
@@ -26,16 +29,6 @@ function hashCode(str: string) {
 export class VueEngine extends Engine {
   #renderToString: any;
 
-  async $onInit() {
-    await super.$onInit();
-    await importEngine("vue-pronto/lib/index", "pronto");
-    await importEngine("vueify");
-    await importEngine("vue-server-renderer");
-    const ssrRenderer = this.vueServerRenderer.createRenderer();
-
-    this.#renderToString = promisify(ssrRenderer.renderToString.bind(this));
-  }
-
   get pronto() {
     return getCachedEngine("pronto");
   }
@@ -48,8 +41,18 @@ export class VueEngine extends Engine {
     return getCachedEngine("vue-server-renderer");
   }
 
+  async $onInit() {
+    await super.$onInit();
+    await importEngine("vue-pronto/lib/index", "pronto");
+    await importEngine("vueify");
+    await importEngine("vue-server-renderer");
+    const ssrRenderer = this.vueServerRenderer.createRenderer();
+
+    this.#renderToString = promisify(ssrRenderer.renderToString.bind(this));
+  }
+
   protected $cacheOptions(template: string, options: EngineOptions, fromFile?: boolean): EngineOptions {
-    const fullPath = join(__dirname, `/${hashCode(template)}`);
+    const fullPath = join(rootDir, `/${hashCode(template)}`);
 
     if (!fromFile) {
       return {
@@ -63,7 +66,7 @@ export class VueEngine extends Engine {
 
   protected $compile(template: string, options: EngineOptions) {
     // make up a fake path
-    const fullPath = join(__dirname, `/${hashCode(template)}`);
+    const fullPath = join(rootDir, `/${hashCode(template)}`);
     const promise = this.getComponent(fullPath, template, options);
 
     return async (options: EngineOptions) => {
@@ -74,7 +77,7 @@ export class VueEngine extends Engine {
   protected async $compileFile(file: string, options: EngineOptions) {
     // prontoRenderer assume that the filepath is relative to a passed "rootpath"
     // and if you don't pass a rootpath it will try to find one
-    // based on its current __dirname
+    // based on its current rootDir
     // https://github.com/express-vue/vue-pronto/blob/c88e380fee8656bc3ed21c7d3adb2ef331be07d5/lib/utils/findPaths.js#L10-L18
     const fullPath = resolve(file);
     const rootPath = process.cwd();
diff --git a/packages/engines/src/utils/getEngines.spec.ts b/packages/engines/src/utils/getEngines.spec.ts
index 78a274bdfca..1beeb0b3c11 100644
--- a/packages/engines/src/utils/getEngines.spec.ts
+++ b/packages/engines/src/utils/getEngines.spec.ts
@@ -1,7 +1,11 @@
-import {join} from "path";
 import {expect} from "chai";
+import filedirname from "filedirname";
+import {join} from "path";
 import {getEngine, getEngines} from "./getEngines";
 
+// FIXME remove when esm is ready
+const [, rootDir] = filedirname();
+
 describe("getEngines", () => {
   describe("getEngine()", () => {
     describe("render file", () => {
@@ -10,7 +14,7 @@ describe("getEngines", () => {
 
         const result = await new Promise((resolve, reject) => {
           render(
-            join(__dirname, "../../test/fixtures/ejs/user.ejs"),
+            join(rootDir, "../../test/fixtures/ejs/user.ejs"),
             {
               user: {
                 name: "Tobi"
@@ -29,7 +33,7 @@ describe("getEngines", () => {
 
         const error: any = await new Promise((resolve) => {
           render(
-            join(__dirname, "../../test/fixtures/ejs/user2.ejs"),
+            join(rootDir, "../../test/fixtures/ejs/user2.ejs"),
             {
               user: {
                 name: "Tobi"
diff --git a/packages/engines/test/getEngineFixture.ts b/packages/engines/test/getEngineFixture.ts
index d4754774300..6a8dc29715f 100644
--- a/packages/engines/test/getEngineFixture.ts
+++ b/packages/engines/test/getEngineFixture.ts
@@ -1,10 +1,12 @@
-import {join} from "path";
-import {engines} from "../src/index";
+import filedirname from "filedirname";
 import fs from "fs";
 import sinon from "sinon";
+
 import {Engine} from "../src/components/Engine";
+import {engines} from "../src/index";
 
-const rootDir = join(__dirname);
+// FIXME remove when esm is ready
+const [, rootDir] = filedirname();
 
 interface EngineFixtureOptions {
   token: string | typeof Engine;
diff --git a/packages/engines/test/shared/dust.ts b/packages/engines/test/shared/dust.ts
index 568082cad3a..2ebdd687102 100644
--- a/packages/engines/test/shared/dust.ts
+++ b/packages/engines/test/shared/dust.ts
@@ -1,9 +1,13 @@
 import {engines, requires} from "../../src/index";
-import fs from "fs";
 import {expect} from "chai";
+import filedirname from "filedirname";
+import fs from "fs";
 import {join} from "path";
 
-const rootDir = join(__dirname, "..");
+// FIXME remove when esm is ready
+const [, dir] = filedirname();
+
+const rootDir = join(dir, "..");
 
 export function test(name: string) {
   const user = {name: "Tobi"};
diff --git a/packages/engines/test/shared/filters.ts b/packages/engines/test/shared/filters.ts
index e0a67ce5ca5..1d7a44e5f9a 100644
--- a/packages/engines/test/shared/filters.ts
+++ b/packages/engines/test/shared/filters.ts
@@ -1,9 +1,12 @@
 import {engines} from "../../src/index";
+import filedirname from "filedirname";
 import fs from "fs";
 import {expect} from "chai";
 import {join} from "path";
 
-const rootDir = join(__dirname, "..");
+// FIXME remove when esm is ready
+const [, dir] = filedirname();
+const rootDir = join(dir, "..");
 
 export function test(name: string) {
   const engine = engines.get(name)!;
diff --git a/packages/engines/test/shared/helpers.ts b/packages/engines/test/shared/helpers.ts
index b17e1dd7196..e3130d85390 100644
--- a/packages/engines/test/shared/helpers.ts
+++ b/packages/engines/test/shared/helpers.ts
@@ -1,12 +1,14 @@
 import {engines} from "../../src/index";
+import filedirname from "filedirname";
 import handlebars from "handlebars";
 import fs from "fs";
 import {expect} from "chai";
 import {join} from "path";
 
 const Sqrl = require("squirrelly");
-
-const rootDir = join(__dirname, "..");
+// FIXME remove when esm is ready
+const [, dir] = filedirname();
+const rootDir = join(dir, "..");
 
 const readFile = fs.readFile;
 const readFileSync = fs.readFileSync;
diff --git a/packages/engines/test/shared/includes.ts b/packages/engines/test/shared/includes.ts
index f487bfafb79..6220fa992d1 100644
--- a/packages/engines/test/shared/includes.ts
+++ b/packages/engines/test/shared/includes.ts
@@ -1,9 +1,12 @@
 import {engines} from "../../src/index";
+import filedirname from "filedirname";
 import fs from "fs";
 import {expect} from "chai";
 import {join} from "path";
 
-const rootDir = join(__dirname, "..");
+// FIXME remove when esm is ready
+const [, dir] = filedirname();
+const rootDir = join(dir, "..");
 
 export function test(name: string) {
   const engine = engines.get(name)!;
diff --git a/packages/engines/test/shared/index.ts b/packages/engines/test/shared/index.ts
index ab65a9c5316..819aa837abb 100644
--- a/packages/engines/test/shared/index.ts
+++ b/packages/engines/test/shared/index.ts
@@ -1,9 +1,12 @@
 import {engines, requires} from "../../src/index";
 import {expect} from "chai";
+import filedirname from "filedirname";
 import fs from "fs";
 import {join} from "path";
 
-const rootDir = join(__dirname, "..");
+// FIXME remove when esm is ready
+const [, dir] = filedirname();
+const rootDir = join(dir, "..");
 
 const readFile = fs.readFile;
 const readFileSync = fs.readFileSync;
diff --git a/packages/engines/test/shared/partials.ts b/packages/engines/test/shared/partials.ts
index e7296d891bb..6d94ae792a9 100644
--- a/packages/engines/test/shared/partials.ts
+++ b/packages/engines/test/shared/partials.ts
@@ -1,9 +1,12 @@
 import {engines} from "../../src/index";
+import filedirname from "filedirname";
 import {join} from "path";
 import fs from "fs";
 import {expect} from "chai";
 
-const rootDir = join(__dirname, "..");
+// FIXME remove when esm is ready
+const [, dir] = filedirname();
+const rootDir = join(dir, "..");
 
 const readFile = fs.readFile;
 const readFileSync = fs.readFileSync;
@@ -38,7 +41,7 @@ export function test(name: string) {
       });
       it("should support absolute path partial", async () => {
         const path = `${rootDir}/fixtures/${name}/partials.${name}`;
-        const locals = {user: user, partials: {partial: join(__dirname, "/../../test/fixtures/", name, "/user")}};
+        const locals = {user: user, partials: {partial: join(dir, "/../../test/fixtures/", name, "/user")}};
         const html = await engine.renderFile(path, locals);
         expect(html).to.equal("<p>Tobi</p>");
       });
diff --git a/packages/engines/test/shared/react.ts b/packages/engines/test/shared/react.ts
index 4f6327f36a1..fe20505e9e3 100644
--- a/packages/engines/test/shared/react.ts
+++ b/packages/engines/test/shared/react.ts
@@ -1,10 +1,13 @@
 import {engines} from "../../src/index";
 import {expect} from "chai";
+import filedirname from "filedirname";
 import fs from "fs";
 import sinon from "sinon";
 import {join} from "path";
 
-const rootDir = join(__dirname, "..");
+// FIXME remove when esm is ready
+const [, dir] = filedirname();
+const rootDir = join(dir, "..");
 const sandbox = sinon.createSandbox();
 
 const readFile = fs.readFile;
diff --git a/packages/graphql/typegraphql/test/app/Server.ts b/packages/graphql/typegraphql/test/app/Server.ts
index 6b1f6f7a1ea..41b99d2a9e1 100644
--- a/packages/graphql/typegraphql/test/app/Server.ts
+++ b/packages/graphql/typegraphql/test/app/Server.ts
@@ -2,6 +2,7 @@ import "@tsed/ajv";
 import {Configuration, Constant, Inject, PlatformApplication} from "@tsed/common";
 import "@tsed/typegraphql";
 import "@tsed/passport";
+import filedirname from "filedirname";
 import {resolve} from "path";
 import {User} from "./graphql/auth/User";
 import {HelloController} from "./controllers/HelloController";
@@ -11,7 +12,8 @@ import "./graphql/index";
 import "./services/RecipeService";
 import "./services/UsersRepository";
 
-const rootDir = resolve(__dirname);
+// FIXME remove when esm is ready
+const [, rootDir] = filedirname();
 
 @Configuration({
   rootDir,
@@ -28,7 +30,7 @@ const rootDir = resolve(__dirname);
     default: {
       path: "/api/graphql",
       buildSchemaOptions: {
-        emitSchemaFile: resolve(__dirname, "../resources/schema.gql")
+        emitSchemaFile: resolve(rootDir, "../resources/schema.gql")
       },
       serverConfig: {
         context({req, res}: any) {
diff --git a/packages/orm/mikro-orm/test/helpers/Server.ts b/packages/orm/mikro-orm/test/helpers/Server.ts
index 02d4b321b12..350d65a6f3d 100644
--- a/packages/orm/mikro-orm/test/helpers/Server.ts
+++ b/packages/orm/mikro-orm/test/helpers/Server.ts
@@ -1,14 +1,15 @@
-import {Configuration, Inject} from "@tsed/di";
 import {PlatformApplication} from "@tsed/common";
-import {resolve} from "path";
+import {Configuration, Inject} from "@tsed/di";
 import "@tsed/platform-express";
-
-import cookieParser from "cookie-parser";
 import bodyParser from "body-parser";
 import compress from "compression";
+
+import cookieParser from "cookie-parser";
+import filedirname from "filedirname";
 import methodOverride from "method-override";
 
-const rootDir = resolve(__dirname);
+// FIXME remove when esm is ready
+const [, rootDir] = filedirname();
 
 @Configuration({
   rootDir,
diff --git a/packages/orm/mongoose/test/helpers/Server.ts b/packages/orm/mongoose/test/helpers/Server.ts
index 9f5f753ba74..f9937d4cf3a 100644
--- a/packages/orm/mongoose/test/helpers/Server.ts
+++ b/packages/orm/mongoose/test/helpers/Server.ts
@@ -1,13 +1,14 @@
 import {Configuration, Inject, PlatformApplication} from "@tsed/common";
 import "@tsed/mongoose";
 import "@tsed/platform-express";
-import Path from "path";
-import cookieParser from "cookie-parser";
 import bodyParser from "body-parser";
 import compress from "compression";
+import cookieParser from "cookie-parser";
+import filedirname from "filedirname";
 import methodOverride from "method-override";
 
-const rootDir = Path.resolve(__dirname);
+// FIXME remove when esm is ready
+const [, rootDir] = filedirname();
 
 @Configuration({
   rootDir,
diff --git a/packages/orm/objection/test/helpers/Server.ts b/packages/orm/objection/test/helpers/Server.ts
index a60e4add43d..e93b6d968f0 100644
--- a/packages/orm/objection/test/helpers/Server.ts
+++ b/packages/orm/objection/test/helpers/Server.ts
@@ -1,14 +1,15 @@
 import {Configuration, Inject, PlatformApplication} from "@tsed/common";
-import Path from "path";
-import "@tsed/platform-express";
 import "@tsed/objection";
-
-import cookieParser from "cookie-parser";
+import "@tsed/platform-express";
 import bodyParser from "body-parser";
 import compress from "compression";
+
+import cookieParser from "cookie-parser";
+import filedirname from "filedirname";
 import methodOverride from "method-override";
 
-const rootDir = Path.resolve(__dirname);
+// FIXME remove when esm is ready
+const [, rootDir] = filedirname();
 
 @Configuration({
   rootDir,
diff --git a/packages/orm/objection/test/integration.spec.ts b/packages/orm/objection/test/integration.spec.ts
index 67d65d6a3aa..5c516376466 100644
--- a/packages/orm/objection/test/integration.spec.ts
+++ b/packages/orm/objection/test/integration.spec.ts
@@ -1,9 +1,13 @@
 import {PlatformTest} from "@tsed/common";
+import filedirname from "filedirname";
 import {Knex} from "knex";
 import {serialize} from "@tsed/json-mapper";
 import {OBJECTION_CONNECTION} from "@tsed/objection";
 import {User} from "./helpers/models/User";
 
+// FIXME remove when esm is ready
+const [, rootDir] = filedirname();
+
 describe("Objection integrations", () => {
   beforeAll(() => {
     PlatformTest.create({
@@ -11,10 +15,10 @@ describe("Objection integrations", () => {
         client: "sqlite3",
         connection: ":memory:",
         migrations: {
-          directory: `${__dirname}/helpers/migrations`
+          directory: `${rootDir}/helpers/migrations`
         },
         seeds: {
-          directory: `${__dirname}/helpers/seeds`
+          directory: `${rootDir}/helpers/seeds`
         }
       }
     });
diff --git a/packages/orm/prisma/src/__mock__/createProjectFixture.ts b/packages/orm/prisma/src/__mock__/createProjectFixture.ts
index 5f147d3f7dc..2cec0022851 100644
--- a/packages/orm/prisma/src/__mock__/createProjectFixture.ts
+++ b/packages/orm/prisma/src/__mock__/createProjectFixture.ts
@@ -1,7 +1,11 @@
+import filedirname from "filedirname";
 import {join} from "path";
 import {ModuleKind, Project, ScriptTarget} from "ts-morph";
 
-const SNAPSHOT_DIR = `${__dirname}/../../test/snapshots`;
+// FIXME remove when esm is ready
+const [, rootDir] = filedirname();
+
+const SNAPSHOT_DIR = `${rootDir}/../../test/snapshots`;
 
 export function createProjectFixture(dir = "/") {
   const baseDir = join(SNAPSHOT_DIR, dir);
diff --git a/packages/orm/prisma/src/cli/prismaGenerator.ts b/packages/orm/prisma/src/cli/prismaGenerator.ts
index 43c5b145956..cd6a98c3347 100644
--- a/packages/orm/prisma/src/cli/prismaGenerator.ts
+++ b/packages/orm/prisma/src/cli/prismaGenerator.ts
@@ -1,12 +1,15 @@
 import {GeneratorOptions} from "@prisma/generator-helper";
 import {parseEnvValue} from "@prisma/internals";
+import filedirname from "filedirname";
 import fs from "fs-extra";
 import {generateCode} from "../generator/generateCode";
 import removeDir from "../generator/utils/removeDir";
 import path, {join} from "path";
 
-export const defaultOutput = join(__dirname, "..", ".schema");
-export const packageDir = join(__dirname, "..", "..", "..");
+// FIXME remove when esm is ready
+const [, rootDir] = filedirname();
+export const defaultOutput = join(rootDir, "..", ".schema");
+export const packageDir = join(rootDir, "..", "..", "..");
 
 function parseStringBoolean(stringBoolean: string | undefined) {
   return Boolean(stringBoolean ? stringBoolean === "true" : undefined);
diff --git a/packages/orm/typeorm/test/helpers/Server.ts b/packages/orm/typeorm/test/helpers/Server.ts
index 0cb49c52ac1..88c68bcd2f9 100644
--- a/packages/orm/typeorm/test/helpers/Server.ts
+++ b/packages/orm/typeorm/test/helpers/Server.ts
@@ -1,14 +1,15 @@
 import {Configuration, Inject, PlatformApplication} from "@tsed/common";
-import Path from "path";
 import "@tsed/platform-express";
 import "@tsed/typeorm";
-import "./connections/ConnectionProvider";
-import cookieParser from "cookie-parser";
 import bodyParser from "body-parser";
 import compress from "compression";
+import cookieParser from "cookie-parser";
+import filedirname from "filedirname";
 import methodOverride from "method-override";
+import "./connections/ConnectionProvider";
 
-const rootDir = Path.resolve(__dirname);
+// FIXME remove when esm is ready
+const [, rootDir] = filedirname();
 
 @Configuration({
   rootDir,
diff --git a/packages/platform/common/jest.config.js b/packages/platform/common/jest.config.js
index ab882c06166..2708d93d589 100644
--- a/packages/platform/common/jest.config.js
+++ b/packages/platform/common/jest.config.js
@@ -9,10 +9,10 @@ module.exports = {
   },
   coverageThreshold: {
     global: {
-      statements: 92.25,
-      branches: 77.65,
-      functions: 88.81,
-      lines: 92.24
+      statements: 98.05,
+      branches: 90.32,
+      functions: 97.08,
+      lines: 98.05
     }
   }
 };
diff --git a/packages/platform/common/src/builder/PlatformBuilder.ts b/packages/platform/common/src/builder/PlatformBuilder.ts
index c396024c1a7..689673263d3 100644
--- a/packages/platform/common/src/builder/PlatformBuilder.ts
+++ b/packages/platform/common/src/builder/PlatformBuilder.ts
@@ -81,7 +81,6 @@ export class PlatformBuilder<App = TsED.Application> {
    *
    * ```typescript
    * @Configuration({
-   *    rootDir: Path.resolve(__dirname),
    *    port: 8000,
    *    httpsPort: 8080,
    *    mount: {
diff --git a/packages/platform/common/src/services/PlatformHandler.spec.ts b/packages/platform/common/src/services/PlatformHandler.spec.ts
index 632e812a38d..235b9633c02 100644
--- a/packages/platform/common/src/services/PlatformHandler.spec.ts
+++ b/packages/platform/common/src/services/PlatformHandler.spec.ts
@@ -2,11 +2,15 @@ import {catchAsyncError} from "@tsed/core";
 import {Injectable} from "@tsed/di";
 import {PlatformHandlerMetadata, PlatformHandlerType} from "@tsed/platform-router";
 import {EndpointMetadata, Get, View} from "@tsed/schema";
+import filedirname from "filedirname";
 import {createReadStream} from "fs";
 import {join} from "path";
 import {PlatformHandler} from "./PlatformHandler";
 import {PlatformTest} from "./PlatformTest";
 
+// FIXME remove when esm is ready
+const [, rootDir] = filedirname();
+
 function getServiceFixture() {
   const service = PlatformTest.get<PlatformHandler>(PlatformHandler);
   return {service};
@@ -128,7 +132,7 @@ describe("PlatformHandler", () => {
 
       const $ctx = PlatformTest.createRequestContext();
       $ctx.next = jest.fn();
-      $ctx.data = createReadStream(join(__dirname, "__mock__/data.txt"));
+      $ctx.data = createReadStream(join(rootDir, "__mock__/data.txt"));
 
       await service.next($ctx);
 
@@ -277,7 +281,7 @@ describe("PlatformHandler", () => {
       }
 
       const {service} = getServiceFixture();
-      const data = createReadStream(join(__dirname, "__mock__/data.txt"));
+      const data = createReadStream(join(rootDir, "__mock__/data.txt"));
       const handler = jest.fn().mockResolvedValue(data);
 
       const $ctx = PlatformTest.createRequestContext();
diff --git a/packages/platform/common/src/services/PlatformResponse.spec.ts b/packages/platform/common/src/services/PlatformResponse.spec.ts
index 8b47657fb04..aea0e2ff15f 100644
--- a/packages/platform/common/src/services/PlatformResponse.spec.ts
+++ b/packages/platform/common/src/services/PlatformResponse.spec.ts
@@ -1,8 +1,12 @@
 import {PlatformViews} from "@tsed/platform-views";
+import filedirname from "filedirname";
 import {createReadStream} from "fs";
 import {PlatformResponse} from "./PlatformResponse";
 import {PlatformTest} from "./PlatformTest";
 
+// FIXME remove when esm is ready
+const [, rootDir] = filedirname();
+
 jest.mock("on-finished");
 
 function createResponse() {
@@ -148,7 +152,7 @@ describe("PlatformResponse", () => {
     });
     it("should call body with stream", () => {
       const {res, response} = createResponse();
-      const stream = createReadStream(__dirname + "/__mock__/data.txt");
+      const stream = createReadStream(rootDir + "/__mock__/data.txt");
       jest.spyOn(stream, "pipe").mockReturnValue(undefined as any);
 
       response.body(stream);
diff --git a/packages/platform/common/test/integration/platform.spec.ts b/packages/platform/common/test/integration/platform.spec.ts
index 23f557c79fb..4b914f66118 100644
--- a/packages/platform/common/test/integration/platform.spec.ts
+++ b/packages/platform/common/test/integration/platform.spec.ts
@@ -5,9 +5,13 @@ import {PlatformTestSdk} from "@tsed/platform-test-sdk";
 import bodyParser from "body-parser";
 import compress from "compression";
 import cookieParser from "cookie-parser";
+import filedirname from "filedirname";
 import methodOverride from "method-override";
 import SuperTest from "supertest";
 
+// FIXME remove when esm is ready
+const [, rootDir] = filedirname();
+
 @Controller("/hello")
 class TestHelloWorld {
   @Get("/")
@@ -29,7 +33,7 @@ class TestHelloWorld {
 export class Server {}
 
 const utils = PlatformTestSdk.create({
-  rootDir: __dirname,
+  rootDir,
   platform: PlatformExpress,
   server: Server,
   logger: {
diff --git a/packages/platform/platform-exceptions/src/domain/ExceptionSchema.spec.ts b/packages/platform/platform-exceptions/src/domain/ExceptionSchema.spec.ts
index d0b0dc925ff..aedfd3befdc 100644
--- a/packages/platform/platform-exceptions/src/domain/ExceptionSchema.spec.ts
+++ b/packages/platform/platform-exceptions/src/domain/ExceptionSchema.spec.ts
@@ -2,9 +2,13 @@ import SwaggerParser from "@apidevtools/swagger-parser";
 import {BadRequest, Exception} from "@tsed/exceptions";
 import {getJsonSchema, getSpec, OperationPath, Path, Returns, SpecTypes} from "@tsed/schema";
 import Ajv from "ajv";
+import filedirname from "filedirname";
 import {unlinkSync, writeJsonSync} from "fs-extra";
 import "./ExceptionSchema";
 
+// FIXME remove when esm is ready
+const [, rootDir] = filedirname();
+
 function getAjv() {
   return new Ajv({
     verbose: false,
@@ -13,7 +17,7 @@ function getAjv() {
 }
 
 const validateSpec = async (spec: any) => {
-  const file = __dirname + "/spec.json";
+  const file = rootDir + "/spec.json";
   spec = {
     ...spec
   };
diff --git a/packages/platform/platform-express/test/app/Server.ts b/packages/platform/platform-express/test/app/Server.ts
index 30a9e030207..27d90114b7f 100644
--- a/packages/platform/platform-express/test/app/Server.ts
+++ b/packages/platform/platform-express/test/app/Server.ts
@@ -4,9 +4,13 @@ import {Configuration, Inject} from "@tsed/di";
 import compress from "compression";
 import {Application} from "express";
 import session from "express-session";
+
+import filedirname from "filedirname";
 import "../../src/index";
 
-export const rootDir = __dirname;
+// FIXME remove when esm is ready
+const [, rootDir] = filedirname();
+export {rootDir};
 
 @Configuration({
   port: 8081,
diff --git a/packages/platform/platform-koa/test/app/Server.ts b/packages/platform/platform-koa/test/app/Server.ts
index ea46bb965e6..35a571ff886 100644
--- a/packages/platform/platform-koa/test/app/Server.ts
+++ b/packages/platform/platform-koa/test/app/Server.ts
@@ -1,10 +1,13 @@
 import "@tsed/ajv";
 import {PlatformApplication} from "@tsed/common";
 import {Configuration, Inject} from "@tsed/di";
+import filedirname from "filedirname";
 import Application from "koa";
 import session from "koa-session";
 
-export const rootDir = __dirname;
+// FIXME remove when esm is ready
+const [, rootDir] = filedirname();
+export {rootDir};
 
 @Configuration({
   port: 8083,
diff --git a/packages/platform/platform-test-sdk/src/tests/testMulter.ts b/packages/platform/platform-test-sdk/src/tests/testMulter.ts
index bd376966723..34e0c4969de 100644
--- a/packages/platform/platform-test-sdk/src/tests/testMulter.ts
+++ b/packages/platform/platform-test-sdk/src/tests/testMulter.ts
@@ -1,11 +1,15 @@
 import {BodyParams, Controller, MulterOptions, MultipartFile, PlatformMulterFile, PlatformTest} from "@tsed/common";
 import {CollectionOf, Post, Property, Required, Status} from "@tsed/schema";
+import filedirname from "filedirname";
 import multer, {FileFilterCallback} from "multer";
 import {dirname, join} from "path";
 import readPkgUp from "read-pkg-up";
 import SuperTest from "supertest";
 import {PlatformTestingSdkOpts} from "../interfaces";
 
+// FIXME remove when esm is ready
+const [, rootDir] = filedirname();
+
 export class Task {
   @Property()
   id: string;
@@ -33,7 +37,7 @@ function getFileConfig(): any {
   return {
     storage: multer.diskStorage({
       destination: (req: any, _fileItem, cb) => {
-        const path = `${__dirname}/../.tmp`;
+        const path = `${rootDir}/../.tmp`;
         cb(null, path);
       }
     }),
@@ -45,14 +49,14 @@ function getFileConfig(): any {
 export class TestMulterController {
   @Post("/scenario-1")
   @Status(201)
-  @MulterOptions({dest: `${__dirname}/../.tmp`})
+  @MulterOptions({dest: `${rootDir}/../.tmp`})
   uploadWithName(@Required() @MultipartFile("media") media: PlatformMulterFile) {
     return media.originalname;
   }
 
   @Post("/scenario-2")
   @Status(201)
-  @MulterOptions({dest: `${__dirname}/../.tmp`})
+  @MulterOptions({dest: `${rootDir}/../.tmp`})
   uploadWithPayload(@MultipartFile("media") media: PlatformMulterFile, @BodyParams("form_id") formId: string) {
     return {
       file: media.originalname,
diff --git a/packages/platform/platform-test-sdk/src/tests/testResponse.ts b/packages/platform/platform-test-sdk/src/tests/testResponse.ts
index 62d80f658ce..5e134861321 100644
--- a/packages/platform/platform-test-sdk/src/tests/testResponse.ts
+++ b/packages/platform/platform-test-sdk/src/tests/testResponse.ts
@@ -1,12 +1,15 @@
 import {Context, Controller, Get, getContext, PathParams, PlatformResponse, PlatformTest, Post, Res} from "@tsed/common";
 import {CollectionOf, ContentType, Enum, ForwardGroups, Groups, Ignore, Name, Property, Required, Returns, Status} from "@tsed/schema";
 import axios from "axios";
+import filedirname from "filedirname";
 import {createReadStream} from "fs";
 import {join} from "path";
 import {of} from "rxjs";
 import {agent, SuperAgentStatic} from "superagent";
 import SuperTest from "supertest";
 import {PlatformTestingSdkOpts} from "../interfaces";
+// FIXME remove when esm is ready
+const [, rootDir] = filedirname();
 
 class Base {
   @Ignore()
@@ -131,13 +134,13 @@ class TestResponseParamsCtrl {
   @Get("/scenario7")
   @ContentType("application/json")
   testScenario7Stream() {
-    return createReadStream(join(__dirname, "../data/response.data.json"));
+    return createReadStream(join(rootDir, "../data/response.data.json"));
   }
 
   @Get("/scenario7b")
   @ContentType("application/json")
   async testScenario7bStream() {
-    return createReadStream(join(__dirname, "../data/response.data.json"));
+    return createReadStream(join(rootDir, "../data/response.data.json"));
   }
 
   @Get("/scenario9/static")
diff --git a/packages/security/jwks/src/getJwks.spec.ts b/packages/security/jwks/src/getJwks.spec.ts
index 2c132f6e3af..ea41c55e97b 100644
--- a/packages/security/jwks/src/getJwks.spec.ts
+++ b/packages/security/jwks/src/getJwks.spec.ts
@@ -1,8 +1,11 @@
+import filedirname from "filedirname";
 import {removeSync} from "fs-extra";
 import {join} from "path";
 import {generateJwks, getJwks} from "./getJwks";
 
-const rootDir = join(__dirname, "__mocks__");
+// FIXME remove when esm is ready
+const [, dir] = filedirname();
+const rootDir = join(dir, "__mocks__");
 
 describe("GetJwks", () => {
   beforeEach(() => {
diff --git a/packages/security/oidc-provider/test/app/Server.ts b/packages/security/oidc-provider/test/app/Server.ts
index b936377842b..3100fa47b12 100644
--- a/packages/security/oidc-provider/test/app/Server.ts
+++ b/packages/security/oidc-provider/test/app/Server.ts
@@ -9,11 +9,14 @@ import bodyParser from "body-parser";
 import compress from "compression";
 import cookieParser from "cookie-parser";
 import session from "express-session";
+import filedirname from "filedirname";
 import methodOverride from "method-override";
 import {join} from "path";
 import {Accounts} from "./services/Accounts";
 
-export const rootDir = __dirname;
+// FIXME remove when esm is ready
+const [, rootDir] = filedirname();
+export {rootDir};
 
 @Configuration({
   port: 8081,
@@ -26,7 +29,7 @@ export const rootDir = __dirname;
   },
   oidc: {
     Accounts: Accounts,
-    jwksPath: join(__dirname, "..", "..", "keys", "jwks.json"),
+    jwksPath: join(rootDir, "..", "..", "keys", "jwks.json"),
     clients: [
       {
         client_id: "client_id",
diff --git a/packages/security/oidc-provider/test/oidc.integration.spec.ts b/packages/security/oidc-provider/test/oidc.integration.spec.ts
index 95e55109d01..c8e68df25f0 100644
--- a/packages/security/oidc-provider/test/oidc.integration.spec.ts
+++ b/packages/security/oidc-provider/test/oidc.integration.spec.ts
@@ -2,6 +2,7 @@ import {MemoryAdapter} from "@tsed/adapters";
 import {PlatformTest} from "@tsed/common";
 import {PlatformExpress} from "@tsed/platform-express";
 import {PlatformTestSdk} from "@tsed/platform-test-sdk";
+import filedirname from "filedirname";
 import SuperTest from "supertest";
 import {rootDir} from "../../../platform/platform-express/test/app/Server";
 import {InteractionsCtrl} from "./app/controllers/oidc/InteractionsCtrl";
@@ -10,6 +11,9 @@ import {Server} from "./app/Server";
 import {join} from "path";
 import {Accounts} from "./app/services/Accounts";
 
+// FIXME remove when esm is ready
+const [, testDir] = filedirname();
+
 const utils = PlatformTestSdk.create({
   rootDir,
   platform: PlatformExpress,
@@ -129,7 +133,7 @@ describe("OIDC on a different path", () => {
       oidc: {
         path: "/oidc",
         Accounts: Accounts,
-        jwksPath: join(__dirname, "..", "..", "keys", "jwks.json"),
+        jwksPath: join(testDir, "..", "..", "keys", "jwks.json"),
         clients: [
           {
             client_id: "client_id",
diff --git a/packages/security/passport/test/app/Server.ts b/packages/security/passport/test/app/Server.ts
index ca8c8dc4321..f1d69bd6933 100644
--- a/packages/security/passport/test/app/Server.ts
+++ b/packages/security/passport/test/app/Server.ts
@@ -6,6 +6,7 @@ import "@tsed/swagger";
 import bodyParser from "body-parser";
 import compress from "compression";
 import cookieParser from "cookie-parser";
+import filedirname from "filedirname";
 import methodOverride from "method-override";
 import Path from "path";
 import {AuthCtrl} from "./controllers/rest/auth/AuthCtrl";
@@ -13,14 +14,16 @@ import {Account} from "./models/Account";
 import "./protocols/LoginLocalProtocol";
 import session from "express-session";
 
-export const rootDir = Path.resolve(__dirname);
+// FIXME remove when esm is ready
+const [, rootDir] = filedirname();
+export {rootDir};
 
 @Configuration({
   rootDir,
   port: 8001,
   adapters: {
     Adapter: MemoryAdapter,
-    lowdbDir: `${__dirname}/../../.db`
+    lowdbDir: `${rootDir}/../../.db`
   },
   mount: {
     "/": [AuthCtrl]
diff --git a/packages/specs/json-mapper/jest.config.js b/packages/specs/json-mapper/jest.config.js
index 8a3887b7122..05f1f8ce4b8 100644
--- a/packages/specs/json-mapper/jest.config.js
+++ b/packages/specs/json-mapper/jest.config.js
@@ -7,7 +7,7 @@ module.exports = {
   coverageThreshold: {
     global: {
       statements: 99.89,
-      branches: 94.07,
+      branches: 97.89,
       functions: 100,
       lines: 99.89
     }
diff --git a/packages/specs/schema/jest.config.js b/packages/specs/schema/jest.config.js
index 7a62134d220..f13e4d8fdd4 100644
--- a/packages/specs/schema/jest.config.js
+++ b/packages/specs/schema/jest.config.js
@@ -6,10 +6,10 @@ module.exports = {
   roots: ["<rootDir>/src", "<rootDir>/test"],
   coverageThreshold: {
     global: {
-      statements: 98.85,
-      branches: 91.8,
-      functions: 99.59,
-      lines: 98.93
+      statements: 99.45,
+      branches: 96.13,
+      functions: 100,
+      lines: 99.45
     }
   },
   moduleNameMapper: {
diff --git a/packages/specs/schema/src/utils/generateSpec.spec.ts b/packages/specs/schema/src/utils/generateSpec.spec.ts
index 0b633a773c8..454ea839a50 100644
--- a/packages/specs/schema/src/utils/generateSpec.spec.ts
+++ b/packages/specs/schema/src/utils/generateSpec.spec.ts
@@ -13,6 +13,10 @@ import {Path} from "../decorators/operations/path";
 import {Returns} from "../decorators/operations/returns";
 import {SpecTypes} from "../domain/SpecTypes";
 import {generateSpec} from "./generateSpec";
+import filedirname from "filedirname";
+
+// FIXME remove when esm is ready
+const [, rootDir] = filedirname();
 
 describe("generateSpec()", () => {
   describe("OS 3.0.1", () => {
@@ -36,7 +40,7 @@ describe("generateSpec()", () => {
           {token: Controller2, rootPath: "/rest"}
         ],
         specVersion: "3.0.1",
-        specPath: join(__dirname, "__mock__", "spec.json")
+        specPath: join(rootDir, "__mock__", "spec.json")
       });
 
       expect(result).toEqual({
@@ -154,7 +158,7 @@ describe("generateSpec()", () => {
           {token: Controller1, rootPath: "/rest"},
           {token: Controller2, rootPath: "/rest"}
         ],
-        specPath: join(__dirname, "__mock__", "spec.json")
+        specPath: join(rootDir, "__mock__", "spec.json")
       });
 
       expect(result).toEqual({
diff --git a/packages/specs/schema/test/helpers/validateSpec.ts b/packages/specs/schema/test/helpers/validateSpec.ts
index 6d68e60fada..77d4613d5dd 100644
--- a/packages/specs/schema/test/helpers/validateSpec.ts
+++ b/packages/specs/schema/test/helpers/validateSpec.ts
@@ -1,10 +1,14 @@
 import SwaggerParser from "@apidevtools/swagger-parser";
+import filedirname from "filedirname";
 import {unlinkSync, writeJsonSync} from "fs-extra";
 import {SpecTypes} from "../../src/index";
 import {v4} from "uuid";
 
+// FIXME remove when esm is ready
+const [, rootDir] = filedirname();
+
 export const validateSpec = async (spec: any, version = SpecTypes.SWAGGER) => {
-  const file = `${__dirname}/spec-${v4()}.json`;
+  const file = `${rootDir}/spec-${v4()}.json`;
   spec = {
     ...spec
   };
diff --git a/packages/specs/swagger/package.json b/packages/specs/swagger/package.json
index 8530d027a22..5af8d7e7a1e 100644
--- a/packages/specs/swagger/package.json
+++ b/packages/specs/swagger/package.json
@@ -26,6 +26,7 @@
   "dependencies": {
     "@tsed/normalize-path": "7.18.2",
     "@tsed/openspec": "7.18.2",
+    "filedirname": "^2.7.0",
     "fs-extra": "10.0.1",
     "micromatch": "4.0.5",
     "swagger-ui-dist": "^4.5.2",
diff --git a/packages/specs/swagger/src/SwaggerModule.ts b/packages/specs/swagger/src/SwaggerModule.ts
index 8e58d753221..f41204cc2b7 100644
--- a/packages/specs/swagger/src/SwaggerModule.ts
+++ b/packages/specs/swagger/src/SwaggerModule.ts
@@ -14,6 +14,7 @@ import Fs from "fs";
 import {join} from "path";
 import {Env} from "@tsed/core";
 import {normalizePath} from "@tsed/normalize-path";
+import filedirname from "filedirname";
 import {absolutePath} from "swagger-ui-dist";
 import {SwaggerSettings} from "./interfaces/SwaggerSettings";
 import {cssMiddleware} from "./middlewares/cssMiddleware";
@@ -22,6 +23,9 @@ import {jsMiddleware} from "./middlewares/jsMiddleware";
 import {redirectMiddleware} from "./middlewares/redirectMiddleware";
 import {SwaggerService} from "./services/SwaggerService";
 
+// FIXME remove when esm is ready
+const [, rootDir] = filedirname();
+
 /**
  * @ignore
  */
@@ -123,7 +127,7 @@ export class SwaggerModule implements OnRoutesInit, OnReady {
    * @param urls
    */
   private createRouter(conf: SwaggerSettings, urls: string[]) {
-    const {disableSpec = false, fileName = "swagger.json", cssPath, jsPath, viewPath = join(__dirname, "../views/index.ejs")} = conf;
+    const {disableSpec = false, fileName = "swagger.json", cssPath, jsPath, viewPath = join(rootDir, "../views/index.ejs")} = conf;
     const router = new PlatformRouter(this.injector);
 
     if (!disableSpec) {
diff --git a/packages/specs/swagger/test/app/Server.ts b/packages/specs/swagger/test/app/Server.ts
index e0bb89ad9db..e3ff467ef3f 100644
--- a/packages/specs/swagger/test/app/Server.ts
+++ b/packages/specs/swagger/test/app/Server.ts
@@ -1,13 +1,14 @@
 import {Configuration, Inject, PlatformApplication} from "@tsed/common";
 import "@tsed/platform-express";
 import "@tsed/swagger";
-import Path from "path";
-import cookieParser from "cookie-parser";
 import bodyParser from "body-parser";
 import compress from "compression";
+import cookieParser from "cookie-parser";
+import filedirname from "filedirname";
 import methodOverride from "method-override";
 
-const rootDir = Path.resolve(__dirname);
+// FIXME remove when esm is ready
+const [, rootDir] = filedirname();
 
 @Configuration({
   rootDir,
diff --git a/packages/third-parties/agenda/test/helpers/Server.ts b/packages/third-parties/agenda/test/helpers/Server.ts
index f6f1d11b4e2..c113119a48b 100644
--- a/packages/third-parties/agenda/test/helpers/Server.ts
+++ b/packages/third-parties/agenda/test/helpers/Server.ts
@@ -1,4 +1,5 @@
 import {Configuration, Inject, PlatformApplication} from "@tsed/common";
+import filedirname from "filedirname";
 import Path from "path";
 import "@tsed/platform-express";
 import "@tsed/agenda";
@@ -7,7 +8,8 @@ import bodyParser from "body-parser";
 import compress from "compression";
 import methodOverride from "method-override";
 
-const rootDir = Path.resolve(__dirname);
+// FIXME remove when esm is ready
+const [, rootDir] = filedirname();
 
 @Configuration({
   rootDir,
diff --git a/packages/third-parties/components-scan/src/importFiles.spec.ts b/packages/third-parties/components-scan/src/importFiles.spec.ts
index bfa18c093da..de5287cc631 100644
--- a/packages/third-parties/components-scan/src/importFiles.spec.ts
+++ b/packages/third-parties/components-scan/src/importFiles.spec.ts
@@ -1,17 +1,21 @@
+import filedirname from "filedirname";
 import {join} from "path";
 import {importFiles} from "./importFiles";
 import {Test1} from "./__mock__/Test1";
 import {Test2} from "./__mock__/Test2";
 
+// FIXME remove when esm is ready
+const [, rootDir] = filedirname();
+
 describe("importFiles", () => {
   it("should import symbols", async () => {
-    const symbols = await importFiles([join(__dirname, "__mock__/*.ts")], []);
+    const symbols = await importFiles([join(rootDir, "__mock__/*.ts")], []);
 
     expect(symbols).toEqual(["value", Test1, "value", Test2]);
   });
 
   it("should import symbols without excluded files", async () => {
-    const symbols = await importFiles([join(__dirname, "__mock__/*.ts")], [join(__dirname, "__mock__/Test2.ts")]);
+    const symbols = await importFiles([join(rootDir, "__mock__/*.ts")], [join(rootDir, "__mock__/Test2.ts")]);
 
     expect(symbols).toEqual(["value", Test1]);
   });
diff --git a/packages/third-parties/components-scan/src/importProviders.spec.ts b/packages/third-parties/components-scan/src/importProviders.spec.ts
index 4eb76ba3670..890064afa07 100644
--- a/packages/third-parties/components-scan/src/importProviders.spec.ts
+++ b/packages/third-parties/components-scan/src/importProviders.spec.ts
@@ -1,14 +1,17 @@
 import {nameOf} from "@tsed/core";
 import {resolveControllers} from "@tsed/di";
+import filedirname from "filedirname";
 import {importProviders} from "./importProviders";
+// FIXME remove when esm is ready
+const [, rootDir] = filedirname();
 
 describe("importProviders", () => {
   it("should load providers and merge configuration", async () => {
     const configuration = {
       mount: {
-        "/rest": [`${__dirname}/__mock__/controllers/**/*.ts`]
+        "/rest": [`${rootDir}/__mock__/controllers/**/*.ts`]
       },
-      imports: [`${__dirname}/__mock__/**/Module*.ts`]
+      imports: [`${rootDir}/__mock__/**/Module*.ts`]
     };
 
     const result = await importProviders(configuration);
diff --git a/packages/third-parties/event-emitter/test/helpers/Server.ts b/packages/third-parties/event-emitter/test/helpers/Server.ts
index 9f0090e95c5..f524c6f21cb 100644
--- a/packages/third-parties/event-emitter/test/helpers/Server.ts
+++ b/packages/third-parties/event-emitter/test/helpers/Server.ts
@@ -1,4 +1,5 @@
 import {Configuration, Inject, PlatformApplication} from "@tsed/common";
+import filedirname from "filedirname";
 import Path from "path";
 import "@tsed/platform-express";
 import "../../src/EventEmitterModule";
@@ -8,7 +9,8 @@ import bodyParser from "body-parser";
 import compress from "compression";
 import methodOverride from "method-override";
 
-const rootDir = Path.resolve(__dirname);
+// FIXME remove when esm is ready
+const [, rootDir] = filedirname();
 
 @Configuration({
   rootDir,
diff --git a/packages/third-parties/formio/test/app/Server.ts b/packages/third-parties/formio/test/app/Server.ts
index 7c895e2ab98..8cf62e194bb 100644
--- a/packages/third-parties/formio/test/app/Server.ts
+++ b/packages/third-parties/formio/test/app/Server.ts
@@ -8,11 +8,14 @@ import bodyParser from "body-parser";
 import compress from "compression";
 import cookieParser from "cookie-parser";
 import session from "express-session";
+import filedirname from "filedirname";
 import methodOverride from "method-override";
 import "../../src";
 import template from "../template/project.json";
 
-export const rootDir = __dirname;
+// FIXME remove when esm is ready
+const [, rootDir] = filedirname();
+export {rootDir};
 
 @Configuration({
   port: 8083,
diff --git a/packages/third-parties/socketio/test/app/Server.ts b/packages/third-parties/socketio/test/app/Server.ts
index 672962743b7..653556c5c5d 100644
--- a/packages/third-parties/socketio/test/app/Server.ts
+++ b/packages/third-parties/socketio/test/app/Server.ts
@@ -5,11 +5,14 @@ import "@tsed/socketio";
 import bodyParser from "body-parser";
 import compress from "compression";
 import cookieParser from "cookie-parser";
+import filedirname from "filedirname";
 import methodOverride from "method-override";
-import {resolve} from "path";
 import {SocketPageCtrl} from "./controllers/pages/SocketPageCtrl";
 
-const rootDir = resolve(__dirname);
+// FIXME remove when esm is ready
+const [, rootDir] = filedirname();
+
+export {rootDir};
 
 @Configuration({
   rootDir,
diff --git a/packages/third-parties/stripe/test/app/Server.ts b/packages/third-parties/stripe/test/app/Server.ts
index 474d3a7ea5c..3fa8df78982 100644
--- a/packages/third-parties/stripe/test/app/Server.ts
+++ b/packages/third-parties/stripe/test/app/Server.ts
@@ -3,8 +3,11 @@ import "@tsed/ajv";
 import {Configuration} from "@tsed/di";
 import "@tsed/stripe";
 import "@tsed/swagger";
+import filedirname from "filedirname";
 
-export const rootDir = __dirname;
+// FIXME remove when esm is ready
+const [, rootDir] = filedirname();
+export {rootDir};
 
 @Configuration({
   port: 8081,
diff --git a/packages/third-parties/terminus/test/app/Server.ts b/packages/third-parties/terminus/test/app/Server.ts
index 798cc6374a1..f67e5a49c3f 100644
--- a/packages/third-parties/terminus/test/app/Server.ts
+++ b/packages/third-parties/terminus/test/app/Server.ts
@@ -7,8 +7,11 @@ import cookieParser from "cookie-parser";
 import {Application} from "express";
 import "./services/MongoClient";
 import "./services/RedisClient";
+import filedirname from "filedirname";
 
-export const rootDir = __dirname;
+// FIXME remove when esm is ready
+const [, rootDir] = filedirname();
+export {rootDir};
 
 @Configuration({
   port: 8081,
diff --git a/packages/third-parties/vite-ssr-plugin/src/middlewares/ViteRendererMiddleware.spec.ts b/packages/third-parties/vite-ssr-plugin/src/middlewares/ViteRendererMiddleware.spec.ts
index c61ce4040fc..0d752e51cbd 100644
--- a/packages/third-parties/vite-ssr-plugin/src/middlewares/ViteRendererMiddleware.spec.ts
+++ b/packages/third-parties/vite-ssr-plugin/src/middlewares/ViteRendererMiddleware.spec.ts
@@ -1,14 +1,18 @@
 import {PlatformTest} from "@tsed/common";
+import filedirname from "filedirname";
 
 import {ViteService} from "../services/ViteService";
 import {ViteRendererMiddleware} from "./ViteRendererMiddleware";
 
+// FIXME remove when esm is ready
+const [, rootDir] = filedirname();
+
 describe("ViteRenderMiddleware", () => {
   describe("use()", () => {
     beforeEach(() =>
       PlatformTest.create({
         vite: {
-          root: __dirname
+          root: rootDir
         }
       })
     );
diff --git a/yarn.lock b/yarn.lock
index 0a7a83fb450..aad016029dc 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -11730,6 +11730,13 @@ file-uri-to-path@1.0.0:
   resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd"
   integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==
 
+filedirname@^2.7.0:
+  version "2.7.0"
+  resolved "https://registry.yarnpkg.com/filedirname/-/filedirname-2.7.0.tgz#aff98ce95590b89de5b502d51885095c01b1f36e"
+  integrity sha512-rw4NZ0XCpm4EeBp0NK2b1WUkCm/LSDg6mJR8ywV2JYvIiwe+fimMgwVxjgd94lbmx4rOOmxybeVHsB6SRNeaXQ==
+  dependencies:
+    get-current-line "^6.5.0"
+
 filelist@^1.0.1:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/filelist/-/filelist-1.0.2.tgz#80202f21462d4d1c2e214119b1807c1bc0380e5b"
@@ -12375,6 +12382,11 @@ get-caller-file@^2.0.1, get-caller-file@^2.0.5:
   resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"
   integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
 
+get-current-line@^6.5.0:
+  version "6.6.0"
+  resolved "https://registry.yarnpkg.com/get-current-line/-/get-current-line-6.6.0.tgz#3b01ef83a1bc732e190755853516e13783d5ea93"
+  integrity sha512-9q/tqdL4+GMb0P28N/oSFruQE/8Sa1l9ew73AWS4j/KEMY32wD8+5QRB8LSTgt9HUZuLplmi8vc5dFFf5OvROA==
+
 get-func-name@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41"