diff --git a/src/lua/init.c b/src/lua/init.c
index 12600f80d2f5c2354d77d49b131aec1b47f0b300..5ffdaf86a9a395f1e15ebb167eca0ec0a6077d67 100644
--- a/src/lua/init.c
+++ b/src/lua/init.c
@@ -795,15 +795,7 @@ luaopen_tarantool(lua_State *L)
 	lua_pushstring(L, tarantool_version());
 	lua_setfield(L, LUA_GLOBALSINDEX, "_TARANTOOL");
 
-	/*
-	 * Get tarantool module.
-	 *
-	 * src/lua/init.lua is already registered as tarantool
-	 * module, so we `require` it here, not create.
-	 */
-	lua_getfield(L, LUA_GLOBALSINDEX, "require");
-	lua_pushstring(L, "tarantool");
-	lua_call(L, 1, 1);
+	luaT_newmodule(L, "tarantool", NULL);
 
 	/* package */
 	lua_pushstring(L, tarantool_package());
@@ -998,6 +990,7 @@ tarantool_lua_init(const char *tarantool_bin, const char *script, int argc,
 #if defined(ENABLE_BACKTRACE)
 	backtrace_lua_init();
 #endif /* defined(ENABLE_BACKTRACE) */
+	luaopen_tarantool(L);
 	for (const char **s = lua_modules; *s; s += 2) {
 		const char *modname = *s;
 		const char *modsrc = *(s + 1);
@@ -1018,9 +1011,6 @@ tarantool_lua_init(const char *tarantool_bin, const char *script, int argc,
 		builtin_modcache_put(modname, modsrc);
 	}
 	lua_pop(L, 1); /* _PRELOAD */
-
-	luaopen_tarantool(L);
-
 #ifdef NDEBUG
 	/* Unload strict after boot in release mode */
 	if (luaL_dostring(L, "require('strict').off()") != 0)
diff --git a/src/lua/init.lua b/src/lua/init.lua
index f42274a1e4d35d20f9bc31de02cbd68c84b32ab0..352e7a8c3778809ee0f175dde7f45587549cc29e 100644
--- a/src/lua/init.lua
+++ b/src/lua/init.lua
@@ -1,8 +1,8 @@
-
 -- init.lua -- internal file
 
 local ffi = require('ffi')
 local loaders = require('internal.loaders')
+local tarantool = require('tarantool')
 
 ffi.cdef[[
 struct method_info;
@@ -211,7 +211,7 @@ local mt = {
     __serialize = filter_out_private_fields,
 }
 
-return setmetatable({
+local tarantool_lua = {
     uptime = uptime,
     pid = pid,
     _internal = {
@@ -219,4 +219,9 @@ return setmetatable({
         module_name_from_filename = module_name_from_filename,
         run_preload = run_preload,
     },
-}, mt)
+}
+-- tarantool module is already registered by src/lua/init.c
+for k, v in pairs(tarantool_lua) do
+    tarantool[k] = v
+end
+return setmetatable(tarantool, mt)
diff --git a/src/lua/utils.c b/src/lua/utils.c
index ad6fe278494206d8eadba8df44a934f4c5f54e8e..66d24bc1cbb95bdeb29856887a89bab1ee009284 100644
--- a/src/lua/utils.c
+++ b/src/lua/utils.c
@@ -406,7 +406,7 @@ luaT_newmodule(struct lua_State *L, const char *modname,
 	       const struct luaL_Reg *funcs)
 {
 	say_debug("%s(%s)", __func__, modname);
-	assert(modname != NULL && funcs != NULL);
+	assert(modname != NULL);
 
 	/* Get loaders.builtin. */
 	lua_getfield(L, LUA_REGISTRYINDEX, "_TARANTOOL_BUILTIN");
@@ -422,7 +422,8 @@ luaT_newmodule(struct lua_State *L, const char *modname,
 	lua_newtable(L);
 
 	/* Fill the module table with functions. */
-	luaL_setfuncs(L, funcs, 0);
+	if (funcs != NULL)
+		luaL_setfuncs(L, funcs, 0);
 
 	/* Copy the module table. */
 	lua_pushvalue(L, -1);