Simpatico
The simpatico server.js
is an http/https/websocket server. It can serve literate markdown without a build-step, supports Let's Encrypt for SSL/TLS, has privacy-preserving headers, and caches it's responses. It answers the question: what is the smallest most secure and privacy-preserving way to offer a fun, fast build-test-debug cycle for web experiments? It's kind of like codepen.io but where you own the files, use your own editor, can run it locally, can modify it to your taste, and even run it in production. Alternatively, it's a bit like React's create-react-app but without the build-step and much simpler, approachable code.
The simpatico
npm module exposes a small set of isomorphic vanilla javascript libraries with no dependencies: utility functions core
, a transducer function combine
, a novel multiverse data structure stree
, and a runtime type system called friendly
.
Server Installation
Requirements
- Linux-like OS (Linux, macOS, Windows WSL)
- Node 17+
- pnpm 10+
Tip: Install requirements with mise with
curl https://mise.run | sh
and thenmise use node@latest pnpm@latest
within your project directory to easily meet the runtime requirements without affecting your global toolchain. Mise (pronounced 'meez') is a modern tool that replaces and improves many version managers likenvm
,rvm
, andsdkman
. No affiliation! Notenpm
andyarn
may be supported in lieu ofpnpmp
, but untested.
Note Rather than cloning this repository, consider forking this repo and cloning the fork.
Running in Development
git clone git@github.com:simpaticoder/simpatico.git
pnpm install
node server.js
At this point you have a running simpatico server and can add/remove/modify files and they will update without a server restart. The main feature you get is a very fast literate markdown BTD loop.
Development HTTPS
HTTPS is a requirement for any modern production server, and so you should use it for local testing as well.
make-certs.sh
is a helper script to generate a self-signed certificate for testing purposes. It does the following:
- Create your own root CA
- Use the root CA to generate your own
<domain>.crt.pem
and<domain>.key.pem
files - Run
simpatico
with an argument that points to the generated certificate files - (only for non .localhost domains) Install the root CA in all testing browsers on all devices (e.g. nav to
about:settings
, searchcertificates
, then follow the UI to add~/.ssh/RootCA
)
The make-certs
script will generate the correct files and output a simpatico
command line that will work for your mode of operation
(testing/production + privileged/unprivileged ports). Here is an example generating certs for domain simpatico.localhost
:
alias p=pnpm
p make-certs simpatico.localhost
# Lots of descriptive output describing what to do next..
# ...run on the default unprivileged ports
p simpatico '{"cert":"./simpatico.localhost.crt.pem","key":"./simpatico.localhost.key.pem", "useTls":true}'
Running in Production
Important note as of 8/25/2025 dropping process privileges is not functional.
It's not clear why but until it is, you must run simpatico
as root.
There is a test script, `test/test-suid.js' that reproduces the issue.
Privileged Ports
simpatico
can bind to ports < 1024 and drop privileges immediately if run as root via sudo
.
Both node
and pnpm
must be available to root and on its path, which is non-interactive (so don't bother with /root/.bashrc
)
Assuming you've installed mise
as root, add its tools to the non-interactive root path like so:
sudo visudo
# Add mise/shims
Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin:/root/.local/share/mise/shims"
Now execute as root, binding to privileged ports, dropping privileges to user alice
, and serving on https:
sudo pnpm simpatico '{"cert":"./simpatico.localhost.crt.pem","key":"./simpatico.localhost.key.pem", "useTls":true, "http":80, "https":443, "ws":443, "runAsUser":"alice"}'
We may run node
as root, but we mitigate that by dropping privileges asap, just like other production servers.
We also do not want to run mise
and pnpm
as root, but again, we do so only briefly.
apt install nginx
is highly trusted mainly because it is well-known, but has it's own (supply chain, operational) risk.
Networking and DNS
Domains ending in .localhost
do not need an entry in /etc/hosts
to be served locally. Other domains either need an entry or a static ip and dns entry in your router.
Windows WSL2 users may need to connect the WSL loopback address to the external address: netsh interface portproxy add v4tov4 listenport=443 listenaddress=0.0.0.0 connectport=443 connectaddress=192.168.X.X
Using a proxy server
Why not just proxy behind nginx
or caddy
? You can. It is the industry standard and in some ways simplifies running simpatico
(no need to run with sudo or with TLS).
This is absolutely necessary if you want to host multiple domains.
For beginners, running simpatico as a single stand-alone process makes it simpler to get started, especially in the mental model of a single process.
A strong argument for the conventional proxy is it's enormous feature-set - nginx can serve many domains, for example, where simpatico cannot. Nginx is far more standards compliant; simpatico does the bare minimum HTTP/1.1 and does not support all MIME types and has inflexible headers. As with all software tools, there are tradeoffs.
© 2025 simpatico