Перейти к основному содержимому

When to Use Xec

Xec is powerful, but it's not the right tool for every situation. This guide helps you determine when Xec is the best choice for your project.

Perfect Use Cases

1. Multi-Environment Orchestration

Scenario: You need to coordinate operations across local, SSH, Docker, and Kubernetes environments.

Why Xec: Unified API eliminates the complexity of juggling multiple tools.

// Deploy across environments with one API
await $`npm run build`; // Build locally
await $.ssh({ host: 'staging' })`docker pull`; // Update staging
await $.k8s({ pod: 'web', namespace: 'default' })`curl /health`; // Verify in K8s

2. DevOps Automation Scripts

Scenario: Writing deployment, backup, or maintenance scripts.

Why Xec: Replace complex bash scripts with maintainable JavaScript/TypeScript.

// Readable, maintainable deployment script
async function deploy(environment) {
const server = $.ssh({ host: `${environment}.example.com`, username: 'deploy' });

// Backup current version
await server`cp -r /app /backup/app-$(date +%Y%m%d)`;

// Deploy new version
await server`git pull`;
await server`npm install`;
await server`npm run build`;
await server`pm2 restart app`;

// Verify deployment
const result = await server`curl -s localhost:3000/health`;
const health = JSON.parse(result.stdout);
if (!health.ok) throw new Error('Health check failed');
}

3. CI/CD Pipelines

Scenario: Building continuous integration and deployment pipelines.

Why Xec: Consistent execution across different CI environments.

// CI pipeline script
async function runCI() {
// Run tests in parallel
await $.parallel.all([
$`npm test`,
$`npm run lint`,
$`npm run type-check`
]);

// Build in Docker
await $.docker({ image: 'node:20' })
.volumes([`${process.cwd()}:/app`])
.workdir('/app')
`npm run build`;

// Deploy if on main branch
if (process.env.BRANCH === 'main') {
await $.ssh({ host: 'prod' })`./deploy.sh`;
}
}

4. Container Management

Scenario: Managing Docker containers across multiple hosts.

Why Xec: Simplified container operations with automatic resource cleanup.

// Manage containers across hosts
async function updateContainers(hosts) {
await $.batch(hosts.map(host =>
$.ssh({ host, username: 'deploy' })
`docker pull myapp:latest && docker restart app`
), { concurrency: 3 });
}

5. System Administration

Scenario: Managing multiple servers and performing routine maintenance.

Why Xec: Execute commands across server fleets with error handling.

// System maintenance across servers
async function performMaintenance(servers) {
for (const server of servers) {
const ssh = $.ssh({ host: server, username: 'admin' });

// Check disk space
const result = await ssh`df -h`;
if (result.stdout.includes('100%')) {
await ssh`find /tmp -mtime +7 -delete`;
}

// Update packages
await ssh`apt update && apt upgrade -y`.nothrow();

// Restart services if needed
await ssh`systemctl restart nginx`;
}
}

6. Testing Infrastructure

Scenario: Setting up and tearing down test environments.

Why Xec: Reliable environment management with proper cleanup.

// Test environment setup
async function setupTestEnv() {
// Start test database
await $.docker({ image: 'postgres:14', autoRemove: true })
.env({ POSTGRES_PASSWORD: 'test' })
`postgres`;

// Run tests in app container
await $.docker({ image: 'app:test', autoRemove: true })
.env({ DATABASE_URL: 'postgres://localhost:5432' })
`npm test`;

// Cleanup happens automatically with autoRemove
}

7. Development Tooling

Scenario: Creating development tools and utilities.

Why Xec: Quick script development with powerful capabilities.

// Development helper tool
async function syncDatabase(from, to) {
const source = $.ssh({ host: from, username: 'dbadmin' });
const target = $.ssh({ host: to, username: 'dbadmin' });

// Dump from source
await source`pg_dump app > /tmp/dump.sql`;

// Transfer to target (using scp)
await $`scp ${from}:/tmp/dump.sql ${to}:/tmp/dump.sql`;

// Restore on target
await target`psql app < /tmp/dump.sql`;
}

Good Use Cases

Log Aggregation

Collecting and processing logs from multiple sources.

Monitoring Scripts

Checking service health across environments.

Data Processing Pipelines

Orchestrating data processing across systems.

Migration Scripts

Moving data or applications between environments.

Backup Automation

Coordinating backups across multiple systems.

When NOT to Use Xec

1. High-Performance Requirements

Issue: JavaScript overhead for command execution.

Alternative: Use native system programming languages (C, Rust, Go).

2. Simple, Single-Environment Scripts

Issue: Overhead for simple local scripts.

Alternative: Use basic shell scripts or Node.js child_process.

# Simple enough for bash
#!/bin/bash
echo "Hello"
ls -la

3. Real-Time Systems

Issue: Non-deterministic execution timing.

Alternative: Use specialized real-time frameworks.

4. GUI Applications

Issue: Xec is designed for command-line operations.

Alternative: Use GUI frameworks like Electron or native toolkits.

5. Long-Running Services

Issue: Xec is designed for command execution, not service hosting.

Alternative: Use proper service managers (systemd, PM2, Kubernetes).

Decision Framework

Ask yourself these questions:

1. Do you need to execute commands?

  • Yes → Consider Xec
  • No → Look elsewhere

2. Do you work with multiple environments?

  • Yes → Xec is ideal
  • No → Xec might be overkill

3. Do you value maintainability over raw performance?

  • Yes → Xec is a good fit
  • No → Consider lower-level tools

4. Do you need type safety and modern JavaScript features?

  • Yes → Xec provides both
  • No → Shell scripts might suffice

5. Is your team familiar with JavaScript/TypeScript?

  • Yes → Xec will feel natural
  • No → Consider the learning curve

Comparison with Alternatives

vs. Shell Scripts

  • Xec: Type safety, better error handling, testing support
  • Shell: Simpler for basic tasks, no runtime dependency

vs. Ansible/Terraform

  • Xec: More flexible, programmatic control, real-time execution
  • IaC Tools: Better for declarative infrastructure

vs. Node.js child_process

  • Xec: Unified API, built-in safety, multi-environment support
  • child_process: Lower overhead for simple local execution

vs. SSH Libraries

  • Xec: Simpler API, connection pooling, automatic escaping
  • SSH Libraries: More control over SSH-specific features

vs. Docker/K8s SDKs

  • Xec: Unified interface, simpler commands
  • Native SDKs: Full API access, more features

Performance Considerations

Xec is suitable when:

  • Command execution time dominates (not startup overhead)
  • Convenience and safety outweigh microsecond optimizations
  • You can leverage caching and connection pooling

Xec may not be suitable when:

  • Executing thousands of tiny commands per second
  • Microsecond latency is critical
  • Memory footprint must be minimal

Security Considerations

Xec is secure for:

  • Handling user input (automatic escaping)
  • Managing credentials (secure storage)
  • Multi-tenant environments (isolation)

Additional security needed for:

  • Highly regulated environments (add audit logging)
  • Zero-trust networks (add encryption layers)
  • Compliance requirements (implement specific controls)

Conclusion

Xec shines when you need to:

  • Orchestrate commands across multiple environments
  • Automate DevOps and system administration tasks
  • Simplify complex shell scripting with modern JavaScript
  • Maintain readable, testable infrastructure code

Choose Xec when the benefits of a unified, safe, and maintainable API outweigh the overhead of a JavaScript runtime. For most DevOps, automation, and orchestration tasks, Xec provides the perfect balance of power and simplicity.