Pikku Express Runtime
This skill helps you set up and deploy Pikku functions using Express.js as the runtime adapter.
When to use this skillβ
- Building traditional Node.js web servers
- Creating REST APIs with Express
- Integrating Pikku into existing Express applications
- Development and production Express deployments
- Need for middleware ecosystem and Express plugins
Quick Setupβ
Prerequisites: See pikku-project-setup for project structure detection and common setup patterns.
1. Install Packagesβ
Server mode:
npm install @pikku/express @pikku/core @pikku/schedule
Middleware mode:
npm install @pikku/express-middleware @pikku/core
2. Create Server Fileβ
Standalone: Create src/start.ts
based on templates/express/src/start.ts
Workspace: Create bin/start.ts
based on workspace-starter/backends/express/bin/start.ts
Key imports:
- Import bootstrap (see pikku-project-setup for correct path)
- Import
PikkuExpressServer
from@pikku/express
- Import config, services, and session factory
3. Configure Express-Specific Settingsβ
type ExpressCoreConfig = CoreConfig & {
port: number // Default: 3000
hostname: string // Default: 'localhost' (use '0.0.0.0' for Docker)
healthCheckPath?: string // Default: '/health-check'
limits?: {
json?: string // Default: '1mb'
xml?: string
urlencoded?: string
}
}
4. Update Package.json Scriptsβ
See pikku-project-setup for complete script patterns.
Express-specific tip: Pipe logs through pino-pretty for development:
{
"scripts": {
"dev": "tsx watch src/start.ts | pino-pretty -i time,hostname,pid"
}
}
5. Generate & Verifyβ
# Generate wiring (if applicable to your project type)
npm run pikku
# Start development server
npm run dev
# Verify health check
curl http://localhost:3000/health-check
Expected outcome: Server starts on configured port, health check returns {"status":"ok"}
, Pikku routes are registered.
Runtime Modesβ
Pikku provides two Express integration modes:
Server Mode (@pikku/express
)β
Full Express server managed by Pikku with automatic setup.
Use when:
- Starting a new Express server
- Want automatic configuration (JSON parsing, cookies, CORS)
- Need built-in features (health checks, static assets, file uploads)
Middleware Mode (@pikku/express-middleware
)β
Integrate Pikku into an existing Express app as middleware.
Use when:
- Integrating into existing Express application
- Need custom Express configuration
- Want full control over middleware stack
Installationβ
Server mode:
npm install @pikku/express @pikku/core @pikku/schedule
Middleware mode:
npm install @pikku/express-middleware @pikku/core
Server Modeβ
Standalone Projectβ
For standalone projects where functions are in the same package.
Example: templates/express/src/start.ts
Key points:
- Import bootstrap from local
./.pikku/pikku-bootstrap.gen.js
- Import services from local files
- Create
PikkuExpressServer
with config, services, and session factory - Call
enableExitOnSigInt()
for graceful shutdown - Call
init()
thenstart()
Workspace - No Backend Config (Simpler)β
Backend imports all functions from the functions package without filtering.
Example: workspace-starter/backends/express/bin/start.ts
Key differences:
- Import config/services from functions package:
@my-app/functions/src/config
- Import bootstrap from functions:
@my-app/functions/.pikku/pikku-bootstrap.gen
- No
pikku
script needed in backend package.json - All functions included (no filtering)
Tradeoffs:
- β Faster: No extra build step per backend
- β Simpler: One source of truth
- β Can't customize filtering (uses functions package filters)
Workspace - With Backend Config (Filtered)β
Backend has its own pikku.config.json
that filters which functions are included.
Directory structure:
backends/
express/
bin/start.ts
package.json # Includes "pikku": "pikku" + @pikku/cli devDep
pikku.config.json # Extends functions config, applies filters
.pikku/
pikku-bootstrap.gen.js # Generated (filtered)
packages/
functions/
pikku.config.json
.pikku/
pikku-bootstrap.gen.js # Generated (all functions)
Backend pikku.config.json:
{
"extends": "../../packages/functions/pikku.config.json",
"filters": {
"types": ["http", "channel", "scheduler"],
"tags": ["api", "express"],
"excludeTags": ["edge-only", "lambda-only"]
}
}
Bootstrap import:
// Import from backend's .pikku directory (filtered)
import '../.pikku/pikku-bootstrap.gen'
Build process:
cd backends/express
yarn pikku
(reads local pikku.config.json, applies filters)- Generated files in
backends/express/.pikku/
include only filtered functions
Tradeoffs:
- β Filtering: Different API subsets per backend
- β Tree-shaking: Better bundle size
- β Runtime-specific: Exclude incompatible functions
- β Slower: Must run
pikku
per backend
Configurationβ
Server mode extends CoreConfig
with Express-specific options:
type ExpressCoreConfig = CoreConfig & {
port: number
hostname: string // Use '0.0.0.0' for Docker
healthCheckPath?: string // Default: '/health-check'
limits?: {
json?: string // Default: '1mb'
xml?: string
urlencoded?: string
}
}
See: templates/express/src/start.ts for config usage
Lifecycleβ
const server = new PikkuExpressServer(
config,
singletonServices,
createSessionServices
)
server.enableExitOnSigInt() // Graceful shutdown
await server.init() // Initialize (required)
await server.start() // Start listening
With Schedulerβ
Run Express + scheduled tasks in the same process:
import { PikkuTaskScheduler } from '@pikku/schedule'
// After server.start()
const scheduler = new PikkuTaskScheduler(singletonServices)
scheduler.startAll()
See: templates/express/src/start.ts
Optional Featuresβ
CORS:
server.enableCors({ origin: '*', credentials: true })
Static Assets:
server.enableStaticAssets() // Requires content config
File Uploads:
server.enableReaper() // Enables PUT /reaper/:path
Note: Enable optional features before calling server.init()
Middleware Modeβ
Integrate Pikku into an existing Express application.
Example: templates/express-middleware/src/start.ts
Setup:
import express from 'express'
import { pikkuExpressMiddleware } from '@pikku/express-middleware'
const app = express()
app.use(express.json())
app.use(
pikkuExpressMiddleware(singletonServices, createSessionServices, {
logRoutes: true,
loadSchemas: true,
respondWith404: false, // Pass to next middleware if route not found
})
)
// Your custom routes can go after
app.get('/custom', (req, res) => { ... })
app.listen(3000)
Middleware Optionsβ
logRoutes
: Log registered routes on startuploadSchemas
: Compile and validate schemasrespondWith404
: Iffalse
, passes unmatched routes to next Express middleware (recommended)
CRITICAL: Set respondWith404: false
to allow your custom Express routes to work.
Developmentβ
Scriptsβ
Standalone:
{
"scripts": {
"pikku": "pikku all",
"prebuild": "npm run pikku",
"dev": "tsx watch src/start.ts | pino-pretty -i time,hostname,pid",
"start": "tsx src/start.ts"
}
}
Workspace (no backend config):
{
"scripts": {
"dev": "tsx watch bin/start.ts | pino-pretty -i time,hostname,pid",
"start": "tsx bin/start.ts"
}
}
Workspace (with backend config):
{
"scripts": {
"pikku": "pikku",
"prebuild": "npm run pikku",
"dev": "tsx watch bin/start.ts | pino-pretty -i time,hostname,pid",
"start": "tsx bin/start.ts"
}
}
Health Checkβ
Default endpoint: GET /health-check
β {"status":"ok"}
Customize via config: { healthCheckPath: '/health' }
Deploymentβ
Express servers can be deployed anywhere Node.js runs. Use hostname: '0.0.0.0'
for containerized deployments.
Docker: workspace-starter/docker/Dockerfile.express
Examplesβ
Standalone:
- templates/express - Server mode
- templates/express-middleware - Middleware mode
Workspace:
- workspace-starter/backends/express - Workspace backend
Critical Rulesβ
Standalone Projectsβ
- Import bootstrap from local:
'./.pikku/pikku-bootstrap.gen.js'
- Import services from local files:
'./services.js'
- Call
server.enableExitOnSigInt()
for graceful shutdown - Call
server.init()
beforeserver.start()
Workspace (No Backend Config)β
- Import config/services from functions:
'@my-app/functions/src/...'
- Import bootstrap from functions:
'@my-app/functions/.pikku/pikku-bootstrap.gen'
- Backend package.json has
"@my-app/functions": "workspace:*"
- No
pikku
script needed
Workspace (With Backend Config)β
- Backend has
pikku.config.json
withextends
- Import bootstrap from backend:
'../.pikku/pikku-bootstrap.gen'
- Backend package.json includes
"pikku": "pikku"
script - Backend package.json includes
"@pikku/cli"
in devDependencies - Run
pikku
in backend directory to generate filtered wiring
Middleware Modeβ
- Apply Pikku middleware after body parsers
- Set
respondWith404: false
to allow custom routes - Bootstrap import still required
Deploymentβ
- Use
hostname: '0.0.0.0'
in Docker/containers - Configure health check endpoint
- Enable graceful shutdown
Related Skillsβ
Prerequisites:
- pikku-project-setup - Project structure and common setup patterns
- pikku-functions - Creating Pikku function definitions
Wiring:
- pikku-http - HTTP route wiring and configuration
- pikku-channel - WebSocket/channel wiring
- pikku-scheduler - Scheduled task configuration
Alternative Runtimes:
- pikku-fastify - Higher performance alternative
- pikku-uws - Extreme performance with Β΅WebSockets
- pikku-aws-lambda - Serverless deployment