Automate any server with TypeScript.
No YAML. No config files. Just code.
Getting Started · API Reference · Examples
npm install nodevisorimport $, { Packages, Users, UFW, Docker, endpoints } from 'nodevisor';
const $server = $.connect({ host: '10.0.0.10', username: 'root' });
await $server(Packages).install(['curl', 'git']);
await $server(Users).add('runner');
await $server(UFW).allow([endpoints.ssh, endpoints.web, endpoints.webSecure]);
await $server(Docker).install();- TypeScript Native — Full IDE support, autocomplete, and type safety. Use real code — loops, async/await, npm packages — not YAML.
- Agentless — Connects over SSH with nothing to install on remote servers. No daemons, no agents — just a standard SSH connection.
- Cross-Platform — One API for Linux, macOS, and Windows. Auto-detects apt, yum, brew, or winget.
- Safe by Default — Template literal variables are automatically escaped, preventing shell injection.
- Deploy Anywhere — Define your production stack in TypeScript. Deploy Docker Swarm clusters with Traefik, Postgres, Redis, and your app in one command.
The $ function is a shell proxy. Use template literals to run commands locally or remotely with the same API:
import $ from 'nodevisor';
// Local
const hostname = await $`hostname`.text();
// Remote — same API, just add a connection
const $server = $.connect({ host: '10.0.0.10', username: 'root' });
const remoteHostname = await $server`hostname`.text();
// Switch user without creating a new SSH connection
const $runner = $server.as('runner');
await $runner`whoami`.text(); // "runner"Modules give you typed APIs for system management:
import $, { Packages, Users, UFW, Docker, SSH, AuthorizedKeys, endpoints } from 'nodevisor';
const $server = $.connect({ host: '10.0.0.10', username: 'root' });
// System
await $server(Packages).install(['curl', 'git', 'nginx']);
await $server(Users).add('runner');
// Security
await $server(UFW).allow([endpoints.ssh, endpoints.web, endpoints.webSecure]);
await $server(AuthorizedKeys).write(process.env.SSH_PUBLIC_KEY!);
await $server(SSH).disablePasswordAuthentication();
// Docker
await $server(Docker).install();
await $server(Docker).allowUser('runner');Define your entire production stack in TypeScript and deploy with one command:
import { DockerCluster, DockerNode, ClusterUser, Traefik, Postgres, NodeWeb } from 'nodevisor';
const cluster = new DockerCluster({
name: 'production',
nodes: [
new DockerNode({ host: '10.0.0.1' }),
new DockerNode({ host: '10.0.0.2' }),
],
users: [
new ClusterUser({
username: 'root',
privateKeyPath: '~/.ssh/nodevisor_id_ed25519',
}),
],
});
cluster.addDependency(new Traefik({ ssl: { email: 'ops@example.com' } }));
cluster.addDependency(new Postgres({ database: 'app', username: 'app', password: process.env.DB_PASSWORD! }));
cluster.addDependency(new NodeWeb({ name: 'api', appDir: './apps/api', domains: ['api.example.com'], port: 3000 }));
// Provision servers and deploy everything
await cluster.setup();
await cluster.deploy();Or use the CLI:
nv setup production.ts --generate-keys
nv deploy production.ts| Ansible | Nodevisor |
|---|---|
# playbook.yml
---
- hosts: webservers
become: yes
tasks:
- name: Install packages
apt:
name: "{{ item }}"
state: present
loop:
- curl
- git
- docker.io
- name: Create deploy user
user:
name: runner
shell: /bin/bash
- name: Configure UFW
ufw:
rule: allow
port: "{{ item }}"
proto: tcp
loop:
- "22"
- "80"
- "443"
- name: Enable UFW
ufw:
state: enabled |
// .nodevisor/setup.ts
import $, {
Packages, Users, UFW,
Docker, endpoints,
} from 'nodevisor';
const $s = $.connect({
host: '10.0.0.10',
username: 'root',
});
await $s(Packages).install(['curl', 'git']);
await $s(Users).add('runner');
await $s(UFW).allow([
endpoints.ssh,
endpoints.web,
endpoints.webSecure,
]);
await $s(UFW).start();
await $s(Docker).install(); |
All packages are available individually or through the nodevisor umbrella package.
Core
- @nodevisor/shell — Shell execution, SSH connections, command builder, and module system
- @nodevisor/endpoint — Network endpoint definitions and protocol constants
- @nodevisor/schema — Zod validation schemas for user configuration
System
- @nodevisor/os — Cross-platform OS detection and system commands
- @nodevisor/fs — File system operations over local and remote connections
- @nodevisor/env — Environment variable management
- @nodevisor/packages — Package manager abstraction (apt, yum, brew, winget)
- @nodevisor/services — Systemd service management
- @nodevisor/pwsh — PowerShell command execution
Security
- @nodevisor/auth — User password management
- @nodevisor/users — System user management
- @nodevisor/groups — System group management
- @nodevisor/authorized-keys — SSH authorized keys management
- @nodevisor/ssh — OpenSSH server installation and hardening
- @nodevisor/ufw — UFW firewall management
- @nodevisor/firewall — High-level firewall abstraction
Orchestration
- @nodevisor/docker — Docker, Swarm, Compose, and pre-built services (Traefik, Postgres, Redis, etc.)
- @nodevisor/cluster — Abstract cluster orchestration primitives
- @nodevisor/builder — Abstract image builder interface
- @nodevisor/registry — Abstract container registry interface
- @nodevisor/aws — AWS CLI and Elastic Container Registry (ECR)
Tools
- @nodevisor/cli — CLI for setup, deployment, and remote connections
- Linux: Ubuntu 20+, Debian 11+, Fedora 39+
- macOS: macOS 12+
- Windows: Windows 10+ (PowerShell required)
Full documentation at nodevisor.com
Nodevisor uses a single O'Saasy license across all packages. See LICENSE for full terms.
Open an issue on GitHub.
