Самое главное-то забыл упомянуть. По сути каждая библиотека - это банальный массив, который возвращается после исполнения файла. А любая функция, загружающая файлы, будь то require, load или dofile, преобразует содержимое файла в самую обычную функцию и исполняет ее, а из этой функции идет возврат содержимого библиотеки. Это очень тонкий момент, который крайне необходим для понимания сути Lua. А то делаем всякие return'ы, а новички не понимают, для чего оно надо.
Также стоит добавить, что функция require("имяЛибы") постоянно хранит загруженную библиотеку в package.loaded.имяЛибы. То есть если ты изменишь исходник библиотеки, то изменения не вступят в силу до перезагрузки компьютера, либо до принудительного присвоения package.loaded.имяЛибы = nil. Это далеко не всегда удобно, и лично я предпочитаю использовать классический load().
Кроме того, вовсе необязательно хранить библиотеку в указанных Neo директориях. Я свободный человек, и могу закидывать свои файлы куда пожелаю, а функция require() поддерживает любой указанный путь. А если файл из указанного пути не найден - она начнет искать его в стандартных путях для библиотек.