DEV Community

Cover image for Stop Containerizing Your 50-Line Scripts
Levskiy
Levskiy

Posted on

Stop Containerizing Your 50-Line Scripts

Stop Wrapping 50 Lines of Code in a 500MB Container: Why I Built M3M

We’ve all been there.

You need to deploy a simple webhook handler. It’s maybe 50 lines of code. You open your editor, write the logic in 15 minutes, and then the real work begins:

  1. Write a Dockerfile.
  2. Set up docker-compose.yml.
  3. Pull a 500MB Node.js base image.
  4. Wait for npm install to finish.
  5. Configure environment variables.
  6. Set up a reverse proxy.

All of this for 50 lines of code?

I got tired of it. My $5 VPS was bloating with container layers. Every micro-task I deployed ran in its own isolated Node.js process, eating up RAM I didn't have. Updating a single line of code felt like a deployment ritual.

I wanted to write code, hit "Save", and have it run. No build steps, no containers, no overhead.

So, I built M3M.


What is M3M?

M3M (Mini Services Manager) is a single Go binary that acts as a private runtime for your JavaScript services.

Think of it as a lightweight application server. You don't need containers. You don't need package.json. You don't get stuck in npm dependency hell. It’s designed specifically to run the small utility scripts that power your infrastructure without becoming the infrastructure itself.

Show Me the Code

Here is a complete, working service. It has an API endpoint, database persistence, and a scheduled background task.

$service.boot(() => {
  const users = $database.collection('users');

  // 1. HTTP Endpoint
  $router.get('/users', (ctx) => {
    return { users: users.find({}) };
  });

  $router.post('/users', (ctx) => {
    const user = users.insert(ctx.body);
    return { user };
  });

  // 2. Cron Task (Runs every hour)
  $schedule.every('1h', () => {
    $logger.info('Total users:', users.count({}));
  });
});

$service.start(() => {
  $logger.info('Service is ready!');
});

Enter fullscreen mode Exit fullscreen mode

That's it. No imports. No boilerplate. You write this in the browser-based UI, hit Save, and it’s live.

"Batteries Included" (No npm required)

One of my main goals was to avoid npm install. M3M exposes a powerful standard library via the $ prefix. Everything you typically need for micro-services is already there:

Category Modules
Core $service, $router, $schedule, $logger, $env
Data $database, $storage, $goals
Network $http, $mail
Utils $crypto, $encoding, $utils, $validator
Media $image, $draw

1. Routing with Middleware

Need authentication? It's just a function.

$service.boot(() => {
  // Simple Auth Middleware
  const auth = (ctx) => {
    const token = ctx.header('Authorization');
    if (!token) {
      ctx.status(401);
      return { error: 'Unauthorized' };
    }
  };

  // Protected routes
  const api = $router.group('/api', auth);

  api.get('/profile', (ctx) => {
    return { user: ctx.get('user') };
  });
});

Enter fullscreen mode Exit fullscreen mode

2. Built-in Database

M3M includes a persistent document store with MongoDB-style syntax. No external DB required.

const posts = $database.collection('posts');

// Query with operators
const popular = posts.find({
  views: { $gte: 100 },
  tags: { $contains: 'featured' }
});

// Update
posts.update(
  { _id: post._id },
  { $inc: { views: 1 } }
);

Enter fullscreen mode Exit fullscreen mode

3. Scheduling

Forget crontab. Handle your recurring tasks right alongside your API logic.

// Simple interval
$schedule.every('5m', () => {
  $logger.info('Checking for updates...');
});

// Complex Cron expression (Every day at 9 AM)
$schedule.cron('0 9 * * *', () => {
  sendDailyReport();
});

Enter fullscreen mode Exit fullscreen mode

Performance That Makes Sense

This is why I built it.

M3M runs comfortably on a $5/month VPS with 512MB RAM. I currently have 20+ active services running inside a single M3M instance.

The entire binary (including the web UI) is ~30MB.
Compare that to a typical Docker setup where each Node.js container takes 100-200MB minimum.

AI Integration (Claude MCP)

We live in the AI era, so I made sure M3M plays nice with LLMs. M3M includes an MCP (Model Context Protocol) server.

If you use Claude Code, you can connect it directly to M3M:

make build-mcp
claude mcp add m3m-api ./build/m3m-mcp

Enter fullscreen mode Exit fullscreen mode

Now you can simply ask Claude:

"Write me an M3M service that monitors a website and sends alerts via email when it's down"

Claude knows the M3M API context ($http, $mail, $schedule) and will generate working code instantly.

Who is this for?

I didn't build M3M to replace Kubernetes or compete with AWS Lambda. I built it for practical developers who have better things to do than debug Docker networks.

It shines for:

  • Webhook handlers (Stripe, GitHub, etc.)
  • Telegram/Discord bots (Self-hosted without the container tax)
  • Internal APIs & Tools
  • Cron jobs with a nice UI
  • Data scrapers and ETL pipelines

Getting Started

If you're tired of the bloat, give it a try.

# Clone
git clone https://github.com/levskiy0/m3m.git
cd m3m

# Build (Go 1.24+ required)
make build

# Create admin and run
./build/m3m new-admin admin@example.com yourpassword
./build/m3m serve

Enter fullscreen mode Exit fullscreen mode

Star the repo if you hate writing Dockerfiles as much as I do: github.com/levskiy0/m3m

Top comments (0)