All posts
zapixexpressmigrationaws-lambdatutorial

Migrating from Express to Zapix on AWS Lambda

Already know Express? You already know 90% of Zapix. This guide walks through migrating a real Express API to a Lambda-native Zapix handler — route by route.

Raihan Sharif Rimon·March 14, 2026·6 min read

If you're running an Express API and want to move it to AWS Lambda — maybe to cut costs, remove server management, or handle unpredictable traffic — Zapix is the fastest path. The API surface is intentionally Express-compatible so the migration is mostly mechanical.

Install Zapix

npm install zapix

Step 1: Replace app initialization

// Express
import express from 'express';
const app = express();
app.use(express.json());

// Zapix — body parsing is built-in, no middleware needed
import { Zapix } from 'zapix';
const app = Zapix();

Step 2: Routes stay the same

Route definitions are identical. If you've used Express, there's nothing new to learn:

// Express
app.get('/users/:id', async (req, res) => {
  const user = await getUser(req.params.id);
  res.json(user);
});

// Zapix — identical API
app.get('/users/:id', async (req, res) => {
  const user = await getUser(req.params.id);
  res.json(user);
});

Step 3: Middleware works the same way

// Auth middleware — same pattern as Express
const requireAuth = async (req, res, next) => {
  const token = req.headers.authorization?.split(' ')[1];
  if (!token) return res.status(401).json({ error: 'Unauthorized' });
  req.user = await verifyToken(token);
  next();
};

app.use('/admin', requireAuth);
app.get('/admin/stats', async (req, res) => {
  res.json(await getStats());
});

Step 4: Replace app.listen() with the Lambda handler export

This is the only structural difference. Instead of calling app.listen(port), you export the Lambda handler using the Zapix adapter:

// Express (remove this)
app.listen(3000, () => console.log('Server running'));

// Zapix (replace with this)
import { handler } from 'zapix/aws';
export const main = handler(app);
ℹ️ Note:Your Lambda function handler must be set to "handler.main" (or whatever filename you use) in your SAM/CDK/Serverless Framework config.

Step 5: Update your Lambda config

template.yaml (SAM)
Resources:
  ApiFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: dist/handler.main
      Runtime: nodejs22.x
      Architectures: [arm64]
      Events:
        Api:
          Type: HttpApi
          Properties:
            Path: /{proxy+}
            Method: ANY

What you get for free

  • Cold-start optimized — Zapix is < 5KB, Express is ~200KB with its transitive deps
  • No server management — Lambda scales to zero, you pay only for actual requests
  • Auto-scaling — Lambda handles concurrency without any configuration
  • TypeScript types — req.params, req.body, req.query are all typed out of the box

The migration for a typical 10-route Express API takes about 30 minutes. Most of that is updating your deployment config, not your application code.

Try Zapix in your next Lambda project

Zero config. TypeScript first. Under 5KB.