diff --git a/debug-workspace/debug-dbg.lua b/debug-workspace/debug-dbg.lua
index 34ffd86..d227d9d 100644
--- a/debug-workspace/debug-dbg.lua
+++ b/debug-workspace/debug-dbg.lua
@@ -7,18 +7,33 @@ for i = -1,#arg,1 do
         print('arg['..i..'] = ' .. arg[i])
     end
 end
+
+local function co_type()
+    return coroutine.running() and type(coroutine.running()) or ''
+end
+
+local function co_status()
+    return coroutine.running() and coroutine.status(coroutine.running()) or nil
+end
+
 print('1.out:', fiber.id())
+print('1a.out', co_status())
+print('1b.out', co_type())
+
 local function fiber_function()
     print('1.in:', "I'm a fiber")
     print('2.in:', fiber.id())
+    print('2a.in', co_status())
+    print('2b.in', co_type())
     fiber.yield()
     fiber.sleep(10)
     print('3.in:')
 end
 print('2.out:', fiber.id())
 
-local fiber_object = fiber.create(fiber_function)
+local fiber_object = fiber.new(fiber_function)
 print('3.out:', "Fiber started")
+fiber.yield()
 
 local T = date.new{hour = 3, tzoffset = '+0300'}
 print('4.out:', T)
diff --git a/debugger/debugger.ts b/debugger/debugger.ts
index ceb14f4..aabf10b 100644
--- a/debugger/debugger.ts
+++ b/debugger/debugger.ts
@@ -37,12 +37,32 @@ import {Breakpoint} from "./breakpoint";
 import {Thread, mainThread, mainThreadName, isThread} from "./thread";
 
 import * as tarantool from "tarantool";
+import * as fiber from "fiber";
+import type {LuaFiber} from "fiber";
 
 // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
 const luaTarantoolGetSources = tarantool?.debug?.getsources ?? function(filePath: string) {
     return null;
 };
 
+const luaFiberCreate = fiber.create;
+const luaFiberNew = fiber.new;
+const luaFiberYield = fiber.yield;
+
+const luaFiberId = fiber.id
+const luaFiberStatus = fiber.status
+const luaCoroStatus = coroutine.status
+const luaCoroRunning = coroutine.running
+
+const mainFiberId = luaFiberId()
+
+// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
+export function isFiber(val: any): val is LuaFiber {
+    return val != null &&
+           type(val) === "userdata" &&
+           luaFiberId(val as LuaFiber) > 0;
+}
+
 export interface Var {
     val: unknown;
     type: string;
@@ -92,17 +112,22 @@ export namespace Debugger {
     const hookStack: HookType[] = [];
 
     const threadIds = setmetatable(new LuaTable<Thread, number | undefined>(), {__mode: "k"});
+    const fibers = setmetatable(new LuaTable<number, LuaFiber>(), {__mode: "kv"});
     const threadStackOffsets = setmetatable(new LuaTable<Thread, number | undefined>(), {__mode: "k"});
     const mainThreadId = 1;
     threadIds.set(mainThread, mainThreadId);
     let nextThreadId = mainThreadId + 1;
 
+    // calculate coroutine virtual id, or real fiber id
     function getThreadId(thread: Thread) {
-        return luaAssert(threadIds.get(thread));
+        const threadId = threadIds.get(thread);
+        const fiberId = luaFiberId();
+        luaAssert(threadId || fiberId > mainFiberId);
+        return (threadId || fiberId);
     }
 
     function getActiveThread() {
-        return coroutine.running() ?? mainThread;
+        return luaCoroRunning() ?? mainThread;
     }
 
     function getLine(info: debug.FunctionInfo) {
@@ -499,13 +524,14 @@ export namespace Debugger {
         breakInThread = undefined;
         let frameOffset = activeThreadFrameOffset;
         let frame = 0;
-        let currentThread = activeThread;
+        let currentThread: Thread | undefined = activeThread;
         let currentStack = activeStack;
         let info = luaAssert(currentStack[frame]);
         let source = Path.format(luaAssert(info.source));
         let sourceMap = SourceMap.get(source);
         while (true) {
             const inp = getInput();
+            print('**cmd**', inp);
             if (!inp || inp === "quit") {
                 os.exit(0);
 
@@ -878,14 +904,13 @@ export namespace Debugger {
             } else if (activeThread === breakInThread) {
                 stepBreak = getStack(debugHookStackOffset).length <= breakAtDepth;
             } else {
-                stepBreak = breakInThread !== mainThread && coroutine.status(breakInThread as LuaThread) === "dead";
+                stepBreak = breakInThread !== mainThread && luaCoroStatus(breakInThread as LuaThread) === "dead";
             }
             if (stepBreak) {
                 const topFrameSource = debug.getinfo(debugHookStackOffset, "S");
                 if (!topFrameSource || !topFrameSource.source) {
                     return;
                 }
-
                 //Ignore debugger code
                 if (topFrameSource.source.sub(-debuggerName.length) === debuggerName) {
                     return;
@@ -1040,6 +1065,24 @@ export namespace Debugger {
         return threadId;
     }
 
+    function registerFiber(fiber_: LuaFiber | null) {
+        if (fiber_ === null) {
+            return null;
+        }
+        const fiberId = fiber.id(fiber_);
+        assert(!fibers.get(fiberId));
+        assert(isFiber(fiber_));
+
+        fibers.set(fiberId, fiber_);
+
+        const [hook] = debug.gethook();
+        if (hook === debugHook) {
+            debug.sethook(debugHook, "l");
+        }
+
+        return fiberId;
+    }
+
     let canYieldAcrossPcall: boolean | undefined;
 
     function useXpcallInCoroutine() {
@@ -1106,6 +1149,45 @@ export namespace Debugger {
         return resumer;
     }
 
+    /**
+      fiber.create() is a fiber_create() + fiber_start()
+      fiber.new() is a fiber_create() + fiber_wakeup()
+      We need to intercept control at the moment
+      we create fiber via fiber.new() [for registering it
+      in debugger threads list], but we have not way in Lua
+      to directly start fiber execution as fiber_start() is
+      **not** exported to Lua. But, at least we could yield.
+
+      The order of fiber switches will be messed entirely.
+      But who guaranteed it anyhow, anywhere>
+     */
+    function debuggerFiberCreate(start : boolean)  {
+        return function(f: Function, ...args: unknown[] ): LuaFiber | null {
+            const originalFunc = f as DebuggableFunction;
+            function debugFunc(...props: unknown[]) {
+                function wrappedFunc() {
+                    return originalFunc(...props);
+                }
+                const results = xpcall(wrappedFunc, breakForError);
+                if (results[0]) {
+                    return unpack(results, 2);
+                } else {
+                    skipNextBreak = true;
+                    const message = mapSources(tostring(results[1]));
+                    return luaError(message, 2);
+                }
+            }
+            const fiber_ = luaFiberNew(debugFunc, ...args);
+            // print(fiber_)
+            //print(type(fiber_))
+            registerFiber(fiber_);
+            if (start) {
+                luaFiberYield(); // FIXME - it messes up order or execution
+            }
+            return fiber_;
+        }
+    }
+
     //debug.traceback replacement for catching errors and mapping sources
     function debuggerTraceback(
         threadOrMessage?: LuaThread | string,
@@ -1165,17 +1247,19 @@ export namespace Debugger {
     updateHook = function() {
         if (breakAtDepth < 0 && Breakpoint.getCount() === 0) {
             debug.sethook();
+            print('clearHook (globally)');
 
             for (const [thread] of pairs(threadIds)) {
-                if (isThread(thread) && coroutine.status(thread) !== "dead") {
+                if (isThread(thread) && luaCoroStatus(thread) !== "dead") {
                     debug.sethook(thread);
                 }
             }
         } else {
             debug.sethook(debugHook, "l");
+            print('set debugHook (globally)');
 
             for (const [thread] of pairs(threadIds)) {
-                if (isThread(thread) && coroutine.status(thread) !== "dead") {
+                if (isThread(thread) && luaCoroStatus(thread) !== "dead") {
                     debug.sethook(thread, debugHook, "l");
                 }
             }
@@ -1192,11 +1276,16 @@ export namespace Debugger {
         coroutine.create = luaCoroutineCreate;
         coroutine.wrap = luaCoroutineWrap;
         coroutine.resume = luaCoroutineResume;
+        // FIXME - don't repeat after us! That is bad, really bad!
+        //@ts-ignore
+        fiber.create = luaFiberCreate;
+        //@ts-ignore
+        fiber.new = luaFiberNew;
 
         debug.sethook();
 
         for (const [thread] of pairs(threadIds)) {
-            if (isThread(thread) && coroutine.status(thread) !== "dead") {
+            if (isThread(thread) && luaCoroStatus(thread) !== "dead") {
                 debug.sethook(thread);
             }
         }
@@ -1218,9 +1307,18 @@ export namespace Debugger {
         coroutine.create = (f: Function) => debuggerCoroutineCreate(f, breakInCoroutines);
         coroutine.wrap = debuggerCoroutineWrap;
         coroutine.resume = breakInCoroutines ? debuggerCoroutineResume : luaCoroutineResume;
-
-        const currentThread = coroutine.running();
+        // FIXME - don't repeat after us! That is bad, really bad!
+        //@ts-ignore
+        fiber.create = debuggerFiberCreate(true);
+        //@ts-ignore
+        fiber.new = debuggerFiberCreate(false);
+
+        const currentThread = luaCoroRunning();
+        // when coroutine.running() returns non-null that migt mean 2 things:
+        // - either we are in a real couroutine
+        // - or within running fiber
         if (currentThread && !threadIds.get(currentThread)) {
+            print('register', currentThread);
             registerThread(currentThread);
         }
 
diff --git a/debugger/fiber.d.ts b/debugger/fiber.d.ts
new file mode 100644
index 0000000..bd09911
--- /dev/null
+++ b/debugger/fiber.d.ts
@@ -0,0 +1,14 @@
+declare module "fiber" {
+  interface LuaFiber extends LuaUserData {
+    id : number;
+  }
+
+  const new_: (this: void, f: Function, ...args: unknown[]) => LuaFiber | null;
+  const create: (this: void, f: Function, ...args: unknown[]) => LuaFiber | null;
+  const yield: (this: void) => void;
+  const id: (this: void, fib?: LuaFiber | null) => number;
+  const status: (this: void, fib?: LuaFiber | null) => "running" | "dead" | "suspended" | null;
+
+  export { new_ as new, create, yield, id, status };
+  export type { LuaFiber };
+}
diff --git a/debugger/tsconfig.json b/debugger/tsconfig.json
index 5239136..632a79b 100644
--- a/debugger/tsconfig.json
+++ b/debugger/tsconfig.json
@@ -22,6 +22,6 @@
         "luaBundle": "lldebugger.lua",
         "luaBundleEntry": "lldebugger.ts",
         "luaLibImport": "require",
-        "noResolvePaths": ["tarantool"]
+        "noResolvePaths": ["tarantool", "fiber"]
     }
 }