Add unofficial_url to node/releases.conf and update the nodedist fetcher/classifier to fetch from both URLs. Raw entries are stored with "official/" or "unofficial/" tag prefixes so they don't overwrite each other. The classifier picks the correct base URL from the prefix. This matches the Node.js releases.js behavior which merges both sources, adding musl, riscv64, loong64, and 7z builds from unofficial.
title, homepage, tagline
| title | homepage | tagline |
|---|---|---|
| Node.js | https://nodejs.org | Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine. |
To update or switch versions, run webi node@<tag>.
(you can use @lts for long-term support, @beta for pre-releases, or @x.y.z
for a specific version)
Files
These are the files / directories that are created and/or modified with this install:
~/.config/envman/PATH.env
~/.local/opt/node/
~/.node/
~/.node_repl_history
~/.npm/
~/.npmrc
Cheat Sheet
Node is great for simple, snappy HTTP(S) servers, and for stitching APIs together with minimal fuss or muss.
Installing node via webi will:
- pick a compatible version from the Node Releases API
- download and unpack to
$HOME/.local/opt/node/ - update your
PATHin$HOME/.config/envman/PATH.env - absolutely leave system file permissions alone
- (no dreaded
sudo npmpermission errors)
- (no dreaded
Hello World
node -e 'console.log("Hello, World!")'
> Hello, World!
How to Lint and Fmt Node Code
Just by installing these alone, most code editors (vim, VS Code, etc) can automatically use them for JavaScript:
npm install --location=global fixjson@1 jshint@2 prettier@3
To run them manually on your code;
- prettier (fmt)
touch .prettierrc.json .prettierignore prettier -w '**/*.{md,js,jsx,html}' - jshintrc (lint)
touch .jshintrc .jshintignore jshint -c ./.jshintrc *.js */*.js - fixjson
(turns JavaScript Objects with comments, trailing commas, etc into actual json)fixjson -i 2 -w ./package.json
To run with GitHub Actions on PRs see "Fmt & Lint Automatically" below.
A Simple Web Server
server.js:
var http = require('http');
var app = function (req, res) {
res.end('Hello, World!');
};
http.createServer(app).listen(8080, function () {
console.info('Listening on', this.address());
});
node server.js
Generate a Secure Random Key
This generates a hex-encoded 128-bit random key.
node -p 'crypto.randomBytes(16).toString("hex")'
This generates a url-safe base64 256-bit random key.
node -p 'crypto.randomBytes(32).toString("base64")
.replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "")'
An Express App
mkdir my-server
pushd my-server/
npm init
npm install --save express
app.js:
'use strict';
var express = require('express');
var app = express();
app.use('/', function (req, res, next) {
res.end('Hello, World!');
});
module.exports = app;
server.js:
'use strict';
var http = require('http');
var app = require('./app.js');
http.createServer(app).listen(8080, function () {
console.info('Listening on', this.address());
});
npm start
How to Reverse Proxy to Node
You can use caddy:
./Caddyfile:
localhost {
# Reverse Proxy to your Node app's API
handle /api/* {
reverse_proxy localhost:3000
}
# Handle static files directly with Caddy
handle /* {
root * ./public/
file_server
}
}
caddy run --config ./Caddyfile
See the Caddy Cheat Sheet for more info, such as how to use
X-SendFile to .
How to Allow Node to bind on 80 & 443
You can... but should you?
Are You Sure?
Typically you should use caddy as a Reverse Proxy (see above).
Yes
On macOS all programs have permissions to use privileged ports by default.
On Linux there are several ways to add network capabilities for privileged ports:
-
Use
setcap-netbindwebi setcap-netbind setcap-netbind caddy -
Use
setcapdirectlymy_caddy_path="$( command -v caddy )" my_caddy_absolute="$( readlink -f "${my_caddy_path}" )" sudo setcap cap_net_bind_service=+ep "${my_caddy_absolute}" -
Add the
--set-cap-net-bindoption toserviceman(see below) -
Update the
systemdconfig directly:CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE
How to run a Node app as a User Service
Also called "Login Item", "Startup Item" or "User Unit", this is how you run a Node app as a Non-System (Unprivileged) Service on Mac, Windows, and Linux:
-
Install
servicemanwebi serviceman -
Use Serviceman to create a Launch Agent (macOS), Startup Item (Windows), or User Unit (Linux):
my_username="$(id -u -n)" serviceman add --agent --name my-node-project -- \ caddy run --config ./Caddyfile --envfile ~/.config/caddy/env -
Manage the service
-
On macOS
# Manage (-w to disable/enable on login) launchctl unload -w ~/Library/LaunchAgents/my-node-project.plist launchctl load -w ~/Library/LaunchAgents/my-node-project.plist # View Logs tail -f ~/.local/share/my-node-project/var/log/my-node-project.log -
On Windows
# Manage serviceman stop caddy serviceman start caddy # View Logs type ~/.local/share/my-node-project/var/log/my-node-project.log | more -
On Linux
# Manage systemctl --user disable my-node-project systemctl --user stop my-node-project systemctl --user enable my-node-project systemctl --user start my-node-project # View Logs journalctl --user -xef -u my-node-project
-
How to run a Node app as a System Service
pushd ./my-node-project/
serviceman add --name 'my-node-project' -- \
npm run start
... with auto-reload in Dev
pushd ./my-node-project/
serviceman add --name 'my-node-project' -- \
npx -p nodemon@3 -- nodemon ./server.js
View Logs & Restart
sudo journalctl -xef -u my-node-project
sudo systemctl restart my-node-project
How to Fmt & Lint Automatically
Here are some useful scripts to have in your package.json, and a sample file
to run them with GitHub Actions (Workflows):
npm run
fmt
lint
bump <major|minor|patch|prerelease>
prepublish # also runs after npm install
# bump
npm pkg set scripts.bump='npm version -m "chore(release): bump to v%s"'
# fmt
npm pkg set scripts.fmt='npm run fixjson && npm run prettier'
npm pkg set scripts.prettier="npx -p prettier@2 -- prettier --write '**/*.{md,js,jsx,json,css,html,vue}'"
npm pkg set scripts.fixjson="npx -p fixjson@1 -- fixjson -i 2 -w '*.json' '*/*.json'"
echo 'node_modules' >> .prettierignore
# lint
npm pkg set scripts.lint='npm run jshint'
npm pkg set scripts.jshint="npx -p jshint@2 -- jshint -c ./.jshintrc ./*.js ./*/*.json"
echo 'node_modules' >> .jshintignore
# prepublish
npm pkg set scripts.prepublish='npm run lint && npm run fmt'
To run these automatically for all PRs on GitHub:
.github/workflows/node.js.yml:
name: Node.js CI
on:
push:
branches: ['main']
pull_request:
jobs:
build:
name: "Fmt, Lint, & Test"
runs-on: ubuntu-latest
strategy:
matrix:
node-version:
- 20.x
- latest
steps:
- uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
- name: "Webi: Install 'shfmt' and 'shellcheck', and update PATH"
run: |
#sh ./_scripts/install-ci-deps
echo "${HOME}/.local/bin" >> $GITHUB_PATH
- run: node --version
- run: npm run fmt
- run: npm clean-install
- run: npm run lint
- run: npm run test
How to Install Node's Linux Dependencies
Typically Node just needs openssl and libstdc++.
# Apline
sudo apk add --no-cache libstdc++ libssl3
# Debian / Ubuntu
sudo apt-get install -y libstdc++6 libssl3