NodeOS is an operating system that is based on JavaScript

Many programmers are familiar with Node.js, but NodeOS](https://node-os.com/) might be less familiar. This operating system is primarily written in Node.js, although it utilizes the Linux kernel for performance-intensive tasks like hardware interaction. Developed over the past two years, NodeOS is driven by the intriguing idea of creating an operating system solely with Node.js.

Darwin’s evolution chart
Is it possible to create an operating system using only Node.js?

Why is this significant?

Firstly, consider the rapid advancements of Node.js in its short lifespan. Now, envision similar progress in an operating system. Add to that some innovative features.

Isolated User Filesystems

NodeOS presents a novel concept: each user has an independent root filesystem. This simplifies file management as their home folder acts as the root directory, allowing global package installations without needing special permissions. This also enhances security by isolating users, preventing a potential breach from compromising the entire system.

Node.js and NPM Integration

With Node.js at its core, NodeOS leverages the vast NPM package repository. Currently boasting over 200,000 packages and growing, this integration could potentially provide NodeOS with millions of applications in the near future.

Linux Kernel Foundation

NodeOS builds upon the widely used Linux kernel, enabling compatibility with applications designed for other Linux distributions, with minimal adjustments.

Current Limitations

While promising, NodeOS is still under development and lacks certain features crucial for a server operating system. Notably absent are common BASH utilities like ps, tail, nano, and grep. Additionally, the lack of a GUI hinders its use as a desktop operating system. While some functionalities can be implemented with JavaScript, their absence by default is a drawback.

Exploring NodeOS

Using Docker

The simplest method to experience NodeOS is through Docker on a Linux or Mac OSX machine (Windows compatibility is untested). After Docker installation, executing the following command initiates the process:

1
sudo docker run -t -i nodeos/nodeos
The easiest and quickest way to try out NodeOS is by using Docker
The easiest and quickest way to try out NodeOS is by using Docker.

Docker automatically downloads the NodeOS image, installs it within a virtual machine, and establishes an SSH connection to the NodeOS shell.

Without Docker

Using the source code offers access to the latest NodeOS version, which might be more recent than the Docker image. However, this approach requires:

  1. A Linux computer (compilation on OSX or Windows is possible but slower)
  2. Linux build tools (make, g++, gcc, autoconf)
  3. Qemu
  4. Significant time

The compilation process involves:

  1. Cloning the repository: bash git clone git@github.com:NodeOS/NodeOS.git.
  2. Navigating to the directory and installing dependencies: cd NodeOS and npm install.
  3. Allocating considerable time for compilation.
  4. Running bash npm start to launch NodeOS within Qemu.

Functionality Check

Upon successful installation, basic functionality can be tested with the ls command, producing an output similar to:

1
[ 'etc', 'lib', 'lib64', 'root', 'bin', 'sys', 'usr', 'share', 'proc' ]

Attempting to use the ifconfig command, however, might result in:

1
command not found: ifconfig

This absence highlights the reliance on NodeOS’s npkg package manager, similar to apt or yum. Installing ifconfig is achieved with:

1
npkg install bin-ifconfig

Subsequently, executing ifconfig should display network information, confirming successful installation:

1
2
3
4
5
6
7
eth0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
  ether 01:23:45:67:89:ab 
  inet6 f0cd::ef01:0203:0405:181%en1 prefixlen 64 scopeid 0x5 
  inet 192.168.0.21 netmask 0xffffff00 broadcast 192.168.0.21
  nd6 options=1<PERFORMNUD>
  media: autoselect
  status: active

Utilizing NodeOS

The true potential of a Node.js-based operating system lies in developing applications solely with Node.js. As an example, let’s create a simple man command functionality, which is not available by default.

Building a NodeOS application with Node.js

Firstly, install a basic text editor called Hipster: npm install -g hipster@0.15.0. Create and save files using commands like hip filename, Ctrl + s, and Ctrl + q for exiting. The following example code is sourced from a NodeOS developer and can be found in the node-bin-man Git repository.

A typical Node.js application starts with a package.json file:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
{
  "name": "bin-man",
  "version": "0.0.1",
  "description": "Format and display manual pages",
  "bin": {
    "man": "man.js"
  },
  "repository": "https://github.com/groundwater/node-bin-man",
  "author": "groundwater",
  "license": "MIT",
  "dependencies": {
    "blessed": "~0.0.22"
  }
}

The parameters like name, version, description, etc., are self-explanatory. The bin field maps the man command to the man.js file. Dependencies are listed under dependencies.

Next, the main code:

1
#!/usr/bin/env node

This shebang line, while not mandatory in NodeOS, instructs the system to execute the script using /usr/bin/env node.

1
2
var fs = require('fs');
var blessed = require('blessed');

The require() function loads the necessary Blessed package.

1
var arg = process.argv[2] || 'bin-man';

This section mimics the default behavior of the man command, displaying its own manual if no other command is specified.

1
2
3
4
5
6
7
8
var path = process.env.HOME + "/lib/node_modules/" + arg + "/README.md";

try{
  var readme = fs.readFileSync(path, 'utf-8');
}catch(e){
  console.log('No README.md for Package ',arg);
  process.exit(-1);
}

The code then checks for a README.md file in the application’s installation path. If found, the content is stored in the readme variable.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
// Create a screen object.
var screen = blessed.screen();

var box = blessed.box({
  content: readme,
  alwaysScroll:true,
  scrollable: true,
});

// Append our box to the screen.
screen.append(box);

Blessed’s API simplifies displaying the content within a created box.

1
2
3
screen.key(['escape', 'q', 'C-c'], function(ch, key) {
  return process.exit(0);
});

This part defines exit functionality using key combinations.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
screen.key(['space','f','j','n'], function(ch, key) {
  box.scroll(box.height);
  screen.render();
});

screen.key(['down'], function(ch, key) {
  box.scroll(1);
  screen.render();
});

screen.key(['up'], function(ch, key) {
  box.scroll(-1);
  screen.render();
});

screen.key(['b','k','p'], function(ch, key) {
  box.scroll(-box.height);
  screen.render();
});

Scrolling through the content is enabled using specific keys.

1
2
box.focus();
screen.render();

Finally, the focus is set on the created box, and the content is rendered. Place these files in the /lib/node_modules/bin-man directory and create a README.md file:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# Man

Author: @groundwater

## Install

npkg install bin-man

## Usage

```
Usage: man PKGNAME

Display a packages README.md file
```

Lastly, create a config file at /etc/bin-man/config.json containing an empty JSON object: {}.

Now, running man within the NodeOS shell should display the created readme file.

Conclusion

This simple example illustrates the ease of developing applications for NodeOS using just Node.js. While still in its early stages, NodeOS holds immense potential. With continued development and the growing popularity of the Node.js ecosystem, it could evolve into a significant operating system. What are your thoughts? Share them in the comments.

Licensed under CC BY-NC-SA 4.0