NGS is a programming language for Ops tasks, not a nicer bash
Next Generation Shell (NGS)
At a glance
- What is it?
- Next Generation Shell is a C implementation of a language aimed at operations work, with built-in facilities for piping external programs, turning non-zero exit codes into exceptions, parsing command output, retrying calls, and running tests against CLI tools. Its centrepiece, an interactive shell with a new user interface, is still work in progress.
- Who is it for?
- NGS suits an operations team whose scripts have outgrown shell scripting, especially one that spends its day calling APIs, parsing JSON and chaining external tools, since the language treats those as the normal case rather than the exception. It is the wrong choice if you need a general purpose language with a large ecosystem, and a poor match if you want a finished interactive shell today, because the new user interface is explicitly work in progress.
- Can I use it commercially?
- Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
- Is it still maintained?
- Yes. The repository last received commits 7 days ago.
- 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
The argument is about shells, not about scripting
Next Generation Shell is described as a modern programming language for DevOps, and the problem it is written against is stated in the readme as a choice you should not have to make: bash or Python, and both are inadequate for Ops tasks, in what the author calls a square pegs for a round hole situation.
The bash side of the argument is specific. bash does not meet modern expectations for syntax, for error handling, nor has the ability to work with structured data, beyond arrays and associative arrays which cannot be nested. The readme even adds a caveat, that this is not a blanket statement and you should use your own judgement when to make an exception.
The Python side of the argument is about fit rather than quality. Python and many other languages are general purpose languages which were not intended to solve specifically Ops problems, and the consequence is longer and less readable scripts when dealing with files or running external programs, which are both common for Ops work. The readme links a blog post with the same square peg and round hole framing, which is where the argument is developed at length.
There is a third target, and it is the more interesting one for a project called Next Generation Shell. The readme names the shell user interface as an atrocity, and argues that current shells and proposed alternatives treat the user interface as if nothing happened since the 70s: mostly typing commands and getting some text back. A linked video of fifteen minutes is described as being about what is wrong with the shell user interface and how NGS is fixing it, and it is marked work in progress.
So the project is not trying to be a faster bash. It is trying to be a language in which operations work is the default, with a new terminal interface as the visible part of that ambition. The author's stated motivation is simple: helping people, reducing frustration and making people more productive, with a scalable way to help through tools.
The built-in facilities are the actual product
The use cases section is where NGS becomes concrete, and the list is a list of things an operations script usually reimplements.
For data manipulation, the case is: you have JSON from an API call, an external program or standard input, and you want to extract from it, modify it, and push it into the next API call, external program or standard output. The language treats that round trip as a first class operation rather than as something you assemble from a parser invocation and a pipe.
For typical Ops scripting, the built-in list is long. There is syntax for pipes and input and output redirection, and a built-in Argv facility for conveniently building command line arguments. There is a built-in mechanism that throws exceptions when exit codes indicate an error, and a built-in mechanism that parses a command's output. Data can be piped in and out of an external program easily. Output can be JSON or a human-readable, nicely formatted table.
Then the ones that save the most code. A built-in debug() function prints debug information conditionally, depending on an environment variable per section setting, so you can turn on the logging for one section of a script without turning it on everywhere. A built-in status() reporting function shows the current status on screen, and the previous status is overridden with the new one. A built-in log() function prints timestamped output. And a built-in retry() function, with the pointed comment that you should stop re-implementing it hundreds of times.
For testing, there is a built-in testing mini-framework, aimed at testing CLI programs and API endpoints.
The AWS library is marked work in progress or proof of concept, and its stated value is that scripting is easier than the declarative tools, because it allows modelling of processes and not just final state, which is the argument CloudFormation and Terraform have been having with everyone for a decade.
The interactive shell is the plan, and the plan is visible
The readme's structure gives you a clear picture of where the project is going, because several sections are explicitly about the future.
The stated solution ends with the line that the next big planned part is the interactive shell, and the use cases list ends with the future interactive shell with a user interface that is not from the 70s, with a link to the UI design notes in the project wiki.
There is also a section on how to run the proof of concept, and one titled have you heard of project X, how it compares to NGS. The existence of a comparison section in the readme is itself informative: it means the project expects to be evaluated against other shell proposals, and that the author wants the comparison to be visible rather than implicit.
The planned features are grouped into three headings, cross-system, development, and later, unformed, unfinished thoughts. The last category is a good sign of self-awareness in a project of this kind, since a language design that has not settled is exactly the kind of thing that is better said out loud.
For an adopter, the honest reading is that NGS today is a language with a script-oriented interface and a plan for something else. The scripts, the built-in facilities and the test framework are usable now. The interactive experience that the project's name promises is the part that is still being designed, and the readme's own framing of that work as in progress is the guidance to weigh it against.
Nine ways to install it, including a notebook and a Lambda
The installation section of the readme is a list of methods rather than a single procedure, and the variety says something about who the project expects to reach for it.
There is a script, for people who want to try it quickly. There is MacPorts. There is Homebrew, whose formula is linked with a badge in the header, so a stable version is tracked there. There is Snap, with a snapcraft badge. There is Docker, with a build badge pointing at a Docker Hub repository. There is a GitHub Action. There is a path for using it from iPython or Jupyter Notebook, which is a striking choice for a systems language and suggests the language is expected to be driven from a notebook for exploration. And there is a path for AWS Lambda, which is the deployment target that a lot of operations automation actually runs on.
The repository supports those stories. There is a build-in-aws/ directory, a snap/ directory with the packaging, a Dockerfile and a separate Dockerfile.build-deb for the Debian package, a debian/ directory, an action.yml for the GitHub Action, and an install.sh at the root that the Docker build calls.
The Docker image is worth a look, because it shows how the project tests itself. The build stage is Debian bullseye, it installs sudo, copies the source in, and runs the install script followed by the test target. The release stage is also Debian bullseye and installs just three runtime libraries, libgc1, libffi7 and libjson-c5, then copies the library directory and the binary across from the build stage, copies a test script, and runs the test suite with the environment variable NGS_TESTS_BASE_DIR pointing at the installed library.
That dependency list is a good summary of the implementation: a garbage collected runtime, a foreign function interface library, and a JSON library. The language has a garbage collector, it can call into C libraries, and it parses and emits JSON.
A virtual machine, a parser generator and a syntax file for vim
The repository root tells you that NGS is a compiled language with its own toolchain, and the file names are the architecture.
There is a virtual machine in vm.c and vm.h, a compiler in compile.c and compile.h, and a decompiler in decompile.c and decompile.h, which is an unusual component to find and suggests that the compiled form is inspectable. The abstract syntax tree lives in ast.c and ast.h, objects in obj.c and obj.h, and the entry point in ngs.c and ngs.h.
The parser is generated from a grammar file, syntax.leg, which is the input for the LEG parser generator. The syntax itself is declared in syntax.h. There is a debug.c and debug.h for the debugging support, and a gc.supp file, which is a suppression file for the garbage collector, the one that the libgc1 dependency in the container points at.
Two files show the care taken with the edges of the system. fmemopen.c and fmemopen.h implement the memory stream function, which is the standard way to let a program read a file that is still being written, and malloc.c is a wrapper for allocation. The latter is the sort of file that exists because the runtime needs to control allocation, probably to hand memory to the garbage collector.
Around that are the operational files: install.sh, the Makefile, CMakeLists.txt, the Vagrantfile, and the test files in the NGS language itself, test.ngs, test-gc.ngs for the garbage collector, test-invoke.ngs for the external program invocation, and test-aws.ngs for the AWS work. There is also one-liners.txt, a collection of short scripts, and a vim/ directory with the syntax highlighting, updated by a helper script that the Makefile can run.
The project is GPL-3.0, and the licence is the one thing about a language implementation that has to be settled before anyone embeds it in a product.
Building from source, and a dev setup that only works on macOS
The manual compilation section is thorough, and the Makefile is small enough to read in one go.
There is a build target that creates a build directory, runs cmake in it and makes the result, and a tests target that runs ctest with the failed tests rerun and the output shown on failure. There is an install target that depends on the build and installs with sudo, a clean target that removes the build directory, and a test-installation target that reports where the ngs binary and the man page were found, which is a nice touch for a language that installs both a binary and its documentation.
The cmake and ctest commands are looked up at build time, preferring the versioned names cmake3 and ctest3 when they exist and falling back to the plain names, which is the kind of compatibility handling that saves a build on an older distribution.
There is a target for updating the vim syntax file, which runs a helper script written in NGS itself, and there is a setup-dev-env target that symlinks the built binary into the local bin directory and the library directory into the local lib directory. That target is implemented for Darwin only, and on any other platform it prints that setup-dev-env is not implemented for your platform. In other words, the developer convenience path is macOS only, and a Linux contributor has to install into the system prefix with sudo instead.
That is a small thing and it is the kind of small thing that tells you about a project with a handful of people in it rather than an organisation behind it. The same is true of the release history: v0.2.15 on 2023-03-18, v0.2.16 on 2023-05-17, and v0.2.17 on 2025-04-05, so the tagged versions moved twice in 2023 and then not for two years, while the last push was on 2026-10-16 and the header carries a badge counting the commits on the dev branch since the last release. The development is continuous and the releases are occasional.
Editorial conclusion
NGS suits an operations team whose scripts have outgrown shell scripting, especially one that spends its day calling APIs, parsing JSON and chaining external tools, since the language treats those as the normal case rather than the exception. It is the wrong choice if you need a general purpose language with a large ecosystem, and a poor match if you want a finished interactive shell today, because the new user interface is explicitly work in progress. Before adopting, run the project status and comparison sections of the documentation to see how the project positions itself, try the proof of concept scripts in the repository, and note that the released version line is still at 0.2.x with releases more than a year apart.
Frequently asked questions
What is NGS and what problem does it target?
Next Generation Shell is a modern programming language for DevOps, written in C. The project argues that bash lacks modern syntax, error handling and structured data handling, and that general purpose languages such as Python produce longer and less readable scripts for the file and external program work that operations scripts do constantly.
Which built-in functions does NGS provide for operations scripts?
There is a built-in Argv facility for building command line arguments, a mechanism that throws exceptions on error exit codes, a mechanism for parsing command output, a retry function, a status function that reports on screen, a timestamped log function, a debug function with per section environment variable settings, and output as JSON or a formatted table.
How do I install NGS?
The documentation lists a script, MacPorts, Homebrew, Snap, Docker, a GitHub Action, use from iPython or Jupyter Notebook, and AWS Lambda. The container images are published to Docker Hub, and the Homebrew formula tracks a stable version.
Is the interactive shell part of NGS finished?
No. The readme describes the new shell user interface as the next big planned part, links a video about fixing what is wrong with the shell user interface and marks it work in progress, and lists a UI design page in the project wiki. The proof of concept scripts and the built-in facilities are the parts available now.
Official sources
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.
[](https://hysenlabs.com/projects/ngs-lang-ngs)Was this useful?