diff --git a/src/box/lua/call.c b/src/box/lua/call.c
index 4ae531dad2e3ee6a6e2188a74d4d825eafb97495..a2d7b9e3a2cccb332133f162db1751a4b39814ad 100644
--- a/src/box/lua/call.c
+++ b/src/box/lua/call.c
@@ -1145,7 +1145,8 @@ box_lua_call_init(struct lua_State *L)
 	trigger_add(&luaL_msgpack_default->on_update,
 		    &call_serializer_no_error_ext.update_trigger);
 
-	luaL_register(L, "box.internal", boxlib_internal);
+	luaL_findtable(L, LUA_GLOBALSINDEX, "box.internal", 0);
+	luaL_setfuncs(L, boxlib_internal, 0);
 	lua_pop(L, 1);
 	/*
 	 * Register the trigger that will push persistent
diff --git a/src/box/lua/cfg.cc b/src/box/lua/cfg.cc
index 947a3a6a78bfe4857cf841b883db0368357b2c6e..38ed523915ef38561e23b305ea3aa5ad995dde3b 100644
--- a/src/box/lua/cfg.cc
+++ b/src/box/lua/cfg.cc
@@ -483,6 +483,7 @@ box_lua_cfg_init(struct lua_State *L)
 		{NULL, NULL}
 	};
 
-	luaL_register(L, "box.internal", cfglib_internal);
+	luaL_findtable(L, LUA_GLOBALSINDEX, "box.internal", 0);
+	luaL_setfuncs(L, cfglib_internal, 0);
 	lua_pop(L, 1);
 }
diff --git a/src/box/lua/console.c b/src/box/lua/console.c
index 6bc9067b0b7709a1c37d7eeec2c27d47e540a843..0facfb09ced99602a54b8ba96b06f5da7b3f6d83 100644
--- a/src/box/lua/console.c
+++ b/src/box/lua/console.c
@@ -886,7 +886,7 @@ tarantool_lua_console_init(struct lua_State *L)
 		{"run_on_eval",		lbox_console_run_on_eval},
 		{NULL, NULL}
 	};
-	luaL_register_module(L, "console", consolelib);
+	luaT_newmodule(L, "console", consolelib);
 
 	/* readline() func needs a ref to completion_handler (in upvalue) */
 	lua_getfield(L, -1, "completion_handler");
diff --git a/src/box/lua/console.lua b/src/box/lua/console.lua
index be1e8d2d3b073f7e2d6025914d70736a92f3ec89..403ceaea85ef798d37f264ac7a75e967a57c0d28 100644
--- a/src/box/lua/console.lua
+++ b/src/box/lua/console.lua
@@ -18,7 +18,7 @@ ffi.cdef[[
 ]]
 
 local internal = require('console')
-local session_internal = require('box.internal.session')
+local session_internal = box.internal.session
 local fiber = require('fiber')
 local socket = require('socket')
 local log = require('log')
@@ -26,7 +26,6 @@ local errno = require('errno')
 local urilib = require('uri')
 local yaml = require('yaml')
 local net_box = require('net.box')
-local box_internal = require('box.internal')
 local help = require('help').help
 
 local DEFAULT_CONNECT_TIMEOUT = 10
@@ -199,7 +198,7 @@ local function current_output()
 end
 
 -- Used by console_session_push.
-box_internal.format_lua_push = function(value)
+box.internal.format_lua_push = function(value)
     local internal_opts = gen_lua_opts(current_output()["opts"])
     value = format_lua_value(true, internal_opts, value)
     return '-- Push\n' .. value .. ';'
diff --git a/src/box/lua/ctl.c b/src/box/lua/ctl.c
index 40d5ae4f28eeecd282391a6cb4c7d88061015b00..ad075fc7baa67f32ebf2af92afb42f5d2038e979 100644
--- a/src/box/lua/ctl.c
+++ b/src/box/lua/ctl.c
@@ -166,6 +166,7 @@ static const struct luaL_Reg lbox_ctl_lib[] = {
 void
 box_lua_ctl_init(struct lua_State *L)
 {
-	luaL_register_module(L, "box.ctl", lbox_ctl_lib);
+	luaL_findtable(L, LUA_GLOBALSINDEX, "box.ctl", 0);
+	luaL_setfuncs(L, lbox_ctl_lib, 0);
 	lua_pop(L, 1);
 }
diff --git a/src/box/lua/error.cc b/src/box/lua/error.cc
index 54ec28468c1627fa9e5dc355dfd759ab53cd9ee7..8e922e44666a9c577292b48af45504dbf4e1ed72 100644
--- a/src/box/lua/error.cc
+++ b/src/box/lua/error.cc
@@ -293,10 +293,7 @@ lbox_errinj_info(struct lua_State *L)
 
 void
 box_lua_error_init(struct lua_State *L) {
-	static const struct luaL_Reg errorlib[] = {
-		{NULL, NULL}
-	};
-	luaL_register_module(L, "box.error", errorlib);
+	luaL_findtable(L, LUA_GLOBALSINDEX, "box.error", 0);
 	for (int i = 0; i < box_error_code_MAX; i++) {
 		const char *name = box_error_codes[i].errstr;
 		if (strstr(name, "UNUSED") || strstr(name, "RESERVED"))
@@ -340,7 +337,7 @@ box_lua_error_init(struct lua_State *L) {
 		{"get", lbox_errinj_get},
 		{NULL, NULL}
 	};
-	/* box.error.injection is not set by register_module */
-	luaL_register_module(L, "box.error.injection", errinjlib);
+	luaL_findtable(L, LUA_GLOBALSINDEX, "box.error.injection", 0);
+	luaL_setfuncs(L, errinjlib, 0);
 	lua_pop(L, 1);
 }
diff --git a/src/box/lua/index.c b/src/box/lua/index.c
index 5c2351991a3f882360f9adb053d4ebcbc7d920ee..fcbc17ff3305290369f9f6ceaae9ddb45f36fe75 100644
--- a/src/box/lua/index.c
+++ b/src/box/lua/index.c
@@ -365,12 +365,8 @@ box_lua_index_init(struct lua_State *L)
 	CTID_STRUCT_ITERATOR_PTR = luaL_ctypeid(L, "struct iterator*");
 	assert(CTID_STRUCT_ITERATOR_PTR != 0);
 
-	static const struct luaL_Reg indexlib [] = {
-		{NULL, NULL}
-	};
-
 	/* box.index */
-	luaL_register_module(L, "box.index", indexlib);
+	luaL_findtable(L, LUA_GLOBALSINDEX, "box.index", 0);
 	box_index_init_iterator_types(L, -2);
 	lua_pop(L, 1);
 
@@ -393,6 +389,7 @@ box_lua_index_init(struct lua_State *L)
 		{NULL, NULL}
 	};
 
-	luaL_register(L, "box.internal", boxlib_internal);
+	luaL_findtable(L, LUA_GLOBALSINDEX, "box.internal", 0);
+	luaL_setfuncs(L, boxlib_internal, 0);
 	lua_pop(L, 1);
 }
diff --git a/src/box/lua/info.c b/src/box/lua/info.c
index b007081fa3e14a01919d6a6151ccdc6d05e0d284..0e08b3004f6d6f849ee4780e7edfb5233a336330 100644
--- a/src/box/lua/info.c
+++ b/src/box/lua/info.c
@@ -757,19 +757,14 @@ lbox_info_call(struct lua_State *L)
 void
 box_lua_info_init(struct lua_State *L)
 {
-	static const struct luaL_Reg infolib [] = {
-		{NULL, NULL}
-	};
-
-	luaL_register_module(L, "box.info", infolib);
-
+	luaL_findtable(L, LUA_GLOBALSINDEX, "box.info", 0);
 	lua_newtable(L);		/* metatable for info */
 
 	lua_pushstring(L, "__index");
 
 	lua_newtable(L); /* table for __index */
-	luaL_register(L, NULL, lbox_info_dynamic_meta);
-	luaL_register(L, NULL, lbox_info_dynamic_meta_v16);
+	luaL_setfuncs(L, lbox_info_dynamic_meta, 0);
+	luaL_setfuncs(L, lbox_info_dynamic_meta_v16, 0);
 	lua_pushcclosure(L, lbox_info_index, 1);
 	lua_settable(L, -3);
 
diff --git a/src/box/lua/init.c b/src/box/lua/init.c
index 750f004f786397e002bddda3be72090a4cd7bbdb..98960f219512afa610d0a00d2bb9c78079dac1d7 100644
--- a/src/box/lua/init.c
+++ b/src/box/lua/init.c
@@ -517,11 +517,16 @@ box_lua_init(struct lua_State *L)
 	CTID_STRUCT_TXN_SAVEPOINT_PTR = luaL_ctypeid(L,
 						     "struct txn_savepoint*");
 
-	/* Use luaL_register() to set _G.box */
-	luaL_register(L, "box", boxlib);
-	lua_pop(L, 1);
+	/*
+	 * Create a table and expose it as require('box') and
+	 * as _G.box.
+	 */
+	luaT_newmodule(L, "box", boxlib);
+	lua_setfield(L, LUA_GLOBALSINDEX, "box");
 
-	luaL_register(L, "box.backup", boxlib_backup);
+	/* box.backup = {<...>} */
+	luaL_findtable(L, LUA_GLOBALSINDEX, "box.backup", 0);
+	luaL_setfuncs(L, boxlib_backup, 0);
 	lua_pop(L, 1);
 
 	box_lua_error_init(L);
diff --git a/src/box/lua/key_def.c b/src/box/lua/key_def.c
index 321bdad3f8e3380ba5f1e9f361a8aceb7a673137..e5fc370e49803ae6167fdd78bb2c9009b0c653de 100644
--- a/src/box/lua/key_def.c
+++ b/src/box/lua/key_def.c
@@ -517,6 +517,6 @@ luaopen_key_def(struct lua_State *L)
 		{"totable", lbox_key_def_to_table},
 		{NULL, NULL}
 	};
-	luaL_register_module(L, "key_def", meta);
+	luaT_newmodule(L, "key_def", meta);
 	return 1;
 }
diff --git a/src/box/lua/lib.c b/src/box/lua/lib.c
index 3d45f4ce1d6f9a269b16b1d8f84120e9bb84564c..f0921074d665331d9f41e78cbe2afba11fede0d9 100644
--- a/src/box/lua/lib.c
+++ b/src/box/lua/lib.c
@@ -578,7 +578,8 @@ box_lua_lib_init(struct lua_State *L)
 		{ "load",		lbox_module_load	},
 		{ NULL, NULL },
 	};
-	luaL_register(L, "box.lib", top_methods);
+	luaL_findtable(L, LUA_GLOBALSINDEX, "box.lib", 0);
+	luaL_setfuncs(L, top_methods, 0);
 	lua_pop(L, 1);
 
 	static const struct luaL_Reg lbox_module_methods[] = {
diff --git a/src/box/lua/load_cfg.lua b/src/box/lua/load_cfg.lua
index 9535a735a404de1cd93ede51776d6982be6a9bbc..8909a8287561c17eec04f084fd3981ca73ed0709 100644
--- a/src/box/lua/load_cfg.lua
+++ b/src/box/lua/load_cfg.lua
@@ -2,7 +2,7 @@
 
 local log = require('log')
 local json = require('json')
-local private = require('box.internal')
+local private = box.internal
 local urilib = require('uri')
 local math = require('math')
 local fiber = require('fiber')
diff --git a/src/box/lua/merger.c b/src/box/lua/merger.c
index ad21f4b7cf2b2eff462237e3c723992a71b4604a..5985c63cebbe69bb5d97b883279b49f108feacd9 100644
--- a/src/box/lua/merger.c
+++ b/src/box/lua/merger.c
@@ -1288,7 +1288,7 @@ luaopen_merger(struct lua_State *L)
 		{"new", lbox_merger_new},
 		{NULL, NULL}
 	};
-	luaL_register_module(L, "merger", meta);
+	luaT_newmodule(L, "merger", meta);
 
 	/* Add internal.{select,ipairs}(). */
 	lua_newtable(L); /* merger.internal */
diff --git a/src/box/lua/misc.cc b/src/box/lua/misc.cc
index 720267e438f7471814b687ad4ae2264ab35ff131..a338c444328ae8439852f720788cafffcb102118 100644
--- a/src/box/lua/misc.cc
+++ b/src/box/lua/misc.cc
@@ -432,7 +432,8 @@ box_lua_misc_init(struct lua_State *L)
 		{NULL, NULL}
 	};
 
-	luaL_register(L, "box.internal", boxlib_internal);
+	luaL_findtable(L, LUA_GLOBALSINDEX, "box.internal", 0);
+	luaL_setfuncs(L, boxlib_internal, 0);
 	lua_pop(L, 1);
 
 	int rc = luaL_cdef(L, "struct tuple_format;");
diff --git a/src/box/lua/net_box.c b/src/box/lua/net_box.c
index 307057f12ca1bf60ac524a718fe4a4d21f75734b..5075894fe5efda79c25bb38d550fc45858431748 100644
--- a/src/box/lua/net_box.c
+++ b/src/box/lua/net_box.c
@@ -3041,12 +3041,6 @@ luaopen_net_box(struct lua_State *L)
 		{ "new_transport",  luaT_netbox_new_transport },
 		{ NULL, NULL}
 	};
-	/* luaL_register_module polutes _G */
-	lua_newtable(L);
-	luaL_openlib(L, NULL, net_box_lib, 0);
-	lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
-	lua_pushvalue(L, -2);
-	lua_setfield(L, -2, "net.box.lib");
-	lua_remove(L, -1);
+	luaT_newmodule(L, "net.box.lib", net_box_lib);
 	return 1;
 }
diff --git a/src/box/lua/net_box.lua b/src/box/lua/net_box.lua
index c74156081adaa8fd698dd0546ee710af803c9b51..6c57ad53926cc30e98ea6e29bd3059198cc5a750 100644
--- a/src/box/lua/net_box.lua
+++ b/src/box/lua/net_box.lua
@@ -1302,8 +1302,7 @@ this_module.self = {
         check_call_args(args)
         args = args or {}
         proc_name = tostring(proc_name)
-        local status, proc, obj = pcall(package.loaded['box.internal'].
-            call_loadproc, proc_name)
+        local status, proc, obj = pcall(box.internal.call_loadproc, proc_name)
         if not status then
             rollback()
             return error(proc) -- re-throw
diff --git a/src/box/lua/schema.lua b/src/box/lua/schema.lua
index 20685bfb7a92bdff589c07c2d780aa1fe44b572a..95363aca3277997ba2d8117a0d36b6d44763a52a 100644
--- a/src/box/lua/schema.lua
+++ b/src/box/lua/schema.lua
@@ -7,7 +7,7 @@ local log = require('log')
 local buffer = require('buffer')
 local fiber = require('fiber')
 local session = box.session
-local internal = require('box.internal')
+local internal = box.internal
 local utf8 = require('utf8')
 local function setmap(table)
     return setmetatable(table, { __serialize = 'map' })
diff --git a/src/box/lua/sequence.c b/src/box/lua/sequence.c
index bf0714c1a185e61197e2da21d1d18f2fbe1b6877..f5d5a456cc40f856ec3b68d0e34335a36e849b75 100644
--- a/src/box/lua/sequence.c
+++ b/src/box/lua/sequence.c
@@ -178,7 +178,8 @@ box_lua_sequence_init(struct lua_State *L)
 		{"reset", lbox_sequence_reset},
 		{NULL, NULL}
 	};
-	luaL_register(L, "box.internal.sequence", sequence_internal_lib);
+	luaL_findtable(L, LUA_GLOBALSINDEX, "box.internal.sequence", 0);
+	luaL_setfuncs(L, sequence_internal_lib, 0);
 	lua_pop(L, 1);
 
 	static struct trigger on_alter_sequence_in_lua;
diff --git a/src/box/lua/session.c b/src/box/lua/session.c
index 23581ef3281d8947bb2bd4bd63dd17e19702f5f7..2145fc9e28d79909b5573133ea8513c23af1e3b4 100644
--- a/src/box/lua/session.c
+++ b/src/box/lua/session.c
@@ -544,7 +544,8 @@ box_lua_session_init(struct lua_State *L)
 		{"run_on_auth", lbox_session_run_on_auth},
 		{NULL, NULL}
 	};
-	luaL_register(L, "box.internal.session", session_internal_lib);
+	luaL_findtable(L, LUA_GLOBALSINDEX, "box.internal.session", 0);
+	luaL_setfuncs(L, session_internal_lib, 0);
 	lua_pop(L, 1);
 
 	static const struct luaL_Reg sessionlib[] = {
@@ -566,7 +567,8 @@ box_lua_session_init(struct lua_State *L)
 		{"push", lbox_session_push},
 		{NULL, NULL}
 	};
-	luaL_register_module(L, sessionlib_name, sessionlib);
+	luaL_findtable(L, LUA_GLOBALSINDEX, sessionlib_name, 0);
+	luaL_setfuncs(L, sessionlib, 0);
 	lbox_session_settings_init(L);
 	lua_pop(L, 1);
 }
diff --git a/src/box/lua/space.cc b/src/box/lua/space.cc
index ccd73e00dbddaa5ec1b65790827b53893e94d31e..688f6b969e7d0ff0a5aa89f0e1c5a5cbf71a24bd 100644
--- a/src/box/lua/space.cc
+++ b/src/box/lua/space.cc
@@ -781,6 +781,7 @@ box_lua_space_init(struct lua_State *L)
 		{"frommap", lbox_space_frommap},
 		{NULL, NULL}
 	};
-	luaL_register(L, "box.internal.space", space_internal_lib);
+	luaL_findtable(L, LUA_GLOBALSINDEX, "box.internal.space", 0);
+	luaL_setfuncs(L, space_internal_lib, 0);
 	lua_pop(L, 1);
 }
diff --git a/src/box/lua/stat.c b/src/box/lua/stat.c
index edba974ab61323a9645e5ea714bbd113b9889746..7f42d88f35a83b662b27e7a0bc88976881b449b7 100644
--- a/src/box/lua/stat.c
+++ b/src/box/lua/stat.c
@@ -452,39 +452,29 @@ box_lua_stat_init(struct lua_State *L)
 		{NULL, NULL}
 	};
 
-	luaL_register_module(L, "box.stat", statlib);
+	luaL_findtable(L, LUA_GLOBALSINDEX, "box.stat", 0);
+	luaL_setfuncs(L, statlib, 0);
 
 	lua_newtable(L);
-	luaL_register(L, NULL, lbox_stat_meta);
+	luaL_setfuncs(L, lbox_stat_meta, 0);
 	lua_setmetatable(L, -2);
 	lua_pop(L, 1); /* stat module */
 
-	static const struct luaL_Reg netstatlib [] = {
-		{NULL, NULL}
-	};
-
-	luaL_register_module(L, "box.stat.net", netstatlib);
-
+	luaL_findtable(L, LUA_GLOBALSINDEX, "box.stat.net", 0);
 	lua_newtable(L);
-	luaL_register(L, NULL, lbox_stat_net_meta);
+	luaL_setfuncs(L, lbox_stat_net_meta, 0);
 	lua_setmetatable(L, -2);
 	lua_pop(L, 1); /* stat net module */
 
-	luaL_register_module(L, "box.stat.net.thread", netstatlib);
-
+	luaL_findtable(L, LUA_GLOBALSINDEX, "box.stat.net.thread", 0);
 	lua_newtable(L);
-	luaL_register(L, NULL, lbox_stat_net_thread_meta);
+	luaL_setfuncs(L, lbox_stat_net_thread_meta, 0);
 	lua_setmetatable(L, -2);
 	lua_pop(L, 1); /* stat net module */
 
-	static const struct luaL_Reg memtx_mvcc_statlib[] = {
-		{NULL, NULL}
-	};
-
-	luaL_register_module(L, "box.stat.memtx.tx", memtx_mvcc_statlib);
-
+	luaL_findtable(L, LUA_GLOBALSINDEX, "box.stat.memtx.tx", 0);
 	lua_newtable(L);
-	luaL_register(L, NULL, lbox_stat_memtx_mvcc_meta);
+	luaL_setfuncs(L, lbox_stat_memtx_mvcc_meta, 0);
 	lua_setmetatable(L, -2);
 	lua_pop(L, 1); /* stat tx module */
 
diff --git a/src/box/lua/tuple.c b/src/box/lua/tuple.c
index 6fd7fd42ded0db797244c3b457b15977e6b9049f..d19f57d735b8a38db131d52d46e5acd0cd0930f7 100644
--- a/src/box/lua/tuple.c
+++ b/src/box/lua/tuple.c
@@ -740,12 +740,13 @@ box_lua_tuple_init(struct lua_State *L)
 	/* export C functions to Lua */
 	luaL_findtable(L, LUA_GLOBALSINDEX, "box.internal", 1);
 	luaL_newmetatable(L, tuplelib_name);
-	luaL_register(L, NULL, lbox_tuple_meta);
+	luaL_setfuncs(L, lbox_tuple_meta, 0);
 	lua_setfield(L, -2, "tuple");
 	lua_pop(L, 1); /* box.internal */
 	luaL_register_type(L, tuple_iteratorlib_name,
 			   lbox_tuple_iterator_meta);
-	luaL_register_module(L, tuplelib_name, lbox_tuplelib);
+	luaL_findtable(L, LUA_GLOBALSINDEX, tuplelib_name, 0);
+	luaL_setfuncs(L, lbox_tuplelib, 0);
 	lua_pop(L, 1);
 
 	tuple_serializer_update_options();
diff --git a/src/box/lua/tuple.lua b/src/box/lua/tuple.lua
index 98f3f8de63ca430bb56fc89b286e640617a0b722..33aa444849b45d84fc154b8197d40b56fde9e23f 100644
--- a/src/box/lua/tuple.lua
+++ b/src/box/lua/tuple.lua
@@ -4,7 +4,7 @@ local ffi = require('ffi')
 local msgpackffi = require('msgpackffi')
 local fun = require('fun')
 local buffer = require('buffer')
-local internal = require('box.internal')
+local internal = box.internal
 local cord_ibuf_take = buffer.internal.cord_ibuf_take
 local cord_ibuf_put = buffer.internal.cord_ibuf_put
 
diff --git a/src/box/lua/xlog.c b/src/box/lua/xlog.c
index 19679a72475c61c0ceb1ecd0c835d93a5e6b31fe..698e72fecd57487d2463dfd7ed2b0eab5744ec01 100644
--- a/src/box/lua/xlog.c
+++ b/src/box/lua/xlog.c
@@ -328,7 +328,7 @@ box_lua_xlog_init(struct lua_State *L)
 	CTID_STRUCT_XLOG_CURSOR_REF = luaL_ctypeid(L, "struct xlog_cursor&");
 	assert(CTID_STRUCT_XLOG_CURSOR_REF != 0);
 
-	luaL_register_module(L, xloglib_name, lbox_xlog_parser_lib);
+	luaT_newmodule(L, xloglib_name, lbox_xlog_parser_lib);
 
 	lua_newtable(L);
 	lua_setmetatable(L, -2);