Parse and process command line options.
optparse parses and processes command line options for LuaJIT and
Lua 5.1 through 5.5. Write the --help text of your program the way
you would anyway, and optparse builds a parser from it:
--long=ARG arguments, and collects options into a table--help, --version and --The API reference has every function and field in detail.
Install the latest release with LuaRocks:
luarocks install optparseoptparse is pure Lua, with no dependencies, so you can also copy
init.lua and _normalize.lua from its lib/optparse directory into an
optparse directory in your package search path.
Loading optparse returns a factory, which you call with the help text of your program to build a parser for it:
local OptionParser = require 'optparse'
local parser = OptionParser [[
parseme 1.0
Copyright (C) 2026 Your Name
This program comes with ABSOLUTELY NO WARRANTY.
Usage: parseme [<options>] <file>...
Banner text.
Long description.
Options:
-h, --help display this help, then exit
--version display version information, then exit
-b a short option with no long option
--long a long option with no short option
--another-long a long option with internal hyphen
-v, --verbose a combined short and long option
-n, --dryrun, --dry-run several spellings of the same option
-u, --name=USER require an argument
-o, --output=[FILE] accept an optional argument
-- end of options
Footer text.
Please report bugs at <https://github.com/you/parseme/issues>.
]]The help text needs a Usage: line, and optparse splits it in two
there:
versiontext is everything before Usage:, which --version
displays. The last word of its first line is the version of your
program, 1.0 above.helptext is everything from Usage: on, which --help displays.
The word after Usage: is the name of your program, which error
messages start with.A line in helptext that starts with two or more spaces and then a
hyphen specifies an option: every comma or space separated spelling at
the start of the line, until the description. Everything else is
there for your users to read, and optparse ignores it.
How each option is written decides what optparse does with it:
| Written as | Handler |
|---|---|
-b, --long, -v, --verbose |
flag |
-u, --name=USER |
required |
-o, --output=[FILE] |
optional |
--help |
showhelp |
--version |
showversion |
-- |
finished |
Pass the command line to parse, which returns the arguments it did not
recognise, and a table of the options it found:
local arg, opts = parser:parse(_G.arg)Each option is stored under one key, made from the last spelling written
in the specification, without its leading hyphens and with every other
non-alphanumeric character turned into _:
| Specification | Key |
|---|---|
-b |
opts.b |
-v, --verbose |
opts.verbose |
--another-long |
opts.another_long |
-n, --dryrun, --dry-run |
opts.dry_run |
Before any handler runs, parse expands combined short options, so that
-bv is the same as -b -v, and splits a recognised --long=ARG into
--long ARG. Then:
$ parseme -bv --name=gary in.txtreturns {'in.txt'} and {b = true, verbose = true, name = 'gary'}.
An argument that is not a recognised option is returned in the first
table, in order, along with the argument after an unrecognised option,
unless it starts with a hyphen. So parseme --bogus in.txt returns
{'--bogus', 'in.txt'}, and your program decides whether that is an
error.
The second argument to parse is a table of defaults, for the options
that the command line leaves out:
local arg, opts = parser:parse(_G.arg, {name = 'nobody'})An option given on the command line keeps its value, even when that is
false.
The parser is an object with the fields that optparse read from the
specification, program, version, versiontext and helptext, and
opts is a table whose missing fields are looked up in the parser.
parse also saves its results in the parser, as parser.unrecognised
and parser.opts.
A handler is the function that parse calls when it finds an option.
optparse chooses one for each option in the specification, as in the
table in section 2, and you can choose another
with on.
flag stores true, however often the option is given:
$ parseme -v -v # opts.verbose == truerequired stores the next argument, even if it starts with a hyphen,
and reports an error if there is none. Given more than once, the
option stores a list of its arguments, in order:
$ parseme -u gary # opts.name == 'gary'
$ parseme --name=gary -u root # opts.name == {'gary', 'root'}optional stores the next argument if there is one that does not start
with a hyphen, and true otherwise:
$ parseme -o out.txt # opts.output == 'out.txt'
$ parseme -o -v # opts.output == trueLike required, it stores a list when the option is given more than
once.
showhelp prints helptext, and showversion prints versiontext;
both then exit with status 0.
finished stops parse there, so every argument after -- is
returned as unrecognised, even when it looks like an option:
$ parseme -- -b in.txt # arg == {'-b', 'in.txt'}on sets the handler for an option, replacing the one from the
specification, or adding an option that the specification leaves out:
parser:on('-?', parser.showhelp)
parser:on({'-e', '--eval'}, parser.required)It takes a spelling of the option, or a list of them, which can leave
out the hyphens: a single letter is a short option, and a longer name a
long option. The key in opts comes from the last spelling, as in
section 3.
A handler of your own is called with the parser, the expanded argument
list, the index of the option in that list, and the third argument
given to on, and returns the index of the next argument to process:
-- Count each -v, for more and more verbose output.
parser:on({'-v', '--verbose'}, function(parser, arglist, i)
parser.opts.verbose = (parser.opts.verbose or 0) + 1
return i + 1
end)on also passes its third argument on to the built-in handlers. If it
is a function, required, optional and flag call it with the
parser, the option and its argument, and store what it returns; the
argument is nil for optional without one, and true for flag.
Otherwise, required and optional store it in place of the argument.
optparse comes with two functions to pass to on that way. boolean
turns an argument into true or false, accepting 1, true, yes
and y, or 0, false, no and n, in any case, and reports an
error for anything else. With optional, the option alone is true:
parser:on('--color', parser.optional, parser.boolean)so --color and --color=yes store true, and --color=no stores
false.
file reports an error unless the argument names a file that can be
read:
parser:on('--config', parser.required, parser.file)opterr writes an error message in the same form as optparseās own,
then exits with status 2:
$ parseme --name
parseme: error: option '--name' requires an argument.
parseme: Try 'parseme --help' for help.Call it from your own handlers, or after parse, to report errors the
same way:
local arg, opts = parser:parse(_G.arg)
if #arg == 0 then
parser:opterr 'no files given'
endPlease report bugs and make suggestions as GitHub issues, and check that they are not already fixed on master first. Pull requests are especially welcome.