Una de las críticas habituales a Lua es que su biblioteca estándar es intencionadamente pequeña. No hay módulo de HTTP, ni de JSON, ni de expresiones regulares PCRE, ni de filesystem completo. Esa filosofía de mínima superficie es una decisión de diseño consciente: el intérprete se mantiene pequeño y es la comunidad quien aporta los módulos adicionales a través de LuaRocks.
¿Qué es LuaRocks?
LuaRocks es el gestor de paquetes de Lua. Un paquete en LuaRocks se llama rock y consiste en código Lua puro, extensiones C compiladas, o una combinación de ambos. El registro público está en luarocks.org y cuenta con miles de paquetes disponibles. LuaRocks descarga las fuentes, las compila si hace falta y las instala en el directorio correcto para que require las encuentre.
Instalación y uso básico
# Instalar LuaRocks (Ubuntu/Debian) sudo apt install luarocks # Instalar un paquete globalmente luarocks install luasocket # Instalar una versión concreta luarocks install lua-cjson 2.1.0 # Instalar solo para el usuario actual (sin sudo) luarocks install --local penlight # Listar paquetes instalados luarocks list # Buscar un paquete en el registro luarocks search http # Ver información de un paquete luarocks show busted # Eliminar un paquete luarocks remove luasocket
Paquetes imprescindibles en 2026
luasocket: networking básico
La biblioteca de red más usada en Lua. Proporciona TCP, UDP, HTTP simple y DNS:
local http = require("socket.http")
local ltn12 = require("ltn12")
-- GET sencillo
local body, code, headers = http.request("http://ejemplo.com/api/datos")
print("HTTP " .. code)
print(body)
-- GET con sink para respuestas grandes
local resultado = {}
http.request({
url = "http://api.ejemplo.com/datos",
sink = ltn12.sink.table(resultado),
headers = {["Accept"] = "application/json"}
})
print(table.concat(resultado))
lua-cjson: JSON rápido
Módulo C para codificar y decodificar JSON. Mucho más rápido que implementaciones Lua puras:
local cjson = require("cjson")
-- Decodificar
local datos = cjson.decode('{"nombre":"Ana","edad":30,"activo":true}')
print(datos.nombre) -- Ana
print(datos.edad) -- 30
-- Codificar
local obj = {
usuarios = {"Ana", "Bruno", "Carla"},
total = 3,
pagina = 1
}
print(cjson.encode(obj))
-- {"usuarios":["Ana","Bruno","Carla"],"total":3,"pagina":1}
-- null de JSON se mapea a cjson.null (no a nil)
local con_null = cjson.decode('{"campo":null}')
if con_null.campo == cjson.null then
print("El campo es null en JSON")
end
penlight: utilidades de propósito general
Penlight es la biblioteca de «puertas de batería incluidas» de Lua. Cubre colecciones, strings, ficheros, templates y más:
local pl = require("pl.import_into")()
-- Manipulación de paths
local path = pl.path
print(path.join("/usr", "local", "bin")) -- /usr/local/bin
print(path.basename("/usr/local/bin/lua")) -- lua
print(path.exists("/etc/hosts")) -- true o false
-- Strings
local stringx = pl.stringx
print(stringx.strip(" hola mundo ")) -- "hola mundo"
print(stringx.startswith("hola", "ho")) -- true
local partes = stringx.split("a,b,c", ",")
-- {"a", "b", "c"}
-- Colecciones funcionales
local tablex = pl.tablex
local nums = {1, 2, 3, 4, 5, 6}
local pares = tablex.filter(nums, function(x) return x % 2 == 0 end)
-- {2, 4, 6}
local cuadrados = tablex.map(function(x) return x * x end, nums)
-- {1, 4, 9, 16, 25, 36}
busted: testing
El framework de testing más usado en Lua. Usa una sintaxis BDD similar a Mocha o RSpec:
-- fichero: spec/calculadora_spec.lua
local calc = require("calculadora")
describe("Calculadora", function()
it("suma dos números", function()
assert.are.equal(5, calc.suma(2, 3))
end)
it("devuelve error al dividir por cero", function()
assert.has_error(function()
calc.dividir(10, 0)
end, "división por cero")
end)
describe("operaciones en cadena", function()
it("permite encadenar sumas", function()
local resultado = calc.nuevo():suma(1):suma(2):suma(3):valor()
assert.are.equal(6, resultado)
end)
end)
end)
# Ejecutar todos los tests busted # Solo un fichero busted spec/calculadora_spec.lua # Con cobertura (requiere luacov) busted --coverage
luafilesystem (lfs): acceso al sistema de ficheros
local lfs = require("lfs")
-- Listar un directorio
for entrada in lfs.dir("/tmp") do
if entrada ~= "." and entrada ~= ".." then
local info = lfs.attributes("/tmp/" .. entrada)
print(entrada, info.mode, info.size)
end
end
-- Crear directorio y cambiar permisos
lfs.mkdir("/tmp/mi_directorio")
-- Atributos de un fichero
local attr = lfs.attributes("/etc/hosts")
print("Tamaño: " .. attr.size .. " bytes")
print("Modificado: " .. os.date("%Y-%m-%d", attr.modification))
Crear un rockspec propio
Para distribuir tu propio módulo Lua, creas un fichero .rockspec que describe el paquete:
-- mi-modulo-1.0-1.rockspec
package = "mi-modulo"
version = "1.0-1"
source = {
url = "https://github.com/usuario/mi-modulo/archive/v1.0.tar.gz",
md5 = "abc123..."
}
description = {
summary = "Un módulo Lua de ejemplo",
homepage = "https://github.com/usuario/mi-modulo",
license = "MIT"
}
dependencies = {
"lua >= 5.1",
"lua-cjson >= 2.0"
}
build = {
type = "builtin",
modules = {
["mi-modulo"] = "src/mi-modulo.lua",
["mi-modulo.util"] = "src/util.lua"
}
}
# Instalar localmente desde el rockspec luarocks make mi-modulo-1.0-1.rockspec # Subir al registro (requiere cuenta en luarocks.org) luarocks upload mi-modulo-1.0-1.rockspec --api-key=TU_CLAVE
LuaRocks resuelve el problema más importante que tenía Lua como lenguaje práctico: la ausencia de un repositorio centralizado de código reutilizable. Combinado con las capacidades de metatables para OOP y el ecosistema de LuaJIT para rendimiento, convierte a Lua en una plataforma viable para proyectos de tamaño mediano sin necesidad de reinventar la rueda en cada proyecto.
Imagen: Pexels / Pixabay
