Open-source project
luaposix/luaposix avatar
luaposix/luaposix

luaposix: POSIX system calls from Lua, one header at a time

Lua bindings for POSIX APIs

595 stars142 forksCMIT

At a glance

What is it?
luaposix binds the C API of the POSIX standard to Lua, split into submodules that mirror the header files, and it tries to detect what your system actually implements so that a script calling a missing function fails on a clear error rather than a missing symbol at load time.
Who is it for?
luaposix fits a Lua developer who needs real POSIX behaviour, file descriptors, signals or process control, without writing a C extension, and it fits anyone who needs the same script to run across different POSIX systems, because the library detects the conformance level of the host and binds only what is actually available.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly C, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What the library is, and what it refuses to be

luaposix is a POSIX binding for LuaJIT and for Lua 5.1, 5.2, 5.3, 5.4 and 5.5. The project describes itself in a way that tells you the design philosophy: like most libraries it simply binds to C APIs on the underlying system, so it will not work on non-POSIX systems. What it adds on top of that is conformance detection. The library tries to detect the level of POSIX conformance of the underlying system and binds only the APIs that are actually available. That single decision shapes everything else about the project, from the way the modules are split to the rules it asks contributors to follow, and it is the difference between a binding that loads cleanly on an old Unix and one that dies with an unresolved symbol. The library is MIT licensed, the same licence as Lua itself, with no warranty, and the last push to the repository was on 2026-10-16.

Installing it, and the three ways to do that

LuaRocks is the recommended route, and the release install is a single command.

bash
    luarocks install luaposix

To follow the development branch, for testing or before filing a bug report, there is a separate rockspec for the master branch.

bash
    luarocks install https://raw.githubusercontent.com/luaposix/luaposix/master/luaposix-dev-1.rockspec

If you would rather not use LuaRocks at all, the project points at a bundled build-aux/luke command, invoked as shown in the build section of the included rockspec, from a freshly cloned working copy, with the caveat that you become responsible for providing the dependencies yourself. The rockspec file does contain a list of minimal dependencies if you go that route. There is a third consideration for anyone repackaging or redistributing the library, and it is the one to read before you build a package around it. Start from a release tarball rather than the development branch, because the master branch is unstable and sometimes breaks subtly, or does not build at all, or provides experimental new APIs that end up being removed before the next official release.

One module per POSIX header, required individually

The library is split into submodules according to the POSIX header file API declarations, and you require the ones you want individually. The example in the project overview is a single line.

lua
    local unistd = require 'posix.unistd'

That naming convention is the API design in one sentence. The module names map to header names, so a reader who knows the C standard library can guess the module path without documentation, and a script that only needs file descriptor operations does not pull in the whole of POSIX. It also means a missing API is a missing module rather than a broken library, which is a reasonable failure mode for a binding whose surface area is as wide as the standard it covers. The authoritative reference for the behaviour of each call is the POSIX standard itself, published online as SUSv3, and the generated documentation links to the appropriate manual page for each function, so the Lua wrapper documentation is a thin layer over the standard rather than a replacement for it.

Documentation, examples and the BDD specs

The documentation is generated with LDoc and published on the project site, with pre-built HTML files included in each release, and those files carry links to the matching SUSv3 manual pages. The example program is tree.lua, and beyond that the project points to the many small examples embedded in the generated documentation and to the BDD specs in the specs/*_spec.yaml files. A YAML-based behavioural test suite alongside a binding library is a deliberate choice, and it fits the conformance-detection design, because a test file can state that a call should fail on a system that lacks the underlying API. For a complete application built on the library, the project points at GNU Zile, a cut-down Emacs clone, which is a useful reference for how much of POSIX a Lua program can actually reach. The repository layout backs this up, with an ext/ directory for the C extension, a lib/ directory for the Lua side, doc/, spec/, build-aux/ and the lukefile that drives the build.

The seven rules that shape every contribution

There is no strict coding style, but the project lists seven points for anyone proposing a change, and the last three are the ones that shape the library. The indentation rules are specific, with 8-character indentation using tabs in C sources and 3-character indentation using spaces in Lua sources, and the string rule asks for single-quote delimiters unless a string contains an apostrophe. The first substantive rule is that there are to be no non-POSIX APIs and no platform-specific code, and that when wrapping APIs introduced in POSIX 2001 or later an appropriate conditional compilation guard should be added, with a note that a platform which is not quite POSIX may have a gnulib module to bridge the gap. The second is that wrappers must be thin, wrapping POSIX APIs in the simplest way possible, and that more convenient wrappers can be added on the Lua side in posix.lua instead. The third is a preference for explicit string function calls over object methods, to mitigate problems with monkey-patching in the caller's environment.

Curses moved out, and what the release numbers mean

For a while luaposix contained support for curses functionality as well, but that now has its own lcurses repository where it is maintained separately, which is the right outcome because a terminal UI library has a different release rhythm from a system binding. The version numbering of the project tracks the POSIX standard revisions rather than the library's own feature count, so luaposix 37.0 corresponds to a particular revision of the standard, and the release history shows v37.0 on 2026-10-11, v36.3 on 2025-02-16 and v36.2.1 on 2023-06-17. The gap between 36.2.1 and 36.3 is over two years, which tells you the project follows the standard rather than shipping on a schedule, and the ChangeLog is split between a ChangeLog.old file and a newer NEWS.md. The last push to the repository was on 2026-10-16, days after the 37.0 release, so the development branch is active.

Where luaposix is the wrong tool

The obvious boundary is portability, and it is a hard one. Because the library binds directly to the underlying C APIs, anything Windows-shaped, including the Win32 API and the C runtime that Windows ships, is out of scope, and a script that uses it cannot be made to run there without a compatibility layer that does not exist. The second boundary is scope. A binding is not a standard library, and if your needs are strings, tables, file globbing and JSON, a Lua distribution with a batteries-included ecosystem will get you there faster and more portably. The third is the surface area of the dependency itself, since you are pulling a C extension into your process and inheriting whatever the underlying system calls do with buffers, signals and file descriptors. The project is candid about the absence of a warranty, and for a binding that sits close to the system boundary that is a fair trade as long as you know it. Maintenance, meanwhile, is in the hands of users, as the project says these libraries are maintained by their users, with issues and pull requests the primary channel.

Editorial conclusion

luaposix fits a Lua developer who needs real POSIX behaviour, file descriptors, signals or process control, without writing a C extension, and it fits anyone who needs the same script to run across different POSIX systems, because the library detects the conformance level of the host and binds only what is actually available. It does not fit a project that needs to run on Windows, since the library binds directly to the underlying C APIs and will not work on non-POSIX systems, and it does not fit someone who wants a batteries-included standard library, since curses support was moved out to a separate lcurses repository. Before you adopt it, check the version of the POSIX level your target systems implement, read the seven coding rules the project lists for contributors, and pin a release rather than tracking master, which the documentation says is unstable and sometimes breaks subtly or does not build at all.

Frequently asked questions

How do I install luaposix?

The recommended way is LuaRocks, with luarocks install luaposix for the latest release or luarocks install with the luaposix-dev-1.rockspec URL for the master branch. Without LuaRocks you can call the bundled build-aux/luke command from a fresh clone, but you become responsible for the dependencies yourself.

Which Lua versions does luaposix support?

It is a POSIX binding for LuaJIT and for Lua 5.1, 5.2, 5.3, 5.4 and 5.5. The library is MIT licensed, the same licence as Lua itself, and is distributed with no warranty.

How is the luaposix API organised?

The library is split into submodules according to the POSIX header file API declarations, which you require individually, for example local unistd = require 'posix.unistd'. The authoritative behaviour reference is the POSIX standard published as SUSv3, and the generated documentation links to the relevant manual page for each function.

Does luaposix work on Windows?

No. The project says that like most libraries it simply binds to C APIs on the underlying system, so it will not work on non-POSIX systems. What it does do is detect the level of POSIX conformance of the system and bind only the APIs that are available.

Official sources

  1. Issues
  2. License: MIT
  3. luaposix/luaposix on GitHub
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/luaposix-luaposix.svg)](https://hysenlabs.com/projects/luaposix-luaposix)

Was this useful?