Getting Started
From an empty folder to a working API in four steps.
1
Create your project
The CLI scaffolds a working project with your choice of runtime, example functions, and auto-generated types.
Terminal
$ npm create pikku@latest
______ _ _ _ (_____ (_) | | | _____) )| | _| | _ _ _ | ____/ | |_/ ) |_/ ) | | | | | | | _ (| _ (| |_| | |_| |_|_| _)_| _)____/ Welcome to the Pikku Project Generator! - Downloading template... β Downloading template... π¦ Installing dependencies...
pikku all (completed in 0ms) β’ 18 HTTP routes β’ 2 Scheduled tasks β’ 1 Trigger β’ 3 MCP endpoints
β Project setup complete! Run the following command to get started: cd my-app
2
Write a function
A Pikku function receives services (your dependencies) and data (typed input). No decorators, no classes β just an async function.
src/functions.ts
import { pikkuFunc } from '@pikku/core'
export const getUser = pikkuFunc(
async ({ db, logger }, { userId }) => {
logger.info(`Fetching user ${userId}`)
return await db.findUser(userId)
}
)
3
Wire it up
Connect your function to a protocol. Start with HTTP β you can always add more later without touching the function.
src/wiring.tsstart here
import { getUser } from './functions'
wireHTTP({
method: 'get',
route: '/users/:userId',
func: getUser
})
src/wiring.tsadd more anytime
// Same function, more protocols
wireHTTP({ method: 'get', route: '/users/:userId', func: getUser })
wireWebSocket({ channel: 'users', func: getUser })
wireRPC({ func: getUser })
wireMCP({ tool: 'get_user', func: getUser })
wireCLI({ command: 'get-user', func: getUser })
HTTPWebSocketRPCMCPQueueCronCLITriggerAI AgentWorkflow
4
Start the server
Run pikku watch to auto-regenerate types as you code, then start the server.
Terminal
Terminal 1
$ npx pikku watch
Watching for changes...
Terminal
Terminal 2
$ npm run start
Server running at http://localhost:4002
$ curl http://localhost:4002/users/123
{"id":"123","name":"John Doe","email":"john@example.com"}
What's next
You have a working API. Here's where to go from here.