🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

ramm

Package Overview
Dependencies
Maintainers
1
Versions
61
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

ramm

A Bun library for server management and deployment automation in TypeScript. Write your infrastructure logic in real code — no YAML, no DSL, no templating language to fight with.

latest
Source
npmnpm
Version
0.0.66
Version published
Weekly downloads
67
-15.19%
Maintainers
1
Weekly downloads
 
Created
Source

RAMM

A Bun library for server management and deployment automation in TypeScript. Write your infrastructure logic in real code — no YAML, no DSL, no templating language to fight with.

Why not Ansible?

Ansible is great, but it comes with a cost: you write infrastructure in YAML with Jinja2 templates. The moment your logic gets non-trivial — conditionals, loops, dynamic values — you're fighting the format instead of solving the problem.

RAMM takes a different approach: your deployment scripts are just TypeScript. Full language, real abstractions, IDE support, type checking, any npm package you need. If you know JS, you already know how to write RAMM scripts.

The trade-off is explicit: Ansible gives you a huge module ecosystem and declarative guarantees. RAMM gives you simplicity and the full power of a real programming language. For developers who want to own their deployment code without learning a separate tool, RAMM is the better fit.

How it works

The core pattern is buildAndRunOverSsh: write a script that configures your server (server.ts), then run it from your local machine (client.ts). RAMM compiles the server script with bun build and executes it on the remote host — all commands inside run on the server.

client.ts          →    [bun build]    →    server.ts runs on remote
(local machine)                             (all execCommand calls are local to the server)

Installation

bun add ramm

Quick Start

client.ts — runs on your local machine:

import { buildAndRunOverSsh, Context } from "ramm";

const ctx = new Context({ user: "root", address: "1.2.3.4" });

await buildAndRunOverSsh({
  entrypoint: "./server.ts",
  context: ctx,
});

server.ts — compiled and executed on the remote server:

import {
  installPodman,
  createPodmanCommand,
  runPodmanContainerService,
  setupNftable,
  printBlock,
} from "ramm";

printBlock("Firewall");
await setupNftable({
  allowedIpV4: ["1.2.3.4"],
  allowedPorts: [443],
});

printBlock("Container");
await installPodman();

const cmd = createPodmanCommand({
  name: "app",
  command: "myregistry.io/app:latest",
  envs: [{ name: "PORT", value: "3000" }],
});

await runPodmanContainerService("app", cmd);

API

Context

Describes the server connection.

const ctx = new Context({
  user: "root",
  address: "1.2.3.4",
  sshKey: "~/.ssh/id_ed25519", // optional
  sudo: false,                  // prefix commands with sudo (default: false)
  userspace: false,             // use systemd --user scope (default: false)
});

ctx.getAddress(); // "root@1.2.3.4"

Commands

execCommand(command, props?, context?)

Runs a command locally. Throws on non-zero exit code.

await execCommand("systemctl restart app");
await execCommand("mkdir -p /opt/app", {}, ctx); // with sudo if ctx.sudo = true

execCommandMayError(command, props?, context?)

Same as execCommand but does not throw — returns the result with exit code.

const result = await execCommandMayError("command -v podman", {}, ctx);
if (result.spawnResult.exitCode !== 0) {
  // podman is not installed
}

execCommandOverSsh(command, context)

Runs a command on a remote server over SSH.

await execCommandOverSsh("systemctl restart app", ctx);

copyFilesOverSsh(from, to, context)

Copies files to the remote server using rsync.

await copyFilesOverSsh("./dist/", "/opt/app/dist", ctx);

Build & Deploy

buildAndRunOverSsh({ entrypoint, context })

Compiles a TypeScript script with bun build and runs it on the remote server. This is the primary usage pattern.

await buildAndRunOverSsh({
  entrypoint: "./server.ts",
  context: ctx,
});

passVarsClient(data, context) / passVarsServer(context?)

Passes variables from the local environment into the server script. Call passVarsClient before buildAndRunOverSsh, then passVarsServer inside the server script.

// client.ts
await passVarsClient({ DB_URL: process.env.DB_URL }, ctx);
await buildAndRunOverSsh({ entrypoint: "./server.ts", context: ctx });

// server.ts
const vars = await passVarsServer();
console.log(vars.DB_URL);

Packages

installSystemPackage(package, context?)

Installs a system package. Auto-detects the OS and uses apt or dnf. Skips if already installed.

await installSystemPackage("nftables");

// with explicit config for a custom package
await installSystemPackage({
  name: "nginx",
  command: "nginx",
});

installBunOverSsh(context)

Installs Bun on a remote server.

await installBunOverSsh(ctx);

Podman

installPodman(context?)

Installs Podman and creates the ramm network. Skips if already installed.

await installPodman();

createPodmanCommand(options)

Builds a podman run command string from structured options.

const cmd = createPodmanCommand({
  name: "app",
  command: "myregistry.io/app:latest",
  networks: ["ramm"],           // default: ["ramm"]
  replace: true,                // default: true
  background: true,             // default: true
  envs: [{ name: "PORT", value: "3000" }],
  volumes: [{ from: "/data", to: "/data" }],
});
// "podman run --name app --replace -d --network ramm -e PORT=3000 -v /data:/data myregistry.io/app:latest"

runPodmanContainer(name, command, context?)

Runs a container. Skips if already running with the same command. Recreates if the command changed.

await runPodmanContainer("app", cmd);

runPodmanContainerService(name, command, context?)

Runs a container and registers it as a systemd service for autostart on reboot.

await runPodmanContainerService("app", cmd);

loginPodman(address, login, password, context?)

Authenticates with a container registry.

await loginPodman("registry.example.com", "user", "password");

addNftPodmanRule(context?)

Adds an nftables rule to allow Podman network traffic through the firewall.

await addNftPodmanRule();

Systemd

createSystemdService(name, content, context?)

Writes a unit file, enables and starts the service.

await createSystemdService(
  "app.service",
  `[Unit]
Description=My App

[Service]
ExecStart=bun run /opt/app/server.js
Restart=always

[Install]
WantedBy=multi-user.target`
);

createSystemdUnit(name, content, context?)

Writes a unit file and reloads systemd. Does not start the service.

startSystemdUnit(name, context?) / restartSystemdUnit(name, context?) / enableSystemdUnit(name, context?) / reloadSystemd(context?)

Systemd unit management.

await reloadSystemd();
await enableSystemdUnit("app.service");
await startSystemdUnit("app.service");

getSystemdPathToUnit(name, context?)

Returns the path to the unit file — /etc/systemd/system/ or ~/.config/systemd/user/ for userspace context.

Firewall (nftables)

setupNftable({ allowedIpV4, allowedPorts, context? })

Creates an inet ramm nftables table. Closes all ports except the ones listed, rate-limits SSH, saves the config, and enables autostart.

await setupNftable({
  allowedIpV4: ["1.2.3.4"],  // IPs with unrestricted SSH access
  allowedPorts: [80, 443],
});

SSH Keys

createAndAddSshKey(filePath, comment, context)

Creates an ed25519 key (if it doesn't exist) and adds the public key to authorized_keys on the server.

await createAndAddSshKey("~/.ssh/deploy_key", "deploy", ctx);

addSshKeyToUse({ key, fingerprint, filePath, server, context? })

Saves a private key locally, adds the fingerprint to known_hosts, and configures ~/.ssh/config.

saveSshFingerptint(filePath, context)

Fetches the server's fingerprint and saves it to a file.

addKeyToHostConfig(pathToHost, address, pathToKey, context?)

Adds a Host block to the SSH config.

Files

writeFile(path, content, context?)

Writes a file. Skips if the content is already the same.

await writeFile("/etc/app/config.json", JSON.stringify(config));

writeFileStrUniq(path, str, context?)

Appends a string to a file only if it is not already present.

await writeFileStrUniq("~/.bashrc", 'export PATH="$PATH:/opt/bin"');

Cron

createCron({ time, pathToFile, context? })

Adds a crontab entry. Skips if the entry already exists. Updates the schedule if the file is already in crontab with a different time.

await createCron({
  time: "0 3 * * *",
  pathToFile: "/opt/scripts/backup.sh",
});

Utilities

printBlock(name)

Prints a named block to the console — useful for structuring deployment output.

printBlock("Database"); // → Block: Database

normalizePath(path)

Expands ~/ to an absolute path.

normalizePath("~/.ssh/config"); // "/home/user/.ssh/config"

FAQs

Package last updated on 05 Jul 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts