GitHub - digplan/instaserve: Instant web stack

5 min read Original article ↗

Instaserve

Instant web stack for Node.js

npm version bundle size

Configuration

Instaserve uses environment variables for Auth0 and Cloudflare R2 integration. Create a .env file (if your runner supports it) or pass them before the command.

Auth0 Variables

  • AUTH0_DOMAIN: Your Auth0 domain
  • AUTH0_CLIENT_ID: Your Auth0 Client ID
  • AUTH0_CLIENT_SECRET: Your Auth0 Client Secret

Cloudflare R2 Variables (via lib/r2.js)

  • CLOUDFLARE_ACCOUNT_ID: R2 Account ID
  • CLOUDFLARE_ACCESS_KEY_ID: R2 Access Key ID
  • CLOUDFLARE_SECRET_ACCESS_KEY: R2 Secret Access Key

Usage

# Run with env vars
AUTH0_DOMAIN=... AUTH0_CLIENT_ID=... npx instaserve [options]

Generate routes file

npx instaserve generate-routes

Commands

generate-routes Create a sample routes.js file in the current directory

Options

-port <number> Port to listen on (default: 3000)

-ip <address> IP address to bind to (default: 127.0.0.1)

-public <path> Public directory path (default: ./public)

-api <file> Path to routes file (default: ./routes.js)

-secure Enable HTTPS (requires cert.pem and key.pem - run ./generate-certs.sh)

-help Show help message

HTTPS Support

Instaserve supports HTTPS with self-signed certificates. To enable HTTPS:

  1. Generate certificates:

    This creates cert.pem and key.pem files and adds them to your system's trust store.

  2. Run with HTTPS:

The certificate generation script:

  • Creates a self-signed certificate valid for 365 days
  • Automatically adds the certificate to your system trust store (macOS/Linux)
  • Prevents browser security warnings

Routes

The routes file (routes.js by default) defines your API endpoints. Each route is a function that handles requests to a specific URL path.

Generating a Routes File

To create a sample routes.js file with example routes and middleware:

npx instaserve generate-routes

This creates a routes.js file in the current directory with example code. If the file already exists, the command will fail to prevent overwriting.

Routes File Validation

Instaserve validates routes files on startup:

  • If -api is specified and the file doesn't exist, the server will fail to start
  • The routes file must export a default object
  • All route handlers must be functions
  • Invalid routes files will cause the server to exit with an error message

Basic Route Example

export default {
    // Handle GET /hello
    hello: (req, res, data) => {
        return { message: 'Hello World' }
    }
}

Method-Specific Routes

Routes can be defined with HTTP method prefixes to handle different methods on the same path. Supported methods: GET, POST, PUT, DELETE.

export default {
    // Method-specific routes
    'POST /users': (req, res, data) => {
        return { message: 'Create user', data }
    },
    
    'GET /users': (req, res, data) => {
        return { message: 'Get users' }
    },
    
    'PUT /users': (req, res, data) => {
        return { message: 'Update user', data }
    },
    
    'DELETE /users': (req, res, data) => {
        return { message: 'Delete user', data }
    },
    
    // Path-only routes still work (backward compatible)
    // These match any HTTP method
    hello: (req, res, data) => {
        return { message: 'Hello World' }
    }
}

Method-specific routes take precedence over path-only routes. If no method-specific route matches, the server falls back to path-only route matching.

Special Routes (Middleware)

Routes starting with _ are middleware functions that run on every request before the main route handler. They are useful for:

  • Logging requests
  • Authentication
  • Request modification
  • Response headers

Middleware functions can:

  • Return false to continue to the next middleware or main route
  • Return a truthy value to stop processing and use that as the response
  • Modify the request or response objects

Middleware Example

export default {
    // Log every request
    _log: (req, res, data) => {
        console.log(`${req.method} ${req.url}`)
        return false // Continue processing
    },

    // Block unauthorized requests
    _auth: (req, res, data) => {
        if (!data.token) {
            res.writeHead(401)
            return 'Unauthorized'
        }
        return false // Continue if authorized
    }
}

Route Parameters

Each route function receives:

  • req - The HTTP request object
  • res - The HTTP response object
  • data - Combined data from:
    • POST body (if JSON)
    • URL query parameters
    • Form data

Returning Status Codes

Routes can return a 3-digit number (100-999) to set the HTTP status code with an empty response body:

export default {
    'GET /notfound': () => 404,
    'GET /unauthorized': () => 401,
    'GET /forbidden': () => 403,
    'GET /teapot': () => 418, // I'm a teapot
    'GET /created': () => 201
}

Routes can also return:

  • Strings - Sent as plain text response
  • Objects - Automatically serialized as JSON
  • Status codes - 3-digit numbers (100-999) set HTTP status with empty body

Example Routes File

// routes.js
export default {
    // Middleware example
    _debug: (req, res, data) => {
        console.log('Request:', req.url)
        return false // Continue to next route
    },

    // Method-specific routes
    'POST /api/users': (req, res, data) => {
        return { status: 'created', data }
    },
    
    'GET /api/users': (req, res, data) => {
        return { status: 'ok', users: [] }
    },
    
    'GET /api/notfound': () => 404,
    'GET /api/unauthorized': () => 401,

    // Path-only route (matches any method)
    api: (req, res, data) => {
        return { status: 'ok', data }
    },

    // Error handling
    testerror: () => {
        throw new Error('Test error')
    }
}

Library Modules

The lib/ directory contains useful modules for authentication, storage, and database manipulation.

Auth0 (lib/auth0.js)

Provides authentication routes and req.user handling via Auth0.

  • Routes: GET /login, GET /logout, GET /callback
  • Usage: Import and spread into your routes.
    import auth0 from './lib/auth0.js';
    
    export default {
      ...auth0,
      // other routes
    }

R2 Storage (lib/r2.js)

Utilities for Cloudflare R2 or S3-compatible object storage.

  • Features: uploadToR2, downloadFromR2, listR2Files
  • Routes: fileRoutes exports helpers for file management.
  • Usage:
    import { fileRoutes } from './lib/r2.js';
    
    export default {
      ...fileRoutes,
      // other routes
    }

SQLite (lib/sqlite.js)

Provides a local SQLite database with a per-user Key-Value store.

  • Features: User management table, KV table.
  • Routes: _auth middleware, CRUD for KV store (/api, /all).
  • Usage:
    import sqliteRoutes from './lib/sqlite.js';
    
    export default {
      ...sqliteRoutes,
      // other routes
    }