Networking#

Lua’s networking story depends heavily on the host. Standalone Lua reaches for LuaSocket; embedded Lua usually uses whatever the host program exposes.

LuaSocket#

The classic, most portable option.

local socket = require("socket")
local http   = require("socket.http")
local ltn12  = require("ltn12")

-- Simple GET
local body, code, headers = http.request("https://example.com/")

-- POST with body
local resp = {}
local body = '{"name":"operator"}'
http.request{
  url = "https://api.example.com/users",
  method = "POST",
  headers = {
    ["Content-Type"] = "application/json",
    ["Content-Length"] = tostring(#body),
  },
  source = ltn12.source.string(body),
  sink   = ltn12.sink.table(resp),
}

For HTTPS, install luasec:

local https = require("ssl.https")
local body, code = https.request("https://example.com/")

TCP / UDP#

-- TCP server
local server = assert(socket.bind("0.0.0.0", 9000))
while true do
  local client = server:accept()
  client:settimeout(5)
  local line = client:receive("*l")
  client:send(line .. "\n")
  client:close()
end

-- TCP client
local c = assert(socket.connect("host", 9000))
c:send("hello\n")
print(c:receive("*l"))

OpenResty / cosockets#

Inside OpenResty (nginx + LuaJIT), use the non-blocking cosocket API rather than LuaSocket; LuaSocket would block the worker.

-- inside an OpenResty handler
local httpc = require("resty.http").new()
local res, err = httpc:request_uri("https://example.com/", {
  method = "GET",
  headers = { ["User-Agent"] = "myapp" },
  ssl_verify = true,
})

ngx.say(res.status, " ", #res.body, " bytes")

The OpenResty ecosystem has cosocket-aware libraries for Postgres (lua-resty-postgres), Redis (lua-resty-redis), MySQL, MongoDB, Memcached, and more.

HTTP Client Libraries#

HTTP Servers#

Standalone Lua HTTP servers are uncommon; the typical deployment puts Lua behind nginx/OpenResty.

  • Lapis , web framework on top of OpenResty.

  • Pegasus, pure-Lua HTTP server.

  • lua-http, can run as a server.

WebSockets#

DNS#

  • socket.dns.toip(host), resolve a hostname.

  • socket.dns.gethostname(), local hostname.

  • lua-resty-dns, non-blocking DNS in OpenResty.

TLS#

  • LuaSec, OpenSSL bindings; provides ssl.https.

  • OpenResty ships TLS via nginx and exposes ssl_verify flags on its HTTP client.

In Embedded Hosts#

  • Neovim: vim.uv (libuv) for low-level I/O; vim.system / vim.net for higher-level use; plugins typically defer to curl / wget.

  • Roblox / Luau: HttpService and game-specific networking primitives.

  • Game engines (LÖVE, Defold): each provides its own networking module; LÖVE bundles LuaSocket.

  • Tarantool: net.box for the database protocol; built-in HTTP server module.

Check the host’s documentation; it almost always has the answer for that environment.