Skip to main content

Pikku Project Setup Foundations

This skill provides foundational patterns for setting up Pikku projects. All runtime adapter skills reference this for common setup logic.

When to use this skill​

  • Setting up any Pikku runtime (Express, Fastify, Lambda, Cloudflare, etc.)
  • Understanding project structure patterns
  • Determining standalone vs workspace setup
  • Configuring bootstrap imports correctly
  • Setting up common package.json scripts

Note: This skill is referenced by runtime skills. Users typically invoke runtime skills directly (e.g., "add express runtime"), which then reference this skill's patterns.


Project Type Detection​

Pikku projects come in three flavors. Detect automatically by checking the project structure:

1. Standalone Project​

Characteristics:

  • Functions and runtime in the same package
  • No packages/ directory
  • Single package.json at root
  • Functions typically in src/functions/

Directory structure:

my-app/
β”œβ”€β”€ package.json
β”œβ”€β”€ pikku.config.json
β”œβ”€β”€ src/
β”‚ β”œβ”€β”€ functions/ # Pikku functions
β”‚ β”‚ └── *.function.ts
β”‚ β”œβ”€β”€ services.ts # Services setup
β”‚ β”œβ”€β”€ config.ts # Config
β”‚ └── start.ts # Runtime server/worker
β”œβ”€β”€ .pikku/ # Generated wiring
β”‚ └── pikku-bootstrap.gen.js
└── tsconfig.json

Detection:

  • Check for src/functions/ or similar
  • No workspace field in package.json
  • No packages/ directory

2. Workspace - No Backend Config​

Characteristics:

  • Monorepo with separate packages
  • Functions in packages/functions/
  • Backend imports from functions package
  • Backend does NOT have its own pikku.config.json
  • Uses functions package's filter configuration

Directory structure:

my-monorepo/
β”œβ”€β”€ package.json (workspace root)
β”œβ”€β”€ packages/
β”‚ └── functions/
β”‚ β”œβ”€β”€ package.json
β”‚ β”œβ”€β”€ pikku.config.json # Filters defined here
β”‚ β”œβ”€β”€ src/
β”‚ β”‚ β”œβ”€β”€ functions/
β”‚ β”‚ β”œβ”€β”€ services.ts
β”‚ β”‚ └── config.ts
β”‚ └── .pikku/ # Generated (with filters)
β”‚ └── pikku-bootstrap.gen.js
β”œβ”€β”€ backends/
β”‚ └── express/
β”‚ β”œβ”€β”€ package.json # Depends on @my-app/functions
β”‚ β”œβ”€β”€ bin/
β”‚ β”‚ └── start.ts # Imports from functions package
β”‚ └── NO pikku.config.json # Key: no config here
└── tsconfig.json

Detection:

  • Check for packages/ or workspace field in root package.json
  • Backend package has dependency on functions package
  • Backend does NOT have pikku.config.json

Key trait: Backend uses functions package filters (can't customize)

3. Workspace - With Backend Config​

Characteristics:

  • Monorepo with separate packages
  • Functions in packages/functions/
  • Backend HAS its own pikku.config.json with custom filters
  • Backend generates its own .pikku/ directory
  • Allows different function subsets per backend

Directory structure:

my-monorepo/
β”œβ”€β”€ package.json (workspace root)
β”œβ”€β”€ packages/
β”‚ └── functions/
β”‚ β”œβ”€β”€ package.json
β”‚ β”œβ”€β”€ pikku.config.json # Base filters
β”‚ β”œβ”€β”€ src/functions/
β”‚ └── .pikku/ # Generated (all functions)
β”œβ”€β”€ backends/
β”‚ └── express/
β”‚ β”œβ”€β”€ package.json # Has @pikku/cli devDep
β”‚ β”œβ”€β”€ pikku.config.json # KEY: Extends functions config
β”‚ β”œβ”€β”€ bin/start.ts # Imports from backend .pikku
β”‚ └── .pikku/ # Generated (custom filtered)
β”‚ └── pikku-bootstrap.gen.js
└── tsconfig.json

Detection:

  • Check for packages/ or workspace field in root package.json
  • Backend HAS pikku.config.json with extends field
  • Backend has @pikku/cli in devDependencies

Key trait: Backend has custom filters, generates own wiring


Bootstrap Import Patterns​

The bootstrap file contains all wiring registration. Import path depends on project type:

Standalone​

import './.pikku/pikku-bootstrap.gen.js'

Generated by running npx pikku all in project root.

Workspace - No Backend Config​

import '@my-app/functions/.pikku/pikku-bootstrap.gen'

Bootstrap comes from functions package. Backend doesn't run pikku command.

Workspace - With Backend Config​

import '../.pikku/pikku-bootstrap.gen'

Generated by running npx pikku in backend directory.

Queue-Specific Bootstrap​

For queue workers (BullMQ, PG-Boss), bootstrap is in a /queue/ subdirectory:

Standalone:

import './.pikku/queue/pikku-bootstrap-queue.gen.js'

Workspace:

import '@my-app/functions/.pikku/queue/pikku-bootstrap-queue.gen.js'

Common Package.json Scripts​

Standalone Project​

{
"scripts": {
"pikku": "pikku all",
"prebuild": "npm run pikku",
"dev": "tsx watch src/start.ts",
"start": "tsx src/start.ts",
"build": "tsc -b"
},
"dependencies": {
"@pikku/core": "^0.9.x",
"@pikku/express": "^0.9.x"
},
"devDependencies": {
"@pikku/cli": "^0.9.x",
"tsx": "^4.x",
"typescript": "^5.x"
}
}

Key scripts:

  • pikku: Generates wiring files
  • prebuild: Auto-run pikku before build
  • dev: Watch mode for development
  • start: Production start

Workspace - No Backend Config​

{
"name": "@my-app/express-backend",
"scripts": {
"dev": "tsx watch bin/start.ts",
"start": "tsx bin/start.ts",
"build": "tsc -b"
},
"dependencies": {
"@my-app/functions": "workspace:*",
"@pikku/express": "^0.9.x"
},
"devDependencies": {
"tsx": "^4.x",
"typescript": "^5.x"
}
}

Key differences:

  • NO pikku script (uses functions package wiring)
  • NO @pikku/cli devDependency
  • NO @pikku/core dependency (comes from functions package)
  • Dependency on functions workspace package

Workspace - With Backend Config​

{
"name": "@my-app/express-backend",
"scripts": {
"pikku": "pikku",
"prebuild": "npm run pikku",
"dev": "tsx watch bin/start.ts",
"start": "tsx bin/start.ts",
"build": "tsc -b"
},
"dependencies": {
"@my-app/functions": "workspace:*",
"@pikku/express": "^0.9.x"
},
"devDependencies": {
"@pikku/cli": "^0.9.x",
"tsx": "^4.x",
"typescript": "^5.x"
}
}

Key differences from no-config:

  • HAS pikku script
  • HAS @pikku/cli in devDependencies
  • HAS prebuild script

pikku.config.json Patterns​

Standalone Project​

{
"tsconfig": "./tsconfig.json",
"srcDirectories": ["src"],
"outDir": ".pikku",
"filters": {
"types": ["http", "channel", "scheduler"],
"tags": ["api"]
}
}

Functions Package (Workspace)​

{
"tsconfig": "./tsconfig.json",
"srcDirectories": ["src"],
"outDir": ".pikku",
"filters": {
"types": ["http", "channel", "scheduler", "queue"],
"tags": ["api", "backend"]
}
}

Backend Package (Workspace with Custom Filters)​

{
"extends": "../../packages/functions/pikku.config.json",
"filters": {
"types": ["http", "scheduler"],
"tags": ["api", "express"],
"excludeTags": ["edge-only", "lambda-only"]
}
}

Key: extends field points to functions package config. Filters override base config.


Running pikku Command​

When to Run​

Always run after:

  • Adding/modifying function definitions
  • Adding/modifying wiring files (_.http.ts, _.channel.ts, etc.)
  • Changing pikku.config.json

Don't need to run:

  • Changing service implementations
  • Changing business logic inside functions
  • Modifying runtime server code

Where to Run​

Standalone:

cd my-app/
npm run pikku

Workspace - Functions Package:

cd packages/functions/
npm run pikku

Workspace - Backend with Config:

# First, ensure functions package is up to date
cd packages/functions/
npm run pikku

# Then, generate backend-specific wiring
cd ../../backends/express/
npm run pikku

What Gets Generated​

Running pikku creates files in .pikku/ directory:

.pikku/
β”œβ”€β”€ pikku-bootstrap.gen.js # Wiring registration
β”œβ”€β”€ pikku-types.gen.ts # Type definitions
β”œβ”€β”€ pikku-fetch.gen.ts # HTTP client (if httpFile configured)
β”œβ”€β”€ pikku-websocket.gen.ts # WebSocket client (if websocketFile configured)
β”œβ”€β”€ queue/
β”‚ └── pikku-bootstrap-queue.gen.js # Queue wiring (if queue functions exist)
└── ...

Smart Defaults​

When setting up runtimes, use these sensible defaults:

Server Configuration​

  • Port: 3000 (or next available)
  • Hostname:
    • Development: 'localhost'
    • Docker/containers: '0.0.0.0'
  • Health check: /health-check

File Locations​

  • Standalone: src/start.ts or src/main.ts
  • Workspace: bin/start.ts
  • Functions: src/functions/
  • Services: src/services.ts
  • Config: src/config.ts

Package Managers​

  • Detect from lockfile: package-lock.json β†’ npm, yarn.lock β†’ yarn, pnpm-lock.yaml β†’ pnpm
  • Default to npm if none detected

Verification Steps​

After setup, verify:

1. Package Installation​

npm list @pikku/core @pikku/[runtime]
# Should show installed versions

2. Wiring Generation​

ls .pikku/pikku-bootstrap.gen.js
# Or for workspace: ls packages/functions/.pikku/pikku-bootstrap.gen.js
# File should exist

3. TypeScript Compilation​

npm run build
# Should compile without errors

4. Server/Worker Start​

npm run dev
# Should start without errors

5. Health Check (for HTTP servers)​

curl http://localhost:3000/health-check
# Should return {"status":"ok"}

Common Pitfalls​

Wrong Bootstrap Import​

❌ Wrong:

// Backend in workspace using functions package filters
import './.pikku/pikku-bootstrap.gen.js' // File doesn't exist!

βœ… Correct:

// Import from functions package
import '@my-app/functions/.pikku/pikku-bootstrap.gen'

Missing pikku Script​

❌ Problem: Backend has pikku.config.json but no pikku script in package.json

βœ… Solution: Add "pikku": "pikku" to scripts AND @pikku/cli to devDependencies

Running pikku in Wrong Directory​

❌ Wrong: Running pikku in workspace root (has no pikku.config.json)

βœ… Correct: Run in packages/functions/ or specific backend directory

Forgetting to Run pikku​

❌ Problem: Modified wiring files but didn't regenerate bootstrap

βœ… Solution: Run npm run pikku after wiring changes, or use prebuild script


Runtime Adapters (all reference this skill):

  • pikku-express
  • pikku-fastify
  • pikku-ws
  • pikku-uws
  • pikku-aws-lambda
  • pikku-cloudflare
  • pikku-queue-bullmq
  • pikku-queue-pg-boss

Function Definition:

  • pikku-functions (for creating function definitions)
  • pikku-http (for HTTP wiring)
  • pikku-channel (for WebSocket wiring)
  • pikku-queue (for queue function definitions)

Configuration:

  • pikku-cli (for CLI commands and config options)