Run JavaScript services with zero infrastructure overhead
Note: M3M is currently in active development. Some features may be incomplete, unstable, or subject to change. Use in production at your own risk.
- Why M3M?
- Example
- Service Lifecycle
- Performance
- Installation
- From Source (Manual)
- CLI Commands
- Accessing Services
- Development
- License
We live in an era where deploying a simple 50-line integration or a webhook handler requires a Dockerfile, a docker-compose.yml, 500MB of Node.js base images, and a bunch of external dependencies.
Your VPS is bloated with layers, your RAM is consumed by identical Node processes, and updating a single line of code feels like a ritual.
M3M was born to kill this complexity. It is a single, lightweight binary that acts as a private ecosystem for your scripts.
Instead of managing separate containers for every task, you have one environment that provides everything out of the box.
M3M is for developers who want to write logic in the browser (or their editor), hit Save, and walk away. It's for those who value their time and their server resources.
- No more NPM dependency hell for micro-tasks
- No more Docker storage anxiety
- No more cloud bills for things that should run on your $5 VPS
$service.boot(() => {
const users = $database.collection('users');
// HTTP Endpoint
$router.get('/users', (ctx) => {
return { users: users.find({}) };
});
$router.post('/users', (ctx) => {
const user = users.insert(ctx.body);
return { user };
});
// Cron Task (Every hour)
$schedule.every('1h', () => {
$logger.info('Total users:', users.count({}));
});
});
$service.start(() => {
$logger.info('Service is ready!');
});Built-in modules (accessed with $ prefix):
- Core:
$service,$router,$schedule,$logger,$env - Data:
$database,$storage,$goals - Network:
$http,$smtp - Utils:
$crypto,$encoding,$utils,$delayed,$validator - Media:
$image,$draw
Every service has three lifecycle phases managed by the $service module:
Initialize your service, set up routes, and configure modules.
$service.boot(() => {
// Set up routes
$router.get('/hello', (ctx) => {
return { message: 'Hello World!' };
});
// Configure scheduler
$schedule.every('1h', () => {
$logger.info('Hourly task running');
});
});Called when service is ready. Good for initial data loading.
$service.start(() => {
$logger.info('Service started!');
// Load initial data, etc.
});Called when service is stopping. Clean up resources here.
$service.shutdown(() => {
$logger.info('Service stopping...');
// Close connections, save state, etc.
});Runs comfortably on a $5/mo VPS with 512MB RAM alongside 20+ active services. The Go binary + embedded UI weighs ~30MB. No Node.js runtime, no container layers.
# Download script
curl -fsSL https://raw.githubusercontent.com/levskiy0/m3m/main/m3m.sh -o m3m.sh
chmod +x m3m.sh
# Install latest release
./m3m.sh install
# Or install specific version
./m3m.sh install v1.0.0
# Or install development version
./m3m.sh install mainThis will:
- Clone the repository to
.m3m/src - Build Docker image locally
- Generate config file with random JWT secret
# Start server
./m3m.sh start
# Create admin user
./m3m.sh admin admin@example.com yourpassword
# View logs
./m3m.sh logsOpen http://localhost:8080 and login.
./m3m.sh install [version] # Install (latest, v1.0.0, or main)
./m3m.sh update [version] # Update to version
./m3m.sh rebuild # Rebuild image (after adding plugins)
./m3m.sh start # Start the container
./m3m.sh stop # Stop the container
./m3m.sh restart # Restart the container
./m3m.sh logs # Show container logs
./m3m.sh status # Show container status
./m3m.sh version # Show installed/latest versions
./m3m.sh admin <email> <pw> # Create admin user
./m3m.sh config # Show config
./m3m.sh uninstall # Remove M3M (keeps data).m3m/
├── config # Configuration file
├── version # Installed version
├── src/ # Repository clone
├── plugins/ # Plugin sources (copy here, then rebuild)
└── data/ # Persistent data (mounted to container)
├── storage/ # File storage for services
├── plugins/ # Compiled plugins (.so files)
├── logs/ # Application logs
└── mongodb/ # MongoDB database files
# Copy plugin source to plugins directory
cp -r my-telegram-plugin .m3m/plugins/
# Rebuild image (plugins are compiled during build)
./m3m.sh rebuildEdit .m3m/config:
# M3M Configuration
M3M_PORT=8080
M3M_JWT_SECRET=<auto-generated>
M3M_SERVER_URI=http://localhost:8080| Variable | Default | Description |
|---|---|---|
M3M_PORT |
8080 |
Server port |
M3M_JWT_SECRET |
auto | JWT signing secret (auto-generated) |
M3M_SERVER_URI |
http://localhost:8080 |
Public server URI |
# Clone
git clone https://github.com/levskiy0/m3m.git
cd m3m
# Build (requires Go 1.24+, Node.js 20+)
make build
# Create first admin user
./build/m3m new-admin admin@example.com yourpassword
# Run
./build/m3m serveYou can also just download the binary and run — zero configuration required:
# Download binary from releases
./m3m new-admin admin@example.com yourpassword
./m3m serveOn first run, M3M automatically creates config.yaml with:
- SQLite database (embedded, no external server needed)
- Random JWT secret (secure by default)
Note: Docker installation via
m3m.shis recommended for production as it includes automatic updates, backup management, and proper process supervision.
Default config file: config.yaml (auto-created on first run)
server:
host: "0.0.0.0"
port: 8080
uri: "http://127.0.0.1:8080"
database:
driver: "sqlite" # "mongodb" or "sqlite"
# MongoDB - external server required
mongodb:
uri: "mongodb://localhost:27017"
database: "m3m"
# SQLite - embedded, no external dependencies (default)
sqlite:
path: "./data"
database: "m3m"
jwt:
secret: "change-me-in-production"
expiration: 168h
storage:
path: "./storage"
logging:
level: "info"
path: "./logs"| Driver | Config | Requirements |
|---|---|---|
sqlite |
driver: "sqlite" |
None — embedded in binary |
mongodb |
driver: "mongodb" |
External MongoDB server |
SQLite mode uses embedded FerretDB with SQLite backend. All MongoDB query syntax ($eq, $gt, $in, etc.) works identically in both modes — switch anytime without code changes.
# Start server
m3m serve
# Start with custom config
m3m serve -c /path/to/config.yaml
# Create root admin
m3m new-admin admin@example.com yourpassword
# Check version
m3m versionOnce running, your service endpoints are available at:
GET /r/{project-slug}/your-route
POST /r/{project-slug}/your-route
make init # Initialize project
make dev # Run backend in dev mode
make web-dev # Run frontend dev server
make test # Run tests
make docs # Generate JavaScript API docs (CODE.md)M3M includes an MCP server for Claude Code. It provides access to the JavaScript runtime API documentation.
# Build MCP server
make build-mcp
# Add to Claude Code
claude mcp add m3m-api ./build/m3m-mcp
# Verify connection
claude mcp listNow Claude knows the M3M API and can help write services.
MIT
