Skip to content

Deploying an ElysiaJS App

ElysiaJS is a fast, modern, and lightweight web framework for Node.js, designed for building scalable APIs and web applications with minimal overhead. It features a simple API, TypeScript support out of the box, and a focus on performance, making it ideal for both small projects and enterprise-grade services. ElysiaJS is perfect for developers building REST APIs, real-time applications, and microservices that require high throughput with low latency.

This comprehensive guide walks you through deploying an ElysiaJS application to Klutch.sh, covering both automatic Nixpacks-based deployments and Docker-based deployments. You’ll learn installation steps, explore sample code, configure environment variables, and discover best practices for production deployments.

Table of Contents

  • Prerequisites
  • Getting Started: Install ElysiaJS
  • Sample Code Examples
  • Deploying Without a Dockerfile (Nixpacks)
  • Deploying With a Dockerfile
  • Environment Variables & Configuration
  • Scaling & Performance
  • Troubleshooting
  • Resources

Prerequisites

To deploy an ElysiaJS application on Klutch.sh, ensure you have:

  • Node.js 18 or higher - ElysiaJS requires a modern Node.js version for full TypeScript support
  • npm or yarn - For managing dependencies
  • Git - For version control
  • GitHub account - Klutch.sh integrates with GitHub for continuous deployments
  • Klutch.sh account - Sign up for free

Getting Started: Install ElysiaJS

Create a New ElysiaJS Project

Follow these steps to create a new ElysiaJS application:

  1. Open your terminal and create a new directory for your project:
    Terminal window
    mkdir my-elysia-app
    cd my-elysia-app
  2. Initialize npm and install ElysiaJS:
    Terminal window
    npm init -y
    npm install elysia
  3. Create a basic ElysiaJS app. Create a file called `index.ts` (or `index.js`):
    import { Elysia } from 'elysia';
    const app = new Elysia()
    .get('/', () => 'Hello from ElysiaJS on Klutch.sh!')
    .get('/api/health', () => ({ status: 'healthy' }))
    .listen(process.env.PORT || 3000);
    console.log(`Server running on port ${app.server?.port}`);
  4. Update your `package.json` to include necessary scripts:
    {
    "name": "my-elysia-app",
    "version": "1.0.0",
    "type": "module",
    "scripts": {
    "start": "node index.ts",
    "dev": "bun run --hot index.ts"
    },
    "dependencies": {
    "elysia": "latest"
    },
    "devDependencies": {
    "typescript": "latest"
    }
    }
  5. Test your app locally:
    Terminal window
    npm run dev

    Visit http://localhost:3000 to see your app running. Check the health endpoint at http://localhost:3000/api/health.


Sample Code Examples

Basic HTTP Server with Multiple Routes

Here’s a more complete example with multiple routes, request validation, and error handling:

import { Elysia, t } from 'elysia';
const app = new Elysia()
.get('/', () => 'Welcome to ElysiaJS on Klutch.sh!')
.get('/api/health', () => ({
status: 'healthy',
timestamp: new Date().toISOString()
}))
.post('/api/greet',
({ body }) => ({
message: `Hello, ${body.name}!`
}),
{
body: t.Object({
name: t.String()
})
}
)
.get('/api/users/:id', ({ params: { id } }) => ({
id: parseInt(id),
name: 'John Doe',
email: 'john@example.com'
}))
.listen(process.env.PORT || 3000);
console.log(`Server running on port ${app.server?.port}`);

JSON API with Query Parameters

import { Elysia } from 'elysia';
const app = new Elysia()
.get('/api/posts', ({ query: { page, limit } }) => {
const pageNum = parseInt(page || '1');
const limitNum = parseInt(limit || '10');
return {
page: pageNum,
limit: limitNum,
total: 100,
posts: [
{ id: 1, title: 'First Post', author: 'Alice' },
{ id: 2, title: 'Second Post', author: 'Bob' }
]
};
})
.listen(process.env.PORT || 3000);
export default app;

Database Integration with Prisma

import { Elysia } from 'elysia';
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
const app = new Elysia()
.get('/api/users', async () => {
return await prisma.user.findMany();
})
.post('/api/users', async ({ body }) => {
return await prisma.user.create({
data: body as any
});
})
.onStop(() => prisma.$disconnect())
.listen(process.env.PORT || 3000);
export default app;

Deploying Without a Dockerfile

Klutch.sh uses Nixpacks to automatically detect and build your ElysiaJS application. This is the simplest deployment option that requires no additional configuration files.

  1. Push your ElysiaJS application to a GitHub repository with all your source code and `package.json` file.
  2. Log in to your Klutch.sh dashboard.
  3. Create a new project and give it a name (e.g., "My API").
  4. Create a new app with the following configuration: - **Repository**: Select your ElysiaJS GitHub repository and the branch to deploy - **Traffic Type**: Select HTTP (default for web applications) - **Internal Port**: Set to 3000 (the default port for ElysiaJS) - **Region**: Choose your preferred region for deployment - **Compute**: Select the appropriate compute resource size - **Instances**: Choose how many instances to run (start with 1 for testing) - **Environment Variables**: Add any environment variables your app needs (API keys, database URLs, etc.)

    If you need to customize the start command or build process, you can set Nixpacks environment variables:

    • START_COMMAND: Override the default start command (e.g., node index.ts)
    • BUILD_COMMAND: Override the default build command
  5. Click "Create" to deploy. Klutch.sh will automatically detect your Node.js project, install dependencies, and start your ElysiaJS application.
  6. Once deployed, your app will be available at a URL like `example-app.klutch.sh`. Test it by visiting the URL in your browser.

Deploying With a Dockerfile

If you prefer more control over the build and runtime environment, you can use a Dockerfile. Klutch.sh will automatically detect and use any Dockerfile in your repository’s root directory.

  1. Create a `Dockerfile` in your project root:
    # Multi-stage build for optimized ElysiaJS deployment
    FROM node:18-alpine AS builder
    WORKDIR /app
    # Copy package files
    COPY package*.json ./
    # Install dependencies
    RUN npm ci
    # Copy source code
    COPY . .
    # Production stage
    FROM node:18-alpine
    WORKDIR /app
    # Copy built app from builder
    COPY --from=builder /app/node_modules ./node_modules
    COPY --from=builder /app/package*.json ./
    COPY --from=builder /app . .
    # Set production environment
    ENV NODE_ENV=production
    # Expose port (must match your app's listening port)
    EXPOSE 3000
    # Health check
    HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
    CMD node -e "require('http').get('http://localhost:3000/api/health', (r) => {if (r.statusCode !== 200) throw new Error(r.statusCode)})"
    # Start the application
    CMD ["npm", "start"]
  2. Create a `.dockerignore` file to exclude unnecessary files from the Docker build:
    node_modules
    npm-debug.log
    dist
    .git
    .gitignore
    README.md
    .env
    .env.local
    .vscode
    .idea
  3. Push your code (with Dockerfile and .dockerignore) to GitHub.
  4. Follow the same deployment steps as the Nixpacks method:
    • Log in to Klutch.sh
    • Create a new project
    • Create a new app pointing to your GitHub repository
    • Set the traffic type to HTTP and internal port to 3000
    • Add any required environment variables
    • Click “Create”

    Klutch.sh will automatically detect your Dockerfile and use it to build and deploy your application.

  5. Your deployed app will be available at `example-app.klutch.sh` once the build and deployment complete.

Environment Variables & Configuration

ElysiaJS applications can use environment variables for configuration. Set these in the Klutch.sh dashboard during app creation or update them afterward.

Common Environment Variables

# Server configuration
PORT=3000
NODE_ENV=production
# Database connection
DATABASE_URL=postgresql://user:password@db.example.com:5432/mydb
# API Keys
API_KEY=your_api_key_here
SECRET_KEY=your_secret_key_here
# CORS configuration
CORS_ORIGIN=https://yourdomain.com

Using Environment Variables in Your App

import { Elysia } from 'elysia';
const app = new Elysia()
.get('/config', () => ({
environment: process.env.NODE_ENV,
apiKey: process.env.API_KEY ? '***hidden***' : 'not set'
}))
.listen(process.env.PORT || 3000);

Customizing Build and Start Commands with Nixpacks

If using Nixpacks deployment without a Dockerfile, you can customize build and start commands:

BUILD_COMMAND: npm run build
START_COMMAND: npm start

Set these as environment variables during app creation on Klutch.sh.


Scaling & Performance

Horizontal Scaling

Klutch.sh makes it easy to scale your ElysiaJS application:

  • Multiple Instances: Set the number of instances in the app configuration to distribute traffic across multiple containers
  • Load Balancing: Klutch.sh automatically load balances traffic across all instances
  • Auto-scaling: For production apps, consider configuring auto-scaling based on CPU or memory usage

Performance Optimization Tips

  1. Use TypeScript Compilation: Compile TypeScript to JavaScript before deployment for faster startup
  2. Minimize Bundle Size: Remove unused dependencies to reduce build time and memory footprint
  3. Connection Pooling: If using databases, implement connection pooling to manage resources efficiently
  4. Caching: Implement caching strategies for frequently accessed data
  5. Response Compression: ElysiaJS supports gzip compression for API responses

Example with compression:

import { Elysia } from 'elysia';
const app = new Elysia()
.use(compression())
.get('/', () => 'Hello from ElysiaJS!')
.listen(process.env.PORT || 3000);

Troubleshooting

Application Won’t Start

Problem: Deployment completes but the app shows as unhealthy

Solution:

  • Check that your app listens on port 3000 (or the port you specified)
  • Verify that process.env.PORT is properly used in your code
  • Check application logs in the Klutch.sh dashboard for error messages

Build Fails with “Cannot find module”

Problem: Dependencies are not installed during build

Solution:

  • Ensure your package.json is in the root directory
  • Verify all dependencies are listed in package.json, not just installed locally
  • For Docker builds, ensure COPY package*.json ./ runs before npm install

Health Check Timeouts

Problem: Container shows as unhealthy even though app is running

Solution:

  • Increase the health check timeout in your Dockerfile
  • Ensure your app responds quickly to the health check endpoint
  • Verify the health check path exists and doesn’t require authentication

Port Already in Use

Problem: Error about port 3000 already being in use

Solution:

  • Make sure only one process is listening on the port
  • If using multiple workers, configure them on different ports and use a reverse proxy
  • Check that previous processes are properly terminated

High Memory Usage

Problem: App uses excessive memory and gets killed

Solution:

  • Check for memory leaks in your application code
  • Implement proper error handling and cleanup
  • Monitor memory usage during development with --inspect flag
  • Consider increasing the compute tier or number of instances

Resources


Summary

Deploying an ElysiaJS application on Klutch.sh is straightforward whether you choose Nixpacks or Docker. Both methods provide reliable, scalable hosting for your high-performance API server. Start with Nixpacks for simplicity, or use Docker for more control over your build environment. With Klutch.sh’s easy scaling and environment variable management, you can quickly move your ElysiaJS app from development to production.